@@ -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 = 8 w255 ;
219231 // XXX hardcoded boundary services addr
220232 hdr .ipv6 .src = 128 w0xfd000099000000000000000000000001 ;
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 = 1 w0 ;
236248 hdr .geneve .reserved = 6 w0 ;
237249 hdr .geneve .protocol = 16 w0x6558 ;
238- hdr .geneve .vni = vni ;
250+ hdr .geneve .vni = ingress . forward_vni ;
239251 hdr .geneve .reserved2 = 8 w0 ;
240252 hdr .geneve .setValid ();
241253
@@ -266,7 +278,6 @@ control nat_ingress(
266278 });
267279 hdr .udp .checksum = 16 w0 ;
268280 }
269-
270281}
271282
272283control 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+
303350control resolver (
304351 inout headers_t hdr ,
305352 inout egress_metadata_t egress ,
0 commit comments