Skip to content

Wrap up RFD 619 migration#724

Open
taspelund wants to merge 44 commits intomainfrom
trey/rfd_619_wrapup
Open

Wrap up RFD 619 migration#724
taspelund wants to merge 44 commits intomainfrom
trey/rfd_619_wrapup

Conversation

@taspelund
Copy link
Copy Markdown
Contributor

Many types were not fully migrated to the RFD 619 conventions in #611 and #665. This PR seeks to remedy that.

As a whole, this PR is simply a re-organization of existing code rather than a functional change.
It does so by splitting some crates apart (introducing $CRATE-types and $CRATE-types-versions for it) and attempting to bring some order to this chaos. In some cases, types were moved into a more fitting home (e.g. BFD types moving out of rdb/mgd crates and into bfd-types).

The exception to no functional changes is that the operation_id in the OpenAPI spec does change for a handful of methods.
These are all broken out into a new dropshot API version for mg-api: ENDPOINT_RENAME.
This results in clients seeing a different method name when importing the latest API version via mg-admin-client.
Aside from the method/operation_id name change, the API remains byte-compatible.

I had claude help with the grunt work on this one, and the commit messages describe the implementation plan it followed (including some course corrections).

Phase 0: capture baseline (cargo nextest 241 passing, clippy clean,
openapi check fresh) before structural migration to RFD 619 layout.

Phase 1: scaffold three new versions crates and v6/v7/v8 module
directories in mg-types-versions:
- mg-common-types + mg-common-types-versions (new)
- bgp-types + bgp-types-versions (new)
- rdb-types/versions (new sibling under existing rdb-types)
- mg-types/versions: add v6 (rib_exported_string_key),
  v7 (operation_id_cleanup), v8 (bgp_src_addr) module dirs

No types are migrated yet; module directories are empty placeholders.
The new facade crates re-export from latest. mg-common-types-versions
already includes v1::net (TunnelOrigin, Ipv6Prefix, Ipv4Prefix,
IpPrefix) but consumers have not yet been re-pointed; that lands in
Phase 2a.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…lFilter to rdb-types-versions

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Move Path and BgpPathProperties out of rdb/src/types.rs into
rdb-types-versions: v1::path holds the pre-UNNUMBERED shape (peer is
IpAddr), v5::path holds the UNNUMBERED shape (peer is PeerId,
nexthop_interface added). Conversions live in v5 (newer module);
the BgpPathProperties -> v1 fallback for PeerId::Interface is silent
(Ipv6Addr::UNSPECIFIED). impl Ord for Path and as_stale move to
rdb-types-versions/impls/path.rs. From<StaticRouteKey> for Path stays
in rdb/src/types.rs until StaticRouteKey migrates.

Split mg-types-versions::rib::GetRibResult per version: v1 references
v1::path::Path, v5 references v5::path::Path; latest re-exports v5.
Free fn v5::rib::get_rib_result_into_v1 downgrades for shims.

Version-gate static_list_v{4,6}_routes in mg-api so prior-version docs
keep their v1-shaped Path. Latest endpoints scoped to VERSION_UNNUMBERED..;
shims static_list_v4_routes_v1 (..VERSION_UNNUMBERED) and
static_list_v6_routes_v2 (VERSION_IPV6_BASIC..VERSION_UNNUMBERED) call
the latest impl and downgrade. Both pairs pin operation_id explicitly so
generated clients see one method per endpoint across versions.

OpenAPI: all 11 blessed docs (mg-admin v1..v8, ddm-admin v1, both
*-latest) byte-identical to baseline.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ions

Move ImportExportPolicyV1 → v1::policy::ImportExportPolicy (suffix dropped;
schemars(rename) annotation no longer needed since the Rust name now matches
the schema name naturally). Move ImportExportPolicy{,4,6} → v4::policy::*.
Conversions From<v1::policy::ImportExportPolicy> for ImportExportPolicy{4,6}
live in the v4 module. The as_ipv4_policy/as_ipv6_policy/from_per_af_policies
inherent methods on the v1 type move into impls/policy.rs.

The combined v4::policy::ImportExportPolicy enum is internal-only (no
JsonSchema), so there is no schema-name collision with v1::policy::Import
ExportPolicy in any blessed OpenAPI doc. Verified all 9 docs byte-identical.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ypes

Move BgpRouterInfo into v1::router; BfdPeerConfig + SessionMode into
v1::bfd. BfdPeerConfig and SessionMode schemas verified byte-identical
across all 8 blessed mg-admin docs.

The remaining trio (BgpNeighborInfo, BgpUnnumberedNeighborInfo,
BgpNeighborParameters) is not present in any blessed OpenAPI document --
they are internal db-persistence types with vestigial JsonSchema
derives. BgpNeighborParameters references ImportExportPolicy{4,6}, which
live in v4 per the prior Phase 2b sub-step, so the only-prior-versions
rule forces all three into v4::neighbor.

OpenAPI: all 9 blessed docs (mg-admin v1..v8, ddm-admin v1) plus both
*-latest symlinks byte-identical to baseline.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
mg-types-versions/src/initial/bfd.rs was importing rdb::BfdPeerConfig
(a floating identifier from the rdb facade), violating
RFD 619 §determinations-only-prior-versions. Switch to
rdb_types_versions::v1::bfd::BfdPeerConfig.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rsions

Move the 12 leaf wire-message enumerations (MessageType,
OptionalParameterCode, CapabilityCode, Safi, PathAttributeTypeCode,
AsPathType, ErrorCode, HeaderErrorSubcode, OpenErrorSubcode,
UpdateErrorSubcode, CeaseErrorSubcode, PathOrigin) into
bgp-types-versions::v1::messages, plus Afi into
bgp-types-versions::v4::messages. Their Display/slog::Value impls and
the Afi <-> rdb-types-versions::v1::AddressFamily conversions go to
bgp-types-versions::impls::messages (orphan-rule case 1).

The three From impls that take protocol types as input (From<&Message>
for MessageType, From<PathAttributeValue> for PathAttributeTypeCode,
From<Capability> for CapabilityCode) become free functions in
bgp/src/messages.rs (message_type_of, path_attribute_type_code_of,
capability_code_of) since their input types live in bgp/ and pulling
them into bgp-types-versions would break the leaf-crate property
(orphan-rule case 2). The handful of call sites are updated.

bgp-types-versions::error::WireError is scaffolded with the parse-only
+ leaf wire-error variants (TooSmall, TooLarge, NoMarker, BadLength,
BadVersion, Eom, Parse, Io, Unassigned, Experimental, InvalidCode,
ReservedCapability/Code, ReservedOptionalParameter, InvalidMessageType,
BadBgpIdentifier, MalformedAttributeList, InvalidNlriPrefix,
InvalidPrefixLength, plus the 11 TryFromPrimitiveError variants for the
moved enums). bgp::error::Error gains a #[from] WireError variant for
future ?-upcasting; existing variants stay put because the parse code
that produces them still lives in bgp/.

bgp-types-versions gains nom/num_enum/thiserror/slog/rdb-types-versions
deps plus an optional clap feature (Afi has #[cfg_attr(feature=clap,
derive(ValueEnum))]); the bgp crate's clap feature now passes through.

The migrated types' Rust paths (bgp::messages::TYPE) still resolve via
pub use re-exports, so no downstream code changes beyond the call-site
updates above. Verified all 11 blessed OpenAPI docs sha256-identical to
baseline; cargo fmt --check, cargo clippy --workspace -- -D warnings,
and cargo nextest (241 passed) all clean.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rsions

Move seven leaf wire-message types into bgp-types-versions::messages:
Tlv, Header, Community, AddPathElement (v1) and BgpNexthop,
Ipv6DoubleNexthop, ExtendedNexthopElement (v4). Header gains the
MAX_MESSAGE_SIZE constant alongside its existing WIRE_SIZE associated
const, both also re-exported from bgp::messages so existing call sites
in bgp::connection_tcp continue to compile unchanged.

Inherent methods on the moved types (Header::new/to_wire/from_wire,
BgpNexthop::from_bytes/to_bytes/byte_len, ExtendedNexthopElement::
is_v4_over_v6/is_v6_over_v4) and their Display/From impls move to
bgp-types-versions::impls::messages (orphan-rule case 1: every input
type is std or already migrated). Header and BgpNexthop parse paths
now produce WireError instead of bgp::Error; bgp::Error already grew
a #[from] WireError variant in chunk 1, so ? propagation through the
session-time call sites is unchanged. WireError gains an
InvalidAddress(String) variant to cover BgpNexthop::from_bytes.

bgp::messages keeps backward-compatible pub use re-exports so the
crate-public Rust paths (bgp::messages::Header etc.) still resolve.
The is_v4_over_v6/is_v6_over_v4 helpers become pub (they were private
methods before, but only consumed from inside bgp/, so widening them
is a no-op for downstream consumers).

Verified all 11 OpenAPI documents fresh with no schema drift; cargo
fmt --check, cargo clippy --workspace -- -D warnings, and cargo
nextest (241 passed) all clean.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…s-versions

Move the MP-BGP PathAttribute family into bgp-types-versions. The
12-variant PathAttributeTypeCode (incorrectly placed at v1::messages in
chunk 1) moves to v4::messages where it belongs; a 10-variant V1 form is
introduced at v1::messages with #[schemars(rename = "PathAttributeTypeCode")]
to keep the v1 admin schema byte-identical.

v4::messages additions: PathAttribute, PathAttributeType,
PathAttributeValue, PathAttributeTypeCode (12-variant), Aggregator,
As4Aggregator, As4PathSegment, MpReachNlri, MpReachIpv4Unicast,
MpReachIpv6Unicast, MpUnreachNlri, MpUnreachIpv4Unicast,
MpUnreachIpv6Unicast, and the path_attribute_flags constants module.

v1::messages additions (the v1 wire-shape compat types, formerly
named *V1 in bgp::messages): Prefix, PathAttribute, PathAttributeType,
PathAttributeTypeCode, PathAttributeValue. These are re-exported from
bgp::messages under their historical *V1 aliases to minimize call-site
churn.

impls/messages.rs gains Display impls for the new types, the
self-contained inherent methods (Aggregator/As4Aggregator
to_wire/from_wire/to_bytes; MpReach/MpUnreach afi/safi/nexthop/
ipv4_unicast/ipv6_unicast/is_empty/len), the v4 → v1 cross-version
From conversions, and reabsorbed-into-From impls for
path_attribute_type_code_of and From<PathAttributeValue> for
PathAttribute.

In bgp/src/messages.rs the type definitions become re-exports from
bgp_types::messages. Wire methods that produce bgp::error::Error or
UpdateParseErrorReason (PathAttribute::to_wire / from_bytes,
PathAttributeType::to_wire / error_action, PathAttributeValue::to_wire /
from_wire, As4PathSegment::to_wire / from_wire, MpReachNlri::to_wire /
from_wire, MpUnreachNlri::to_wire / from_wire) become free fns
(path_attribute_to_wire, path_attribute_from_bytes,
path_attribute_type_to_wire, path_attribute_type_error_action,
path_attribute_value_to_wire, path_attribute_value_from_wire,
as4_path_segment_to_wire, as4_path_segment_from_wire,
mp_reach_nlri_to_wire, mp_reach_nlri_from_wire,
mp_unreach_nlri_to_wire, mp_unreach_nlri_from_wire). Internal call
sites in bgp/src/messages.rs are updated.

WireError::PathAttributeCode in bgp-types-versions::error switches
from v1::messages::PathAttributeTypeCode (10-variant) to
v4::messages::PathAttributeTypeCode (12-variant) since wire parsing
operates on the MP-BGP form.

Verification: cargo fmt --check; cargo clippy --workspace -- -D warnings;
cargo nextest run --workspace (241 passed); cargo run -p xtask -- openapi
check (11 fresh, 0 stale, 0 failed). All blessed mg-admin/ddm-admin
schemas remain sha256-identical to baseline.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…nd to bgp-types-versions

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rorSubcode to bgp-types-versions

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
… RouteRefreshMessage to bgp-types-versions

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…types-versions, drop UpdateMessage::errors field

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…versions

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…erParameters families to mg-types-versions

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…fo/FsmStateKindV1 to mg-types-versions

Migrates the v1 and v2 forms of the PeerInfo family to mg-types-versions:
- v1::bgp::FsmStateKind (was params::FsmStateKindV1, 7-variant pre-IPV6_BASIC).
- v1::bgp::DynamicTimerInfo (was params::DynamicTimerInfoV1, 2-field).
- v1::bgp::PeerTimers (was params::PeerTimersV1).
- v1::bgp::PeerInfo (was params::PeerInfoV1).
- v2::bgp::PeerInfo (was params::PeerInfoV2).
- v4::bgp::DynamicTimerInfo (the latest 3-field form, re-exported as latest).

Cross-version conversions in mg-types-versions/src/impls/bgp.rs:
- From<bgp_types_versions::v2::session::FsmStateKind> for v1::bgp::FsmStateKind
- From<v2::bgp::PeerInfo> for v1::bgp::PeerInfo

The latest PeerInfo (v5 shape) and latest PeerTimers (v5 shape) remain in
bgp/src/params.rs because their public fields embed BgpCapability,
PeerCounters, and StaticTimerInfo, all of which are scheduled for sub-chunk
6c. mg-types-versions cannot depend on bgp, so those types must migrate
together. Sub-chunk 6c will pull the remaining PeerInfo/PeerTimers latest
forms across once the unversioned-but-published group lands.

bgp/src/params.rs preserves the existing public surface via re-export
aliases so call sites in mgd/mg-api are unchanged.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…d rdb tail to versions crates

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ffixed convention

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…rse module

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…dules

Three orphan-rule-adjacent violations found in `mg-types-versions/src/impls/`:

- `From<latest::static_routes::StaticRoute{4,6}> for rdb::StaticRouteKey`
  forced `mg-types-versions` to depend on `rdb` (a business-logic crate).
  Replaced with free fns at the only call site (`mgd/src/static_admin.rs`).
- `From<rdb::db::Rib> for {latest, v1}::rib::Rib` had the same problem.
  Replaced with `rib_latest_from_rdb` / `rib_v1_from_rdb` free fns in
  `mg-types/src/rib.rs` (the facade crate, which already depends on both
  `rdb` and `rdb-types-versions`).

`mg-types-versions` no longer depends on `rdb`. The Phase 3 audit
(`rg "use {bgp,rdb,mg_common,ddm}::"` and the corresponding `_types::`
sweep across all `*-types-versions/src/`) is now clean.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…or migrated paths

Adds `docs/types-organization.md` as a tangible reference for where
schema-published types now live: facade vs versions crate pairs, the
crate map, a type -> crate quick reference, and recipes for adding new
types and new API versions. Calls out the leaf-crate rule, the
internal-vs-published distinction, and the boundary helpers (free
functions in the facade crate or at call sites) used when both source
and target of a conversion are foreign.

`docs/bgp-architecture.md` and `docs/bgp-unnumbered.md` were scanned for
stale type-path references and are unchanged: they reference types only
by short name (`MessageHistory`, `FsmStateKind`, `Path`, `PeerId`),
which remain valid via the facade re-exports.

`README.md` was scanned for moved type paths and is unchanged.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ports

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Adds a dedicated facade+versions crate pair for BFD types and migrates
`BfdPeerState`, `BfdPeerConfig`, `BfdPeerInfo`, and `SessionMode` into
`bfd-types-versions::v1`. This was the last leaf-crate-rule violation in
`mg-types-versions` — its `bfd.workspace = true` dependency (and the
transitive edge into `rdb`/`mg-common`) is now gone.

Type relocations:
- `BfdPeerState` (was `bfd::BfdPeerState`) -> `bfd_types_versions::v1`,
  with the `wire_format()` helper carried along as an inherent method.
- `BfdPeerConfig` and `SessionMode` (was
  `rdb_types_versions::v1::bfd::*`) -> `bfd_types_versions::v1`.
- `BfdPeerInfo` (was `mg_types_versions::v1::bfd`) ->
  `bfd_types_versions::v1`. `mg_types_versions::v1::bfd` keeps only
  `DeleteBfdPeerPathParams` (an admin-API path-params shape, not a BFD
  type proper).

Call-site updates: `bfd`, `rdb`, `mg-api`, and `mgd` now import BFD
types from the `bfd-types` facade. `bfd::BfdPeerState` continues to work
via a `pub use` re-export.

OpenAPI verification: `cargo run -p xtask -- openapi check` reports zero
stale documents — all schemas (`BfdPeerState`, `BfdPeerConfig`,
`BfdPeerInfo`, `SessionMode`) emit byte-identical JsonSchema output, so
no client regeneration is required.

Drive-by: also fixes a stale doc comment in `bgp/src/session.rs` that
referred to the (since-renamed) `UpdateMessage::from_wire()` method;
the actual function is the free fn `update_message_from_wire`.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Extends the per-domain test-* jobs to cover their corresponding type
crates so any future tests added there get picked up automatically:

- test-bfd: adds `bfd-types` and `bfd-types-versions`.
- test-bgp: adds `bgp-types` and `bgp-types-versions` (alongside bgp);
  adds `mg-types` and `mg-types-versions` (alongside mgd).
- test-rdb: adds `rdb-types` and `rdb-types-versions` (alongside rdb).

Bare `-p rdb-types` is ambiguous because omicron transitively pins an
upstream copy of rdb-types via mg-admin-client, leaving two rdb-types
nodes in Cargo.lock. The Package ID Spec form
`path+file://$PWD/../rdb-types` selects the local crate unambiguously.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Squashes adjacent same-prefix `pub use`/`use` lines into single
braced statements and lifts scattered branch-added re-exports to the
top of each file. Touches only items the branch already added or
moved; pre-existing imports and test-module imports are left alone.

- bgp/src/messages.rs: 20 scattered `pub use bgp_types::messages::*`
  and `pub use bgp_types_versions::*` lines -> four consolidated
  blocks at the top.
- bgp/src/session.rs: three scattered uses -> top of file; trims a
  stale doc-comment block whose content is now redundant.
- bgp/src/params.rs: drops single-use `v{1,2,4,5,8}_bgp` aliases in
  favor of fully-qualified `pub use mg_types_versions::vN::bgp::{...}`.
- mg-types/versions/src/latest.rs, mg-common-types/versions/src/latest.rs,
  mg-types/src/rib.rs, bfd/src/lib.rs: minor adjacent-run merges.

OpenAPI verified byte-identical (`cargo xtask openapi check`: all 10
documents fresh). 152 of 152 bgp+bfd tests still pass.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
@taspelund taspelund requested a review from rcgoodfellow April 28, 2026 07:29
@taspelund taspelund self-assigned this Apr 28, 2026
@taspelund taspelund added ddm Delay Driven Multipath dependencies mgd Maghemite daemon rust Pull requests that update rust code labels Apr 28, 2026
taspelund added 16 commits May 8, 2026 19:34
Brings in 15 commits from main, the most substantive being:

- #730 [mg-admin-api] fix v2/v3 MessageHistory and related types
- #715 Update Rust crate rust to v1.95.0 (with clippy::useless_conversion fix)
- #710 dropshot 0.7.1
- #707 opte update
- assorted dep bumps (tokio, clap, oxnet, uuid, oxide-tokio-rt, openssl,
  reqwest, libc) and lock-file maintenance

Notes on conflict resolution:

- mg-types/versions/src/ipv6_basic/bgp.rs: incorporated #730's v2
  MessageHistory/MessageHistoryEntry/Message/UpdateMessage types and
  their From-from-live conversions, but retargeted imports through
  bgp-types-versions and rdb-types-versions to preserve the leaf-crate
  rule cleanup from this branch (the commit message on #730 calls out
  that this is a known short-term shortcut). Same approach for
  mg-types/versions/src/mp_bgp/bgp.rs (where #730 added a v4
  MessageHistoryResponse).
- mg-types/versions/Cargo.toml: kept the leaf-rule-clean dep set
  (bgp-types-versions, rdb-types-versions) and added chrono per #730's
  need for chrono::DateTime in MessageHistoryEntry.
- bgp-types/versions/src/ipv6_basic/session.rs: promoted
  MessageHistoryEntry's timestamp/message/connection_id fields back
  from pub(crate) to pub. The migration in this branch had
  inadvertently tightened the visibility (they were pub on main); #730
  needs pub access for its From impl.
- bgp-types/versions/src/impls/messages.rs: applied #715's
  clippy::useless_conversion fix at the migrated location
  (impl OpenMessage::get_capabilities), which is where the original
  bgp::messages code now lives after our migration.
- bgp/src/messages.rs and bgp/src/session.rs: took our side; #715's
  clippy fix applies to the migrated location, not the bgp-local
  free-fn replacements.
- mg-api/src/lib.rs: kept our use bfd_types::{BfdPeerConfig, BfdPeerInfo}
  import; took main's mg_types_versions::{latest, v1, v2, v4, v5}
  (gaining v4 for #730's MessageHistoryResponse v4 endpoint).
- Cargo.lock: regenerated.

Verified: cargo check --workspace --all-features clean, cargo clippy
--workspace --all-features --no-deps clean (only pre-existing lab/
warnings), cargo run -p xtask -- openapi check shows all 10 documents
fresh (byte-identical schemas), 152/152 tests pass on bgp + bfd +
*-types-versions crates.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Pure rename of crate names and directory paths. No content moves; the
rest of the API-shape consolidation lands in subsequent commits.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Pure rename. Mirror of the mg-types rename in the prior commit.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Move BfdPeerConfig, BfdPeerInfo, BfdPeerState, SessionMode (and the
wire_format() inherent method) into mg-api-types-versions::v1::bfd
alongside the pre-existing DeleteBfdPeerPathParams. Re-export them
through mg-api-types::bfd. Delete the bfd-types/{,versions} crates.

rdb consumes the data types via mg-api-types-versions directly (not
through the mg-api-types facade) to avoid a rdb -> mg-api-types -> rdb
cycle.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Move BGP wire-message and session content into the per-version bgp/
subtree of mg-api-types-versions:
  initial/bgp/{messages,session,config}.rs
  ipv6_basic/bgp/{session,history}.rs
  mp_bgp/bgp/{messages,config}.rs
plus error.rs, parse.rs, impls/{messages,session}.rs at the crate root.

Each vN/bgp/mod.rs flattens its config/history sub-module so existing
intra-crate references like crate::v1::bgp::CheckerSource keep working.
The wire-message and session sub-modules stay namespaced.

Cargo deps for the bgp wire types (nom, num_enum, slog, thiserror, uuid,
clap feature) move onto mg-api-types-versions; bgp-types{,-versions} are
deleted.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Move all routing-database type content into per-version rdb/ subtrees of
mg-api-types-versions:
  initial/rdb/{mod,path,peer,policy,prefix,router}.rs (AddressFamily and
    ProtocolFilter live at v1::rdb::* per the moved mod.rs)
  mp_bgp/rdb/{neighbor,policy}.rs
  unnumbered/rdb/path.rs
  impls/{path,peer,policy,prefix}.rs at the crate root.

Add a latest::rdb module mirroring the old rdb-types-versions::latest
shape (flat AddressFamily/ProtocolFilter plus nested neighbor / path /
peer / policy / prefix / router).

mg-api-types/src/lib.rs flat-re-exports latest::rdb::* so consumers
reach Prefix4, AddressFamily, etc. via mg_api_types::*; the progenitor
replace block depends on these top-level paths.

rdb consumes the routing-database types via mg-api-types-versions
directly to avoid a rdb -> mg-api-types -> rdb cycle.

The two PeerId/AddressFamily doctest fragments and two Prefix{4,6}
doctest fragments retain their use rdb_types::*; lines verbatim to
preserve schemars-derived schema descriptions byte-for-byte.

Cargo: oxnet moves onto mg-api-types-versions; rdb-types{,-versions}
deleted from the workspace.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Move TunnelOrigin, IpPrefix, Ipv4Prefix, Ipv6Prefix into
ddm-api-types-versions/src/initial/net.rs and re-export them through
ddm-api-types::net. The "common" framing dissolves - these types are
DDM-specific despite their old crate name.

mg-common::net (consumed by maghemite for legacy TunnelOriginV2 shims)
now imports from ddm-api-types directly. The mg- -> ddm- crate edge is
unusual but reflects the reality of the type ownership.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
docs/types-organization.md describes the new two-pair API-shape layout
(mg-api-types/{,versions} and ddm-api-types/{,versions}), including the
internal vN/{bgp,rdb}/ subtree, latest.rs structure, and facade
flat-re-export rules used by the mg-admin-client progenitor replace
block.

Buildomat jobs swap the old per-domain test crates for the two new
versions crates:
  - test-bfd.sh, test-bgp.sh, test-rdb.sh, test-ddm.sh

The rdb-types path+file:// workaround is no longer needed: the upstream
omicron pin still exports rdb-types under that name, but our local
crate is now mg-api-types, so -p mg-api-types is unambiguous.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>

replace V1/V6/Live import aliases with versioned-prefix paths

The "as FooV1" / "as FooV6" / "as Live*" import aliases were transitional
pre-RFD-619 patterns: import the same nominal type from multiple version
modules and disambiguate by suffix (V1/V6) or semantic tag (Live = current
runtime form for downgrade conversions). RFD 619 disambiguates by versioned
module path instead, so v1::bgp::config::Neighbor and
v4::bgp::config::Neighbor coexist without renames, and the ipv6_basic
downgrade impls take v4::bgp::messages::Message directly rather than
v4::bgp::messages::Message-as-LiveMessage.

Files: bgp/src/{params,session}.rs, mg-api/src/lib.rs, mgd/src/{admin,
bgp_admin}.rs, mg-api-types/versions/src/{impls/{bgp,messages,session,
rib},initial/bgp/config,ipv6_basic/bgp/history}.rs.

bgp::params now re-exports only the latest admin-API forms plus the
small set of helper types that are the same across versions (CheckerSource,
Origin4, Router, ShaperSource, Origin6, AfiSafi, etc.). Cross-version
callers (mgd per-version endpoints, mg-api API definitions) reach for
mg_api_types_versions::vN::bgp::* directly so the version is visible at
the use site.

Side-benefit: the misleading "V6 = v4" trap is gone — the v4 form is
just v4::bgp::config::* in code, no alias inversion to remember. And
ipv6_basic/bgp/history.rs imports got nested-grouped for readability.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Drop the `pub use config::*;` and `pub use history::*;` re-exports from
each vN/bgp/mod.rs. Internal references now go through
`crate::vN::bgp::config::Foo` and `crate::v2::bgp::history::Foo`
explicitly, matching the playbook rule against wildcard re-exports.

Mechanical: bgp_src_addr/bgp.rs (v8), unnumbered/bgp.rs (v5),
mp_bgp/bgp/config.rs, ipv6_basic/{bgp/{history,session},rib,
static_routes}.rs, initial/{bgp/session,static_routes}.rs,
impls/{bgp,messages,session}.rs, plus consumer files
bgp/src/params.rs, mg-api/src/lib.rs, mg-api-types/src/rib.rs,
mgd/src/{admin,bgp_admin,rib_admin}.rs all gain the explicit
::config:: or ::history:: segment for each affected reference.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Convert From impls and free fns that translate published API types
into runtime/internal shapes so they destructure the source struct
fully. Adding a field to a published type now fails to bind here,
forcing a deliberate decision about runtime threading rather than a
silent drop.

Sites covered:
  bgp/src/session.rs    From<&BgpPeerParameters> for SessionInfo
                        From<&BgpPeerParametersV1> for SessionInfo
  bgp/src/params.rs     From<Neighbor> for PeerConfig
                        From<NeighborV1> for PeerConfig
                        PeerConfig::from_unnumbered_neighbor
  rdb/src/types.rs      From<StaticRouteKey> for Path
  mg-common/src/net.rs  From<TunnelOriginV2> for TunnelOrigin
                        From<TunnelOrigin> for TunnelOriginV2
  mgd/src/static_admin  static_route_key_from_v4
                        static_route_key_from_v6

V1 forms and TunnelOriginV2 are frozen by design; the destructure
note in those impls says the contract is violated upstream rather
than teaching the conversion to handle a new field.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
These were defined inside bgp/src/messages.rs as a transitional shim
during the RFD 619 migration: bgp owned them while the latest forms
(UpdateMessage / Message) were in the process of moving into the
mg-api-types{,-versions} crates. The latest forms have moved, the v1
shapes live in mg_api_types_versions::v1::bgp::messages alongside
their cross-version From impls in mg_api_types_versions::impls::messages,
so the bgp-local definitions are now dead duplicates.

Drops the two type definitions, both From impls, and the cluster of
'as PathAttributeV1' / 'as PrefixV1' / etc. import aliases in
bgp/src/messages.rs that existed only to feed those impls. There are
no external consumers (verified by grep).

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Convert From impls in mg-api-types-versions/impls/ that translate
between API version forms so they destructure the source struct fully.
Adding a field to the source version now fails to bind here, forcing
a deliberate decision about how (or whether) the new field surfaces in
the target version, rather than a silent drop.

Files covered:
  bgp.rs       — neighbor / peer-config / parameters / apply-request
                 conversions across v1, v4, v5, latest. The shared
                 latest_params_from_rdb / v1_params_from_rdb helpers
                 own the BgpNeighborParameters destructure once.
  messages.rs  — UpdateMessage (latest -> v1), PathAttribute,
                 PathAttributeType. The Message wrapper and the
                 PathAttributeValue / PathAttributeTypeCode enums use
                 exhaustive matches as their compile barrier. The
                 v1::Capability match names every variant explicitly
                 (no wildcard) so adding a new variant fails to compile.
  session.rs   — MessageHistory and MessageHistoryEntry (v2 -> v1).

Files left as-is:
  peer.rs / prefix.rs — From impls take primitives or wrap enum
                        variants; no struct fields to destructure.
  rib.rs              — From<latest::rdb::Rib> iterates a BTreeMap
                        alias; no struct fields.

Frozen versions (v1, v4, v5) carry a comment that the destructure
guards an upstream contract violation rather than a normal field
addition.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
bgp::params used to be the API-shape facade for bgp ("params of the
API"). After RFD 619 moved the API-shape types to mg-api-types, that
role is gone — bgp::params became a grab-bag of bgp-internal types
sitting in params.rs for historical reasons, plus 7 dead request /
response shapes (AddExportPolicyRequest, Withdraw4Request,
GracefulShutdownRequest, GetOriginated4Request, GetRoutersRequest,
GetRouersResponse, RouterInfo) with no consumers.

Drop the dead shapes and redistribute the live content to its
semantic home:

  TimerConfig                          -> bgp::clock
  PolicySource / PolicyKind            -> bgp::policy
  PeerConfig From impls                -> bgp::config
  From<&SessionCounters> for PeerCounters -> bgp::session

bgp/src/params.rs and `pub mod params;` go away.

Latest published API forms (Neighbor, BgpPeerConfig, BgpPeerParameters,
ApplyRequest, ...) are now reached via mg_api_types::bgp::* throughout
the workspace; older shapes via mg_api_types_versions::vN::bgp::*
directly. NeighborResetOp moves into mg-api-types-versions::latest::bgp
(it was already published as a NeighborResetRequest field but missing
from the latest re-export).

Consumer updates: bgp/src/{session,clock,test}.rs,
mgd/src/{admin,bgp_admin}.rs, mg-api/src/lib.rs, mgadm/src/bgp.rs.
mgadm gains an mg-api-types dep.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
- TimerConfig in bgp::clock now uses the bare types (Duration,
  Serialize, Deserialize, JsonSchema, SessionInfo) that the file
  already imports, dropping the noisy fully-qualified spellings the
  retirement commit landed with.

- TimerConfig::from_session_info becomes impl From<&SessionInfo> for
  TimerConfig (idiomatic conversion), with the single mgd caller
  updated to TimerConfig::from(&*session_conf).

- bgp::config's PeerConfig boundary-conversion comment no longer
  cross-references the From<&BgpPeerParameters> for SessionInfo impl
  in bgp::session by name. The comment now states the property
  directly (PeerConfig only carries connection-state fields; other
  parameters are session-level).

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…_api_types

Walk mgadm and falcon-lab consumers of mg_admin_client::types::* and
hoist references to the canonical mg_api_types::* path where the
schema-generated form and the Rust canonical form are equivalent.
Each replaced type gets a corresponding entry in the progenitor
replace = {} block in mg-admin-client/src/lib.rs.

Replaced (now reachable as either mg_admin_client::types::Foo or the
canonical Rust path; same nominal type):
  - BGP admin shapes that do not use #[serde(flatten)]:
    CheckerSource, ExportedSelector, FsmEventBuffer,
    Ipv4UnicastConfig, Ipv6UnicastConfig, JitterRange,
    MessageDirection, NeighborResetOp, NeighborResetRequest,
    Origin4, Origin6, PeerInfo, Router, ShaperSource,
    UnnumberedNeighborResetRequest.
  - BGP wire-message types: Afi.
  - BGP session types: FsmStateKind.
  - RIB shapes: BestpathFanoutRequest.
  - Static-route shapes: AddStaticRoute{4,6}Request,
    DeleteStaticRoute{4,6}Request, StaticRoute{4,6},
    StaticRoute{4,6}List.
  - Policy shapes: ImportExportPolicy{,4,6}.

Not replaced (kept as generated forms):
  - Types that use #[serde(flatten)] for parameters
    (Neighbor, UnnumberedNeighbor, BgpPeerConfig,
    UnnumberedBgpPeerConfig, BgpPeerParameters, ApplyRequest):
    progenitor generates a flat struct while the canonical Rust form
    is nested. Wire JSON matches but caller construction sites would
    have to switch from flat literals to nested ones; not worth the
    churn here.
  - Server-side request types whose canonical form is Deserialize-only
    (FsmHistoryRequest, MessageHistoryRequest): the client needs
    Serialize on the request body.

ImportExportPolicy{,4,6} move from mg_api_types::* (flat root
re-exports) to mg_api_types::bgp::*. Their schema is BGP-specific
even though rdb stores them at runtime, and the dual-path
exposure was a back-slid version of the dual-facade anti-pattern
this branch has otherwise removed. rdb::types reaches them through
the new bgp:: path.

Identity conversion helpers in mgadm/src/bgp.rs (jitter_range_to_api,
afi_to_api, peer_id_to_api) are deleted — they used to bridge
generated and canonical forms but those are now the same nominal
type after replace.

Consumer sites in mgadm/{bgp,bfd,rib,static_routing}.rs and
falcon-lab/{bgp,test}.rs switch from mg_admin_client::types::Foo to
mg_api_types::area::Foo for every replaced type.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
…ers through it

The previous round exposed ImportExportPolicy{,4,6} via mg_api_types::bgp::*
because they are BGP-specific schema-published types, but their
underlying definitions still lived in mg-api-types-versions/src/.../rdb/policy.rs.
PeerId had the symmetric mismatch: definition in rdb/peer.rs, schema use
strictly through BGP-area types (NeighborSelector, BgpPathProperties,
etc.), and a re-export chain bgp::session::PeerId -> rdb::PeerId ->
mg_api_types::PeerId that hid the BGP ownership.

File definitions move to match the facade exposure:
  initial/rdb/peer.rs    -> initial/bgp/peer.rs
  initial/rdb/policy.rs  -> initial/bgp/policy.rs
  mp_bgp/rdb/policy.rs   -> mp_bgp/bgp/policy.rs

Module declarations shift accordingly; intra-crate references
v{1,4}::rdb::{peer,policy}:: -> v{1,4}::bgp::{peer,policy}::.
latest::bgp adds direct re-exports of PeerId and
ImportExportPolicy{,4,6}, no longer cross-area pulls into the bgp
facade. latest::rdb drops its peer / policy submodules — rdb-area
code that needs those types reaches them through bgp.

mg-api-types/src/lib.rs drops the root flat re-export of PeerId.
PeerId now lives only at mg_api_types::bgp::PeerId.

bgp::session and mgd::admin stop reaching PeerId through rdb; both
pull from mg_api_types::bgp::PeerId directly, matching the
convention from earlier rounds for latest-API types.

rdb::types reaches the bgp-domain types via mg_api_types::bgp::*
and the routing-database-domain types via the mg_api_types::*
flat root, with a comment that says so honestly.

mg-api-types-versions/src/impls/{peer,policy}.rs gain short
module-level docstrings pointing at the source modules they impl
on, so a navigator who lands in the impls/ directory does not have
to grep to learn where the types live.

Progenitor replace block in mg-admin-client/src/lib.rs follows
PeerId from the routing-database-shapes section into the BGP-domain
shapes section.

Signed-off-by: Trey Aspelund <trey@oxidecomputer.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ddm Delay Driven Multipath dependencies mgd Maghemite daemon rust Pull requests that update rust code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant