Skip to content

Commit 499dfdb

Browse files
authored
Add support for external subnets (#129)
1 parent b58da5d commit 499dfdb

4 files changed

Lines changed: 104 additions & 23 deletions

File tree

Cargo.lock

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

p4/sidecar-lite.p4

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ control ingress(
1616
inout ingress_metadata_t ingress,
1717
inout egress_metadata_t egress,
1818
) {
19+
attached() attached;
1920
local() local;
2021
router() router;
2122
nat_ingress() nat;
@@ -53,6 +54,7 @@ control ingress(
5354
// rack and should be sent to the scrimlet.
5455
else { fwd_to_scrimlet(); return; }
5556
} else {
57+
attached.apply(ingress, hdr);
5658
nat.apply(hdr, ingress, egress); // check for ingress nat
5759
}
5860

@@ -158,18 +160,28 @@ control nat_ingress(
158160
}
159161

160162
apply {
161-
if (hdr.ipv4.isValid()) { nat_v4.apply(); }
162-
if (hdr.ipv6.isValid()) { nat_v6.apply(); }
163+
if (ingress.forward_needed == false) {
164+
if (hdr.ipv4.isValid()) { nat_v4.apply(); }
165+
if (hdr.ipv6.isValid()) { nat_v6.apply(); }
166+
}
167+
if (ingress.forward_needed == true) {
168+
forward_packet();
169+
}
163170
}
164171

165172
action forward_to_sled(bit<128> target, bit<24> vni, bit<48> mac) {
166-
ingress.nat = true;
173+
ingress.forward_tgt = target;
174+
ingress.forward_vni = vni;
175+
ingress.forward_mac = mac;
176+
ingress.forward_needed = true;
177+
}
167178

179+
action forward_packet() {
168180
bit<16> orig_l3_len = 0;
169181
bit<16> orig_l3_csum = 0;
170182

171183
hdr.inner_eth = hdr.ethernet;
172-
hdr.inner_eth.dst = mac;
184+
hdr.inner_eth.dst = ingress.forward_mac;
173185
hdr.inner_eth.setValid();
174186
if (hdr.vlan.isValid()) {
175187
hdr.inner_eth.ether_type = hdr.vlan.ether_type;
@@ -218,7 +230,7 @@ control nat_ingress(
218230
hdr.ipv6.hop_limit = 8w255;
219231
// XXX hardcoded boundary services addr
220232
hdr.ipv6.src = 128w0xfd000099000000000000000000000001;
221-
hdr.ipv6.dst = target;
233+
hdr.ipv6.dst = ingress.forward_tgt;
222234
hdr.ipv6.setValid();
223235

224236
// set up outer udp
@@ -235,7 +247,7 @@ control nat_ingress(
235247
hdr.geneve.crit = 1w0;
236248
hdr.geneve.reserved = 6w0;
237249
hdr.geneve.protocol = 16w0x6558;
238-
hdr.geneve.vni = vni;
250+
hdr.geneve.vni = ingress.forward_vni;
239251
hdr.geneve.reserved2 = 8w0;
240252
hdr.geneve.setValid();
241253

@@ -266,7 +278,6 @@ control nat_ingress(
266278
});
267279
hdr.udp.checksum = 16w0;
268280
}
269-
270281
}
271282

272283
control local(
@@ -300,6 +311,42 @@ control local(
300311
action local() { is_local = true; }
301312
}
302313

314+
control attached(
315+
inout ingress_metadata_t ingress,
316+
inout headers_t hdr,
317+
) {
318+
table attached_subnet_v4 {
319+
key = {
320+
hdr.ipv4.dst: lpm;
321+
}
322+
actions = { forward_to_sled; }
323+
default_action = NoAction;
324+
}
325+
326+
table attached_subnet_v6 {
327+
key = {
328+
hdr.ipv6.dst: lpm;
329+
}
330+
actions = { forward_to_sled; }
331+
default_action = NoAction;
332+
}
333+
334+
apply {
335+
if (hdr.ipv4.isValid()) {
336+
attached_subnet_v4.apply();
337+
} else if (hdr.ipv6.isValid()) {
338+
attached_subnet_v6.apply();
339+
}
340+
}
341+
342+
action forward_to_sled(bit<128> target, bit<24> vni, bit<48> mac) {
343+
ingress.forward_tgt = target;
344+
ingress.forward_vni = vni;
345+
ingress.forward_mac = mac;
346+
ingress.forward_needed = true;
347+
}
348+
}
349+
303350
control resolver(
304351
inout headers_t hdr,
305352
inout egress_metadata_t egress,

p4/softnpu.p4

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,13 @@
33
#include <headers.p4>
44

55
struct ingress_metadata_t {
6+
bit<128> forward_tgt;
7+
bit<24> forward_vni;
8+
bit<48> forward_mac;
69
bit<16> port;
710
bit<16> nat_id;
811
bit<16> path_idx;
9-
bool nat;
12+
bool forward_needed;
1013
bool lldp;
1114

1215
// Used as mutable scratchpad shared between parser states.

scadm/src/main.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,8 @@ const LOCAL_V6: &str = "ingress.local.local_v6";
213213
const LOCAL_V4: &str = "ingress.local.local_v4";
214214
const NAT_V4: &str = "ingress.nat.nat_v4";
215215
const NAT_V6: &str = "ingress.nat.nat_v6";
216+
const ATTACHED_SUBNET_V4: &str = "ingress.attached.attached_subnet_v4";
217+
const ATTACHED_SUBNET_V6: &str = "ingress.attached.attached_subnet_v6";
216218
const RESOLVER_V4: &str = "ingress.resolver.resolver_v4";
217219
const RESOLVER_V6: &str = "ingress.resolver.resolver_v6";
218220
const MAC_REWRITE: &str = "ingress.mac.mac_rewrite";
@@ -1005,7 +1007,36 @@ fn dump_tables(table: &BTreeMap<String, Vec<TableEntry>>) {
10051007
};
10061008
println!("{dst_nat_id} -> {target}");
10071009
}
1008-
1010+
println!("attached subnet v4:");
1011+
for e in table.get(ATTACHED_SUBNET_V4).unwrap() {
1012+
let subnet = match get_addr_subnet(&e.keyset_data) {
1013+
Some((a, m)) => format!("{a}/{m}"),
1014+
_ => continue,
1015+
};
1016+
let target = match get_addr_vni_mac(&e.parameter_data) {
1017+
Some((addr, vni, m)) => format!(
1018+
"{} {}/{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
1019+
addr, vni, m[5], m[4], m[3], m[2], m[1], m[0],
1020+
),
1021+
None => "?".into(),
1022+
};
1023+
println!("{subnet} -> {target}");
1024+
}
1025+
println!("attached subnet v6:");
1026+
for e in table.get(ATTACHED_SUBNET_V6).unwrap() {
1027+
let subnet = match get_addr_subnet(&e.keyset_data) {
1028+
Some((a, m)) => format!("{a}/{m}"),
1029+
_ => continue,
1030+
};
1031+
let target = match get_addr_vni_mac(&e.parameter_data) {
1032+
Some((addr, vni, m)) => format!(
1033+
"{} {}/{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}",
1034+
addr, vni, m[5], m[4], m[3], m[2], m[1], m[0],
1035+
),
1036+
None => "?".into(),
1037+
};
1038+
println!("{subnet} -> {target}");
1039+
}
10091040
println!("port_mac:");
10101041
for e in table.get(MAC_REWRITE).unwrap() {
10111042
let port = u16::from_le_bytes([e.keyset_data[0], e.keyset_data[1]]);

0 commit comments

Comments
 (0)