Add allow_ddm_traffic parameter for link creation - #346
Conversation
Plumb this through such front ports can run ddm for multirack.
taspelund
left a comment
There was a problem hiding this comment.
Looks pretty straightforward to me. Just one typo and a couple questions about struct naming + which struct owns the new param.
There was a problem hiding this comment.
Lgtm!
I appreciate this is time sensitive, so feel free to merge. However I'm curious about validation precedent.
Given more time, how might we test this? What do you think is warranted validation for a change like this? Here are some ideas:
- A basic dpd-client test could apply these settings and verify that
uplink == trueon the resulting link. This is pretty low value, but I guess it would help something like a messy git resolution or big refactor. - Do we have any existing regression tests on the omicron/dendrite API? Guessing these would live on the omicron side?
- I feel that we should eventually have an automated CI test somewhere for multirack networking. Since it combines (at least) omicron, maghemite, and dendrite systems, would we orchestrate this on a4x2/voxel? Do we have precedent/infra for this kind of automated testing?
| /** | ||
| * Apply port settings atomically. | ||
| * | ||
| * These settings will be applied holistically, and to the extent possible | ||
| * atomically to a given port. In the event of a failure a rollback is | ||
| * attempted. If the rollback fails there will be inconsistent state. This | ||
| * failure mode returns the error code "rollback failure". For more details see | ||
| * the docs on the [`PortSettings`] type. | ||
| */ |
There was a problem hiding this comment.
Is there a convention for when we use /** ... */ versus /// doc comments? This module has both. Aesthetically, sticking to one is nice. Feel like I don't see /** */ in the wild very often.
But you don't need to change this. Just curious.
There was a problem hiding this comment.
That said, the contents of the comment are great. When thinking of future design, it would be nice to never need "inconsistent state" in documentation 😅
There was a problem hiding this comment.
This comment was part of the original docs and just copied verbatim to the new version of the API. I personally think we should use /// everywhere. But in this case it didn't make sense for me to modify it.
Thanks for taking a look Cory. I'm in the process of testing this in voxel, although it requires a few more changes in omicron to do so. I'm not going to merge until all the related PRs are ready to go. Besides that I have no idea how to test this. I don't know what tests do or don't exist and what people normally do for changes like this. |
Sgtm, thx for clarifying. Figuring this out and adding any documentation or tooling to standardize dendrite PR validation is on my to-do list. |
nicolaskagami
left a comment
There was a problem hiding this comment.
Found a few problems that need looking into:
- Easy: new
LinkSpecfield but nomodify_linkchange. - Easy: I think we want to pass it through in
api_server.rs, no? - Annoying: I thought it was wrong to set it to
falsefor rear ports, but as I mentioned on another comment I think the problem is that the documented semantics don't match the implementation. It currently only seems to apply forQsfp, more specifically just setting Ipv6 and disablinguplink. At the very least we need to communicate this better for maintainability.
| kr: true, | ||
| lane: Some(dpd_types::link::LinkId(0)), | ||
| tx_eq: None, | ||
| allow_ddm_traffic: false, |
There was a problem hiding this comment.
Shouldn't DDM run on rear ports?
| autoneg: l.config.autoneg, | ||
| kr: l.config.kr, | ||
| tx_eq: l.tx_eq, | ||
| allow_ddm_traffic: false, |
There was a problem hiding this comment.
Shouldn't we pass it through here?
| allow_ddm_traffic: false, | |
| allow_ddm_traffic: l.config.allow_ddm_traffic, |
| /// Whether DDM traffic is allowed on this link. | ||
| /// | ||
| /// This defaults to `false`. | ||
| #[serde(default)] | ||
| pub allow_ddm_traffic: bool, |
There was a problem hiding this comment.
I think the semantics are not matching the behavior. allow_ddm_traffic: false still allows DDM traffic is it isn't a Qsfp port. We should either change the description (and name) to match the current behavior or the other way around.
| pub ipv4: BTreeSet<Ipv4Addr>, | ||
| pub ipv6: BTreeSet<Ipv6Addr>, | ||
| pub tx_eq: Option<TxEq>, | ||
| pub allow_ddm_traffic: bool, |
There was a problem hiding this comment.
We're adding a new field here but the modify_link wasn't changed to apply it. It would definitely benefit from a bit of a refactor, or at least a destructuring pattern, so we'd get compilation errors next time this happens.
| // | ||
| // For multirack ddm traffic on the front ports we must also enable | ||
| // ipv6. | ||
| let ipv6_enabled = | ||
| !matches!(port_id, PortId::Qsfp(_)) || params.allow_ddm_traffic; | ||
| // By default we expect external-facing links to be used as uplinks and | ||
| // internal-facing links for backplane traffic. | ||
| let uplink = matches!(port_id, PortId::Qsfp(_)); | ||
| // | ||
| // We need to disable uplinks for multirack ddm traffic on the front | ||
| // ports. | ||
| let uplink = | ||
| matches!(port_id, PortId::Qsfp(_)) && !params.allow_ddm_traffic; |
There was a problem hiding this comment.
Is this the only place where allow_ddm_traffic effects change? If so, it seems to only affect Qsfp ports, which is different semantics than what it's described as.
|
Applied the two "easy" fixes (after talking to @andrewjstone). There's a bunch around that could be improved long-term. Particularly:
|
|
Thanks for the fixes @nicolaskagami. Much appreciated. |
|
@nicolaskagami I think I updated all the relevant comments to reflect reality. |
nicolaskagami
left a comment
There was a problem hiding this comment.
Thanks for bearing with me!
| @@ -721,6 +723,25 @@ pub trait DpdApi { | |||
| params: TypedBody<latest::link::LinkCreate>, | |||
| ) -> Result<HttpResponseCreated<latest::link::LinkId>, HttpError>; | |||
There was a problem hiding this comment.
I think the guidance in RFD 619 is to always use fully qualified type versions in the dropshot trait, rather than latest. For the endpoints you're bumping, I would also change the signature to use the specific version in the path i.e. v13::link::LinkCreate
There was a problem hiding this comment.
We only use specif versions for prior prior versions of the API. The latest version should use a floating identifier .
There was a problem hiding this comment.
FWIW, the claude skill in omicron handled this correctly.
|
Good news, this appears to work correctly. With a small change to voxel, which brings up an uplink on Here's the relevant voxel patch in @@ -132,6 +133,7 @@ fn uplink_port(p: &UplinkPort, mode: RouterMode) -> Result<PortConfig> {
autoneg: false,
lldp: Some(lldp(&p.switch, &p.lldp)),
tx_eq: None,
+ allow_ddm_traffic: false,
})
}
@@ -152,6 +154,7 @@ fn interconnect_port(switch: &str, port: &str) -> Result<PortConfig> {
autoneg: false,
lldp: Some(lldp(switch, &format!("interconnect-{port}"))),
tx_eq: None,
+ allow_ddm_traffic: true,
})
}That triggers the Looking at the output after RSS we see: |
Plumb this through such front ports can run ddm for multirack.