Skip to content

Commit 818e66c

Browse files
enable mgd to be aware of what switch it is managing (#569)
This change is primarily a part of a larger effort to make the switch zone services location aware by having them communicate with their local MGS. This is also required to allow us to deploy some form of the daemon in our test context in omicron. --- Related: * oxidecomputer/omicron#8999 * oxidecomputer/omicron#9533
1 parent 251ae71 commit 818e66c

10 files changed

Lines changed: 4059 additions & 3 deletions

File tree

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ proptest = "1.4"
114114
serial_test = "3.2"
115115
ddm-api = { path = "ddm-api" }
116116
ddm-types = { path = "ddm-types" }
117+
gateway-client = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
117118

118119
[workspace.dependencies.opte-ioctl]
119120
git = "https://github.com/oxidecomputer/opte"

mg-api/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ api_versions!([
4040
// | example for the next person.
4141
// v
4242
// (next_int, IDENT),
43+
(3, SWITCH_IDENTIFIERS),
4344
(2, IPV6_BASIC),
4445
(1, INITIAL),
4546
]);
@@ -371,6 +372,20 @@ pub trait MgAdminApi {
371372
async fn static_list_v6_routes(
372373
ctx: RequestContext<Self::Context>,
373374
) -> Result<HttpResponseOk<GetRibResult>, HttpError>;
375+
376+
#[endpoint {method = GET, path = "/switch/identifiers", versions = VERSION_SWITCH_IDENTIFIERS.. }]
377+
async fn switch_identifiers(
378+
ctx: RequestContext<Self::Context>,
379+
) -> Result<HttpResponseOk<SwitchIdentifiers>, HttpError>;
380+
}
381+
382+
/// Identifiers for a switch.
383+
#[derive(Clone, Debug, JsonSchema, Serialize)]
384+
pub struct SwitchIdentifiers {
385+
/// The slot number of the switch being managed.
386+
///
387+
/// MGS uses u16 for this internally.
388+
pub slot: Option<u16>,
374389
}
375390

376391
#[derive(Debug, Copy, Clone, Serialize, Deserialize, JsonSchema)]

mgd/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ omicron-common.workspace = true
2626
hostname.workspace = true
2727
uuid.workspace = true
2828
smf.workspace = true
29+
gateway-client.workspace = true
2930

3031
[dev-dependencies]
3132
tempfile = "3"

mgd/src/admin.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,12 @@ impl MgAdminApi for MgAdminApiImpl {
438438
) -> Result<HttpResponseOk<GetRibResult>, HttpError> {
439439
static_admin::static_list_v6_routes(ctx).await
440440
}
441+
442+
async fn switch_identifiers(
443+
ctx: RequestContext<Self::Context>,
444+
) -> Result<HttpResponseOk<SwitchIdentifiers>, HttpError> {
445+
static_admin::switch_identifiers(ctx).await
446+
}
441447
}
442448

443449
pub fn api_description() -> ApiDescription<Arc<HandlerContext>> {

mgd/src/main.rs

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rdb::{BfdPeerConfig, BgpNeighborInfo, BgpRouterInfo};
1717
use signal::handle_signals;
1818
use slog::Logger;
1919
use std::collections::{BTreeMap, BTreeSet};
20-
use std::net::{IpAddr, Ipv6Addr};
20+
use std::net::{IpAddr, Ipv6Addr, SocketAddr};
2121
use std::sync::{Arc, Mutex};
2222
use std::thread::Builder;
2323
use uuid::Uuid;
@@ -88,6 +88,10 @@ struct RunArgs {
8888
/// Id of the sled this router is running on.
8989
#[arg(long)]
9090
sled_uuid: Option<Uuid>,
91+
92+
/// SocketAddr the MGS service is listening on.
93+
#[arg(long, default_value = "[::1]:12225")]
94+
mgs_addr: SocketAddr,
9195
}
9296

9397
fn main() {
@@ -123,6 +127,12 @@ async fn run(args: RunArgs) {
123127
oximeter_port: args.oximeter_port,
124128
});
125129

130+
detect_switch_slot(
131+
context.clone(),
132+
args.mgs_addr,
133+
tokio::runtime::Handle::current(),
134+
);
135+
126136
if let Err(e) = sig_tx.send(context.clone()).await {
127137
dlog!(log, error, "error sending handler context to signal handler: {e}";
128138
"params" => format!("tep {tep_ula}, dir {}, oximeter_port {}",
@@ -202,6 +212,44 @@ async fn run(args: RunArgs) {
202212
j.await.expect("API server quit unexpectedly");
203213
}
204214

215+
fn detect_switch_slot(
216+
ctx: Arc<HandlerContext>,
217+
mgs_socket_addr: SocketAddr,
218+
rt: tokio::runtime::Handle,
219+
) {
220+
let url = format!("http://{mgs_socket_addr}");
221+
let client_log = ctx.log.new(slog::o!("unit" => "gateway-client"));
222+
let task = async move || {
223+
let client = gateway_client::Client::new(&url, client_log);
224+
let ctx = ctx.clone();
225+
226+
loop {
227+
// check in with gateway
228+
let gateway_client::types::SpIdentifier { slot, .. } = match client
229+
.sp_local_switch_id()
230+
.await
231+
{
232+
Ok(v) => *v,
233+
Err(e) => {
234+
slog::error!(ctx.log, "failed to resolve switch slot"; "error" => %e);
235+
tokio::time::sleep(tokio::time::Duration::from_secs(10))
236+
.await;
237+
continue;
238+
}
239+
};
240+
241+
slog::info!(ctx.log, "we are in switch slot {slot}");
242+
243+
// update db
244+
let mut db = ctx.db.clone();
245+
db.set_slot(Some(slot));
246+
break;
247+
}
248+
};
249+
250+
rt.spawn(task());
251+
}
252+
205253
fn init_bgp(args: &RunArgs, log: &Logger) -> BgpContext {
206254
let addr_to_session = Arc::new(Mutex::new(BTreeMap::new()));
207255
if !args.no_bgp_dispatcher {

mgd/src/static_admin.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,3 +134,10 @@ pub async fn static_list_v6_routes(
134134

135135
Ok(HttpResponseOk(static_rib))
136136
}
137+
138+
pub(crate) async fn switch_identifiers(
139+
ctx: RequestContext<Arc<HandlerContext>>,
140+
) -> Result<HttpResponseOk<mg_api::SwitchIdentifiers>, HttpError> {
141+
let slot = ctx.context().db.slot();
142+
Ok(HttpResponseOk(mg_api::SwitchIdentifiers { slot }))
143+
}

0 commit comments

Comments
 (0)