Skip to content

Commit

Permalink
ddm tunnel routing (#77)
Browse files Browse the repository at this point in the history
  • Loading branch information
rcgoodfellow authored Jan 23, 2024
1 parent e76dc67 commit 869cf80
Show file tree
Hide file tree
Showing 33 changed files with 2,207 additions and 259 deletions.
238 changes: 220 additions & 18 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,17 @@ sled = "0.34"
ciborium = "0.2"
http = "0.2"
humantime = "2.1"
rand = "0.8"
mg-common = { path = "mg-common" }

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

[workspace.dependencies.oxide-vpc]
git = "https://github.com/oxidecomputer/opte"
branch = "master"

[workspace.dependencies.dpd-client]
git = "https://github.com/oxidecomputer/dendrite"
branch = "main"
Expand Down
4 changes: 3 additions & 1 deletion bgp/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,9 @@ impl<Cnx: BgpConnection + 'static> SessionRunner<Cnx> {
id,
priority,
};
self.db.set_nexthop4(k);
if let Err(e) = self.db.set_nexthop4(k, false) {
err!(self; "failed to set nexthop {k:#?}: {e}");
}
}
}

Expand Down
1 change: 1 addition & 0 deletions ddm-admin-client/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ slog = "2.7"
percent-encoding.workspace = true
reqwest.workspace = true
progenitor.workspace = true
ddm = { path = "../ddm" }
15 changes: 13 additions & 2 deletions ddm-admin-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,28 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

pub use ddm::db::IpPrefix;
pub use ddm::db::Ipv4Prefix;
pub use ddm::db::Ipv6Prefix;
pub use ddm::db::TunnelOrigin;

progenitor::generate_api!(
spec = "../openapi/ddm-admin.json",
inner_type = slog::Logger,
pre_hook = (|log: &slog::Logger, request: &reqwest::Request| {
slog::debug!(log, "client request";
slog::trace!(log, "client request";
"method" => %request.method(),
"uri" => %request.url(),
"body" => ?&request.body(),
);
}),
post_hook = (|log: &slog::Logger, result: &Result<_, _>| {
slog::debug!(log, "client response"; "result" => ?result);
slog::trace!(log, "client response"; "result" => ?result);
}),
replace = {
IpPrefix = ddm::db::IpPrefix,
Ipv4Prefix = ddm::db::Ipv4Prefix,
Ipv6Prefix = ddm::db::Ipv6Prefix,
TunnelOrigin = ddm::db::TunnelOrigin,
}
);
2 changes: 2 additions & 0 deletions ddm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ serde_json.workspace = true
libnet.workspace = true
dpd-client.workspace = true
dendrite-common.workspace = true
opte-ioctl.workspace = true
oxide-vpc.workspace = true
93 changes: 85 additions & 8 deletions ddm/src/admin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at https://mozilla.org/MPL/2.0/.

use crate::db::{Db, Ipv6Prefix, PeerInfo};
use crate::db::{Db, Ipv6Prefix, PeerInfo, TunnelOrigin, TunnelRoute};
use crate::exchange::PathVector;
use crate::sm::{AdminEvent, Event};
use crate::sm::{AdminEvent, Event, PrefixSet};
use dropshot::endpoint;
use dropshot::ApiDescription;
use dropshot::ConfigDropshot;
Expand Down Expand Up @@ -99,7 +99,10 @@ async fn expire_peer(
let ctx = ctx.context().lock().unwrap();

for e in &ctx.event_channels {
e.send(Event::Admin(AdminEvent::Expire(addr))).unwrap(); //TODO unwrap
e.send(Event::Admin(AdminEvent::Expire(addr)))
.map_err(|e| {
HttpError::for_internal_error(format!("admin event send: {e}"))
})?;
}

Ok(HttpResponseUpdatedNoContent())
Expand All @@ -116,6 +119,15 @@ async fn get_originated(
Ok(HttpResponseOk(originated))
}

#[endpoint { method = GET, path = "/originated_tunnel_endpoints" }]
async fn get_originated_tunnel_endpoints(
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
) -> Result<HttpResponseOk<HashSet<TunnelOrigin>>, HttpError> {
let ctx = ctx.context().lock().unwrap();
let originated = ctx.db.originated_tunnel();
Ok(HttpResponseOk(originated))
}

#[endpoint { method = GET, path = "/prefixes" }]
async fn get_prefixes(
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
Expand Down Expand Up @@ -144,6 +156,15 @@ async fn get_prefixes(
Ok(HttpResponseOk(result))
}

#[endpoint { method = GET, path = "/tunnel_endpoints" }]
async fn get_tunnel_endpoints(
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
) -> Result<HttpResponseOk<HashSet<TunnelRoute>>, HttpError> {
let ctx = ctx.context().lock().unwrap();
let imported = ctx.db.imported_tunnel();
Ok(HttpResponseOk(imported))
}

#[endpoint { method = PUT, path = "/prefix" }]
async fn advertise_prefixes(
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
Expand All @@ -154,8 +175,33 @@ async fn advertise_prefixes(
ctx.db.originate(&prefixes);

for e in &ctx.event_channels {
e.send(Event::Admin(AdminEvent::Announce(prefixes.clone())))
.unwrap(); //TODO(unwrap)
e.send(Event::Admin(AdminEvent::Announce(PrefixSet::Underlay(
prefixes.clone(),
))))
.map_err(|e| {
HttpError::for_internal_error(format!("admin event send: {e}"))
})?;
}

Ok(HttpResponseUpdatedNoContent())
}

#[endpoint { method = PUT, path = "/tunnel_endpoint" }]
async fn advertise_tunnel_endpoints(
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
request: TypedBody<HashSet<TunnelOrigin>>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
let ctx = ctx.context().lock().unwrap();
let endpoints = request.into_inner();
ctx.db.originate_tunnel(&endpoints);

for e in &ctx.event_channels {
e.send(Event::Admin(AdminEvent::Announce(PrefixSet::Tunnel(
endpoints.clone(),
))))
.map_err(|e| {
HttpError::for_internal_error(format!("admin event send: {e}"))
})?;
}

Ok(HttpResponseUpdatedNoContent())
Expand All @@ -171,8 +217,33 @@ async fn withdraw_prefixes(
ctx.db.withdraw(&prefixes);

for e in &ctx.event_channels {
e.send(Event::Admin(AdminEvent::Withdraw(prefixes.clone())))
.unwrap(); //TODO(unwrap)
e.send(Event::Admin(AdminEvent::Withdraw(PrefixSet::Underlay(
prefixes.clone(),
))))
.map_err(|e| {
HttpError::for_internal_error(format!("admin event send: {e}"))
})?;
}

Ok(HttpResponseUpdatedNoContent())
}

#[endpoint { method = DELETE, path = "/tunnel_endpoint" }]
async fn withdraw_tunnel_endpoints(
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
request: TypedBody<HashSet<TunnelOrigin>>,
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
let ctx = ctx.context().lock().unwrap();
let endpoints = request.into_inner();
ctx.db.withdraw_tunnel(&endpoints);

for e in &ctx.event_channels {
e.send(Event::Admin(AdminEvent::Withdraw(PrefixSet::Tunnel(
endpoints.clone(),
))))
.map_err(|e| {
HttpError::for_internal_error(format!("admin event send: {e}"))
})?;
}

Ok(HttpResponseUpdatedNoContent())
Expand All @@ -185,7 +256,9 @@ async fn sync(
let ctx = ctx.context().lock().unwrap();

for e in &ctx.event_channels {
e.send(Event::Admin(AdminEvent::Sync)).unwrap(); //TODO(unwrap)
e.send(Event::Admin(AdminEvent::Sync)).map_err(|e| {
HttpError::for_internal_error(format!("admin event send: {e}"))
})?;
}

Ok(HttpResponseUpdatedNoContent())
Expand All @@ -197,9 +270,13 @@ pub fn api_description(
api.register(get_peers)?;
api.register(expire_peer)?;
api.register(advertise_prefixes)?;
api.register(advertise_tunnel_endpoints)?;
api.register(withdraw_prefixes)?;
api.register(withdraw_tunnel_endpoints)?;
api.register(get_prefixes)?;
api.register(get_tunnel_endpoints)?;
api.register(get_originated)?;
api.register(get_originated_tunnel_endpoints)?;
api.register(sync)?;
Ok(api)
}
Loading

0 comments on commit 869cf80

Please sign in to comment.