Skip to content

Commit 77749e3

Browse files
authored
migrate net/prefix types to oxnet (#266)
In addition, this cleans up some of the features to ensure that illumos-only dependencies aren't pulled in when they aren't needed.
1 parent f22b10f commit 77749e3

File tree

24 files changed

+200
-530
lines changed

24 files changed

+200
-530
lines changed

Cargo.lock

+5
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ mg-common = { path = "mg-common" }
8282
chrono = { version = "0.4.38", features = ["serde"] }
8383
oximeter = { git = "https://github.com/oxidecomputer/omicron", branch = "main"}
8484
oximeter-producer = { git = "https://github.com/oxidecomputer/omicron", branch = "main"}
85+
oxnet = { git = "https://github.com/oxidecomputer/oxnet" }
8586
omicron-common = { git = "https://github.com/oxidecomputer/omicron", branch = "main"}
8687
internal-dns = { git = "https://github.com/oxidecomputer/omicron", branch = "main"}
8788
uuid = { version = "1.8", features = ["serde", "v4"] }

ddm-admin-client/Cargo.toml

+4-3
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ version = "0.1.0"
44
edition = "2021"
55

66
[dependencies]
7+
oxnet.workspace = true
8+
percent-encoding.workspace = true
9+
progenitor.workspace = true
10+
reqwest.workspace = true
711
serde.workspace = true
812
serde_json.workspace = true
913
slog.workspace = true
10-
percent-encoding.workspace = true
11-
reqwest.workspace = true
12-
progenitor.workspace = true
1314
uuid.workspace = true

ddm-admin-client/build.rs

-3
This file was deleted.

ddm-admin-client/src/lib.rs

+3-60
Original file line numberDiff line numberDiff line change
@@ -12,71 +12,14 @@ progenitor::generate_api!(
1212
"body" => ?&request.body(),
1313
);
1414
}),
15+
crates = {
16+
"oxnet" = "0.1.0",
17+
},
1518
post_hook = (|log: &slog::Logger, result: &Result<_, _>| {
1619
slog::trace!(log, "client response"; "result" => ?result);
1720
})
1821
);
1922

20-
impl Copy for types::Ipv4Prefix {}
21-
impl Copy for types::Ipv6Prefix {}
22-
impl Copy for types::IpPrefix {}
23-
24-
impl std::cmp::PartialEq for types::Ipv4Prefix {
25-
fn eq(&self, other: &Self) -> bool {
26-
self.addr.eq(&other.addr) && self.len.eq(&other.len)
27-
}
28-
}
29-
30-
impl std::cmp::Eq for types::Ipv4Prefix {}
31-
32-
impl std::hash::Hash for types::Ipv4Prefix {
33-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
34-
self.addr.hash(state);
35-
self.len.hash(state);
36-
}
37-
}
38-
39-
impl std::cmp::PartialEq for types::Ipv6Prefix {
40-
fn eq(&self, other: &Self) -> bool {
41-
self.addr.eq(&other.addr) && self.len.eq(&other.len)
42-
}
43-
}
44-
45-
impl std::cmp::Eq for types::Ipv6Prefix {}
46-
47-
impl std::hash::Hash for types::Ipv6Prefix {
48-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
49-
self.addr.hash(state);
50-
self.len.hash(state);
51-
}
52-
}
53-
54-
impl std::cmp::PartialEq for types::IpPrefix {
55-
fn eq(&self, other: &Self) -> bool {
56-
match self {
57-
types::IpPrefix::V4(x) => match other {
58-
types::IpPrefix::V4(y) => x.eq(y),
59-
_ => false,
60-
},
61-
types::IpPrefix::V6(x) => match other {
62-
types::IpPrefix::V6(y) => x.eq(y),
63-
_ => false,
64-
},
65-
}
66-
}
67-
}
68-
69-
impl std::hash::Hash for types::IpPrefix {
70-
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
71-
match self {
72-
types::IpPrefix::V4(x) => x.hash(state),
73-
types::IpPrefix::V6(x) => x.hash(state),
74-
}
75-
}
76-
}
77-
78-
impl std::cmp::Eq for types::IpPrefix {}
79-
8023
impl std::cmp::PartialEq for types::TunnelOrigin {
8124
fn eq(&self, other: &Self) -> bool {
8225
self.overlay_prefix.eq(&other.overlay_prefix)

ddm/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ chrono.workspace = true
3131
omicron-common.workspace = true
3232
oximeter.workspace = true
3333
oximeter-producer.workspace = true
34+
oxnet.workspace = true
3435
uuid.workspace = true

ddm/src/admin.rs

+5-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ use dropshot::HttpServerStarter;
1717
use dropshot::Path;
1818
use dropshot::RequestContext;
1919
use dropshot::TypedBody;
20-
use mg_common::net::{Ipv6Prefix, TunnelOrigin};
20+
use mg_common::net::TunnelOrigin;
21+
use oxnet::Ipv6Net;
2122
use schemars::JsonSchema;
2223
use serde::{Deserialize, Serialize};
2324
use slog::{error, info, warn, Logger};
@@ -125,7 +126,7 @@ type PrefixMap = BTreeMap<Ipv6Addr, HashSet<PathVector>>;
125126
#[endpoint { method = GET, path = "/originated" }]
126127
async fn get_originated(
127128
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
128-
) -> Result<HttpResponseOk<HashSet<Ipv6Prefix>>, HttpError> {
129+
) -> Result<HttpResponseOk<HashSet<Ipv6Net>>, HttpError> {
129130
let ctx = ctx.context().lock().unwrap();
130131
let originated = ctx
131132
.db
@@ -186,7 +187,7 @@ async fn get_tunnel_endpoints(
186187
#[endpoint { method = PUT, path = "/prefix" }]
187188
async fn advertise_prefixes(
188189
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
189-
request: TypedBody<HashSet<Ipv6Prefix>>,
190+
request: TypedBody<HashSet<Ipv6Net>>,
190191
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
191192
let ctx = ctx.context().lock().unwrap();
192193
let prefixes = request.into_inner();
@@ -258,7 +259,7 @@ async fn advertise_tunnel_endpoints(
258259
#[endpoint { method = DELETE, path = "/prefix" }]
259260
async fn withdraw_prefixes(
260261
ctx: RequestContext<Arc<Mutex<HandlerContext>>>,
261-
request: TypedBody<HashSet<Ipv6Prefix>>,
262+
request: TypedBody<HashSet<Ipv6Net>>,
262263
) -> Result<HttpResponseUpdatedNoContent, HttpError> {
263264
let ctx = ctx.context().lock().unwrap();
264265
let prefixes = request.into_inner();

ddm/src/db.rs

+23-43
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
// License, v. 2.0. If a copy of the MPL was not distributed with this
33
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
44

5-
use mg_common::net::{IpPrefix, Ipv6Prefix, TunnelOrigin};
5+
use mg_common::net::TunnelOrigin;
6+
use oxnet::{IpNet, Ipv6Net};
67
use schemars::{JsonSchema, JsonSchema_repr};
78
use serde::{Deserialize, Serialize};
89
use serde_repr::{Deserialize_repr, Serialize_repr};
@@ -105,10 +106,7 @@ impl Db {
105106
}
106107
}
107108

108-
pub fn originate(
109-
&self,
110-
prefixes: &HashSet<Ipv6Prefix>,
111-
) -> Result<(), Error> {
109+
pub fn originate(&self, prefixes: &HashSet<Ipv6Net>) -> Result<(), Error> {
112110
let tree = self.persistent_data.open_tree(ORIGINATE)?;
113111
for p in prefixes {
114112
tree.insert(p.db_key(), "")?;
@@ -130,7 +128,7 @@ impl Db {
130128
Ok(())
131129
}
132130

133-
pub fn originated(&self) -> Result<HashSet<Ipv6Prefix>, Error> {
131+
pub fn originated(&self) -> Result<HashSet<Ipv6Net>, Error> {
134132
let tree = self.persistent_data.open_tree(ORIGINATE)?;
135133
let result = tree
136134
.scan_prefix(vec![])
@@ -145,7 +143,7 @@ impl Db {
145143
return None;
146144
}
147145
};
148-
Some(match Ipv6Prefix::from_db_key(&key) {
146+
Some(match Ipv6Net::from_db_key(&key) {
149147
Ok(item) => item,
150148
Err(e) => {
151149
error!(
@@ -200,10 +198,7 @@ impl Db {
200198
Ok(self.originated_tunnel()?.len())
201199
}
202200

203-
pub fn withdraw(
204-
&self,
205-
prefixes: &HashSet<Ipv6Prefix>,
206-
) -> Result<(), Error> {
201+
pub fn withdraw(&self, prefixes: &HashSet<Ipv6Net>) -> Result<(), Error> {
207202
let tree = self.persistent_data.open_tree(ORIGINATE)?;
208203
for p in prefixes {
209204
tree.remove(p.db_key())?;
@@ -269,7 +264,7 @@ impl Db {
269264

270265
pub fn routes_by_vector(
271266
&self,
272-
dst: Ipv6Prefix,
267+
dst: Ipv6Net,
273268
nexthop: Ipv6Addr,
274269
) -> Vec<Route> {
275270
let data = self.data.lock().unwrap();
@@ -356,7 +351,7 @@ pub struct TunnelRoute {
356351
Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema,
357352
)]
358353
pub struct Route {
359-
pub destination: Ipv6Prefix,
354+
pub destination: Ipv6Net,
360355
pub nexthop: Ipv6Addr,
361356
pub ifname: String,
362357
pub path: Vec<String>,
@@ -390,7 +385,7 @@ impl EffectiveTunnelRouteSet {
390385
pub fn effective_route_set(
391386
full: &HashSet<TunnelRoute>,
392387
) -> HashSet<TunnelRoute> {
393-
let mut sets = HashMap::<IpPrefix, EffectiveTunnelRouteSet>::new();
388+
let mut sets = HashMap::<IpNet, EffectiveTunnelRouteSet>::new();
394389
for x in full.iter() {
395390
match sets.get_mut(&x.origin.overlay_prefix) {
396391
Some(set) => {
@@ -458,24 +453,25 @@ trait DbKey: Sized {
458453
fn from_db_key(v: &[u8]) -> Result<Self, Error>;
459454
}
460455

461-
impl DbKey for Ipv6Prefix {
456+
impl DbKey for Ipv6Net {
462457
fn db_key(&self) -> Vec<u8> {
463-
let mut buf: Vec<u8> = self.addr.octets().into();
464-
buf.push(self.len);
458+
let mut buf: Vec<u8> = self.addr().octets().into();
459+
buf.push(self.width());
465460
buf
466461
}
467462

468463
fn from_db_key(v: &[u8]) -> Result<Self, Error> {
469464
if v.len() < 17 {
470465
Err(Error::DbKey(format!(
471-
"buffer to short for prefix 6 key {} < 17",
466+
"buffer too short for prefix 6 key {} < 17",
472467
v.len()
473468
)))
474469
} else {
475-
Ok(Self {
476-
addr: Ipv6Addr::from(<[u8; 16]>::try_from(&v[..16]).unwrap()),
477-
len: v[16],
478-
})
470+
Self::new(
471+
Ipv6Addr::from(<[u8; 16]>::try_from(&v[..16]).unwrap()),
472+
v[16],
473+
)
474+
.map_err(|e| Error::DbKey(e.to_string()))
479475
}
480476
}
481477
}
@@ -494,7 +490,6 @@ impl From<crate::db::TunnelRoute> for TunnelOrigin {
494490
#[cfg(test)]
495491
mod test {
496492
use super::*;
497-
use mg_common::net::{IpPrefix, Ipv4Prefix};
498493
use pretty_assertions::assert_eq;
499494
use std::collections::HashSet;
500495

@@ -503,10 +498,7 @@ mod test {
503498
let mut before = HashSet::<TunnelRoute>::new();
504499
before.insert(TunnelRoute {
505500
origin: TunnelOrigin {
506-
overlay_prefix: IpPrefix::V4(Ipv4Prefix {
507-
addr: "0.0.0.0".parse().unwrap(),
508-
len: 0,
509-
}),
501+
overlay_prefix: "0.0.0.0/0".parse().unwrap(),
510502
boundary_addr: "fd00:a::1".parse().unwrap(),
511503
vni: 99,
512504
metric: 0,
@@ -515,10 +507,7 @@ mod test {
515507
});
516508
before.insert(TunnelRoute {
517509
origin: TunnelOrigin {
518-
overlay_prefix: IpPrefix::V4(Ipv4Prefix {
519-
addr: "0.0.0.0".parse().unwrap(),
520-
len: 0,
521-
}),
510+
overlay_prefix: "0.0.0.0/0".parse().unwrap(),
522511
boundary_addr: "fd00:b::1".parse().unwrap(),
523512
vni: 99,
524513
metric: 0,
@@ -530,10 +519,7 @@ mod test {
530519
let mut after = HashSet::<TunnelRoute>::new();
531520
after.insert(TunnelRoute {
532521
origin: TunnelOrigin {
533-
overlay_prefix: IpPrefix::V4(Ipv4Prefix {
534-
addr: "0.0.0.0".parse().unwrap(),
535-
len: 0,
536-
}),
522+
overlay_prefix: "0.0.0.0/0".parse().unwrap(),
537523
boundary_addr: "fd00:a::1".parse().unwrap(),
538524
vni: 99,
539525
metric: 0,
@@ -542,10 +528,7 @@ mod test {
542528
});
543529
after.insert(TunnelRoute {
544530
origin: TunnelOrigin {
545-
overlay_prefix: IpPrefix::V4(Ipv4Prefix {
546-
addr: "0.0.0.0".parse().unwrap(),
547-
len: 0,
548-
}),
531+
overlay_prefix: "0.0.0.0/0".parse().unwrap(),
549532
boundary_addr: "fd00:b::1".parse().unwrap(),
550533
vni: 99,
551534
metric: 100,
@@ -570,10 +553,7 @@ mod test {
570553
let mut expected_del = HashSet::<TunnelRoute>::new();
571554
expected_del.insert(TunnelRoute {
572555
origin: TunnelOrigin {
573-
overlay_prefix: IpPrefix::V4(Ipv4Prefix {
574-
addr: "0.0.0.0".parse().unwrap(),
575-
len: 0,
576-
}),
556+
overlay_prefix: "0.0.0.0/0".parse().unwrap(),
577557
boundary_addr: "fd00:a::1".parse().unwrap(),
578558
vni: 99,
579559
metric: 0,

0 commit comments

Comments
 (0)