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- // Copyright 2025 Oxide Computer Company
5+ // Copyright 2026 Oxide Computer Company
66
77use slog:: { error, trace} ;
88use softnpu_lib:: { ManagementRequest , TableAdd , TableRemove } ;
@@ -31,6 +31,8 @@ const LOCAL_V6: &str = "ingress.local.local_v6";
3131const LOCAL_V4 : & str = "ingress.local.local_v4" ;
3232const NAT_V4 : & str = "ingress.nat.nat_v4" ;
3333const NAT_V6 : & str = "ingress.nat.nat_v6" ;
34+ const ATTACHED_SUBNET_V4 : & str = "ingress.attached.attached_subnet_v4" ;
35+ const ATTACHED_SUBNET_V6 : & str = "ingress.attached.attached_subnet_v6" ;
3436const _NAT_ICMP_V6: & str = "ingress.nat.nat_icmp_v6" ;
3537const _NAT_ICMP_V4: & str = "ingress.nat.nat_icmp_v4" ;
3638const RESOLVER_V4 : & str = "ingress.resolver.resolver_v4" ;
@@ -54,12 +56,16 @@ const ARP: &str = "pipe.Ingress.l3_router.Router4.Arp.tbl";
5456const DPD_MAC_REWRITE : & str = "pipe.Ingress.mac_rewrite.mac_rewrite" ;
5557const NAT_INGRESS4 : & str = "pipe.Ingress.nat_ingress.ingress_ipv4" ;
5658const NAT_INGRESS6 : & str = "pipe.Ingress.nat_ingress.ingress_ipv6" ;
59+ const ATTACHED_SUBNET_INGRESS4 : & str =
60+ "pipe.Ingress.attached_subnet_ingress.attached_subnets_v4" ;
61+ const ATTACHED_SUBNET_INGRESS6 : & str =
62+ "pipe.Ingress.attached_subnet_ingress.attached_subnets_v6" ;
5763
5864// All tables are defined to be 1024 entries deep
5965const TABLE_SIZE : usize = 4096 ;
6066
6167impl TableOps < Handle > for Table {
62- fn new ( _hdl : & Handle , name : & str ) -> AsicResult < Table > {
68+ fn new ( hdl : & Handle , name : & str ) -> AsicResult < Table > {
6369 // TODO just mapping sidecar.p4 things onto simplified sidecar-lite.p4
6470 // things to get started.
6571 let ( id, dpd_id) = match name {
@@ -84,8 +90,16 @@ impl TableOps<Handle> for Table {
8490 }
8591 NAT_INGRESS4 => ( Some ( NAT_V4 . into ( ) ) , Some ( NAT_INGRESS4 . into ( ) ) ) ,
8692 NAT_INGRESS6 => ( Some ( NAT_V6 . into ( ) ) , Some ( NAT_INGRESS6 . into ( ) ) ) ,
93+ ATTACHED_SUBNET_INGRESS4 => (
94+ Some ( ATTACHED_SUBNET_V4 . into ( ) ) ,
95+ Some ( ATTACHED_SUBNET_INGRESS4 . into ( ) ) ,
96+ ) ,
97+ ATTACHED_SUBNET_INGRESS6 => (
98+ Some ( ATTACHED_SUBNET_V6 . into ( ) ) ,
99+ Some ( ATTACHED_SUBNET_INGRESS6 . into ( ) ) ,
100+ ) ,
87101 x => {
88- println ! ( "TABLE NOT HANDLED {x}" ) ;
102+ error ! ( hdl . log , "TABLE NOT HANDLED {x}" ) ;
89103 ( None , None )
90104 }
91105 } ;
@@ -382,7 +396,9 @@ impl TableOps<Handle> for Table {
382396 ( "rewrite" , params)
383397 }
384398 ( NAT_INGRESS4 , "forward_ipv4_to" )
385- | ( NAT_INGRESS6 , "forward_ipv6_to" ) => {
399+ | ( NAT_INGRESS6 , "forward_ipv6_to" )
400+ | ( ATTACHED_SUBNET_INGRESS4 , "forward_to_v4" )
401+ | ( ATTACHED_SUBNET_INGRESS6 , "forward_to_v6" ) => {
386402 let mut target = Vec :: new ( ) ;
387403 let mut vni = Vec :: new ( ) ;
388404 let mut mac = Vec :: new ( ) ;
@@ -463,7 +479,7 @@ impl TableOps<Handle> for Table {
463479 ( "forward_to_sled" , params)
464480 }
465481 ( tbl, x) => {
466- println ! ( "ACTION NOT HANDLED {tbl} {x}" ) ;
482+ error ! ( hdl . log , "ACTION NOT HANDLED {tbl} {x}" ) ;
467483 return Ok ( ( ) ) ;
468484 }
469485 } ;
@@ -610,7 +626,7 @@ fn keyset_data(match_data: Vec<MatchEntryField>, table: &str) -> Vec<u8> {
610626 MatchEntryValue :: Lpm ( x) => {
611627 let mut data: Vec < u8 > = Vec :: new ( ) ;
612628 match table {
613- ROUTER_V4_IDX => {
629+ ROUTER_V4_IDX | ATTACHED_SUBNET_V4 => {
614630 // prefix for longest prefix match operation
615631 // "dst_addr" => hdr.ipv4.dst: lpm => bit<32>
616632 serialize_value_type_be ( & x. prefix , & mut data) ;
0 commit comments