Yank out type duplication for BGP peers - #803
Conversation
7d328c5 to
d986afd
Compare
This PR yanks out a ton of type duplication around BGP peer config.
We had a lot of this before, but BGP unnumbered added yet another split
for many of the types.
We started with 11 separate types:
1. Neighbor
2. UnnumberedNeighbor
3. BgpPeerConfig
4. UnnumberedBgpPeerConfig
5. BgpPeerParameters
6. BgpNeighborInfo
7. BgpUnnumberedNeighborInfo
8. BgpNeighborParameters
9. PeerConfig
10. SessionInfo
11. NeighborInfo
And ended with just 4 types:
1. NeighborConfig
2. Neighbor
3. SessionInfo
4. NeighborInfo
All in all, we end up with ~1500 fewer lines of code and a noticeably
streamlined order of operations for API handlers. The following summary
came from Claude since the full extent of the changes is so wide.
Added:
- New versioned API module mg-api-types-versions::v12
- (unify_bgp_neighbors/), exposed via latest.rs:
+ NeighborConfig: single write/input type. Peer identity plus
all session params inlined; no asn/group, no serde(flatten).
+ Neighbor: read/stored type via composition:
{ asn, group, config: NeighborConfig }.
+ NeighborGroupSelector { asn, group } for write endpoints.
+ Unified ApplyRequest (peers: map<group, Vec>)
and NeighborResetRequest.
+ v11<->v12 conversions: total From upgrades, partial TryFrom
(PeerKindMismatch) downgrades.
- API version (12, UNIFY_BGP_NEIGHBORS) in mg-api api_versions!.
- Regenerated OpenAPI doc mg-admin-12.0.0.
Removed:
- bgp::config::PeerConfig and its From impls (config.rs now holds
only RouterConfig).
- rdb storage types BgpNeighborInfo and BgpUnnumberedNeighborInfo
(and nested BgpNeighborParameters); the DB now persists Neighbor.
- External BgpPeerConfig/UnnumberedBgpPeerConfig and the
Neighbor/UnnumberedNeighbor split; the BgpPeerParameters struct.
- Conversion hand-copies Neighbor::from_bgp_peer_config and
from_rdb_neighbor_info.
- Router fork: new_unnumbered_session, ensure_unnumbered_session,
update_unnumbered_session; the peer_id param of
new_session_locked.
- UnnumberedManagerNdp::get_neighbor_session and its dead routers
field.
- Dead NeighborResetRequest::to_peer_id.
- Paired numbered/unnumbered mgd handlers (~10 collapsed to ~5).
- Retired the v11 OpenAPI doc to a .gitstub.
Changed:
- Identity unified on PeerId (Ip|Interface) with port: Option; asn/group
are request coordinates, not body fields.
- SessionInfo/NeighborInfo built From<&NeighborConfig>;
Error::UnknownPeer now carries a PeerId; update_session handles
both peer kinds.
- rdb db.rs: one PeerId-keyed tree; add/get/remove keyed by PeerId;
removed the unnumbered ops and BGP_UNNUMBERED_NEIGHBOR.
- mg-api: unified create/read/update/delete/clear as the required
VERSION_UNIFY_BGP_NEIGHBORS.. methods; older split endpoints kept
as version-bounded provided defaults. Create/update moved to
/bgp/config/neighbor-group/{asn}/{group} (Dropshot path-collision
fix).
- mgd: do_bgp_apply diff keyed by PeerId; dropped the
UNSPECIFIED:179 read-path fabrication; reworked add_neighbor,
add_neighbor_v1, get_exported_v1, and main.rs to the new shapes.
- mgadm: to_api_neighbor (was into_*) produces NeighborConfig;
create/update pass asn+group on the path.
- falcon-lab: builds and passes the nested Neighbor.
Fixed:
- deterministic_collision_resolution and jitter are now persisted;
previously hard-coded on rdb read and lost across reload.
Cleanups:
- Trimmed verbose compile-barrier comments to short notes
(mp_bgp, prefix_to_oxnet, static_admin, rdb/types).
- Removed mg-api-types doc-comment text that leaked internal
implementation into the OpenAPI spec.
- Scrubbed test.rs comments of references to removed types.
Fixes: #564
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
d986afd to
498ce1b
Compare
|
marking this ready for review now. I still need to build out the omicron PR, but I don't think that should hold up any reviews on the maghemite side |
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
1acc3c0 to
f4d484f
Compare
nicolaskagami
left a comment
There was a problem hiding this comment.
Nice! It's always great to see code being simplified away :)
I found a couple of things that are worth addressing down below and:
- The PR description mentions a
NeighborGroupSelectorwhich is nowhere to be found in this repo. - I like
PeerIdbut I think we could do more of it, such as withact_as_a_default_ipv6_router. I'm thinking about a better format overall.
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
- validate session updates before mutating peer metadata; - retain a router when Apply drains all peers and require explicit Delete; - enforce one NeighborConfig per PeerId across groups with IdOrdMap; - return 404 for peer-kind mismatches in compatibility endpoints; - reject duplicate peers from legacy apply requests with HTTP 400; - make v13-to-v11 conversion exhaustive instead of dropping peers. Move group into NeighborConfig, retain the array-shaped wire and generated client representation, regenerate the v13 OpenAPI document, and add coverage for serialization, conversions, and apply/delete behavior. Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Thanks! I am much happier with this shape than I was with the parallel un/numbered paths.
I fixed up the PR description (rather, I had claude do it because there are a lot of changes in this PR) with a summary of what's been done.
I understand the urge to move things like Maybe there's another shape we could pursue where |
That's not exactly what I was suggesting, exactly for the reason you give.
Yep. We could have |
This PR removes the duplicated numbered/unnumbered BGP peer configuration paths introduced as BGP unnumbered support grew. The latest implementation goes from 11 overlapping API, storage, and session shapes to four core types:
NeighborConfigNeighborSessionInfoNeighborInfoOlder shapes remain only in versioned compatibility APIs. Overall, this removes more than 1,000 lines while making numbered and unnumbered peers follow the same configuration, persistence, and session-management paths.
API and type model
The new
UNIFY_BGP_NEIGHBORSAPI is version 13 and is exposed throughlatest.PeerIdremains solely the peer identity:Ipfor numbered peers orInterfacefor unnumbered peers.NeighborConfigcontains that identity,group, the optional TCPport, and all session parameters. The formerBgpPeerParameterslayer is inlined withoutserde(flatten).Neighboris the read/stored composition{ asn, config: NeighborConfig }./bgp/config/neighbor, with ASN carried byNeighbor.NeighborResetRequestand one handler.ApplyRequestis now an explicitly tagged operation:{"action":"apply","asn":47,"originate":[],"peers":[]} {"action":"delete","asn":47}Applyrepresents complete desired state for a router. An empty peer list retains the router, whileDeleteexplicitly removes the router and its state.Apply peers are represented internally as
IdOrdMap<NeighborConfig>, keyed only byPeerId, so one peer cannot appear in multiple groups. Serde and OpenAPI retain a normal JSON array representation, and Progenitor generatesVec<NeighborConfig>for clients. Duplicate peer identities are rejected when the request is deserialized.Internal simplification
bgp::config::PeerConfigand its conversion layer.BgpPeerConfig,UnnumberedBgpPeerConfig,BgpPeerParameters,BgpNeighborInfo,BgpUnnumberedNeighborInfo, andBgpNeighborParametersduplication.Neighbordirectly in one tree keyed by(ASN, PeerId)instead of maintaining separate numbered and unnumbered storage paths.PeerIdrather than parallel numbered/unnumbered implementations.Neighborshape used by the API and RDB.deterministic_collision_resolutionand timer jitter settings now survive persistence instead of being reconstructed with defaults.Compatibility and review fixes
PeerId::IpandPeerId::Interface, rather than silently dropping a peer kind. Explicit router deletion cannot be represented by v11 and returns a conversion error.Persistence note
The sled database is used for recovery from daemon crashes and restarts within a deployed zone. mgd upgrades replace and rebuild the zone, so no cross-version migration of the retired numbered/unnumbered neighbor tree is required.
Validation
cargo fmt --all --checkcargo test -p mg-api-types-versionsjust openapi-check mgdcargo check --manifest-path mg-admin-client/Cargo.tomlFixes: #564