diff --git a/examples/pipeline/examples/vxlan.spec b/examples/pipeline/examples/vxlan.spec index 347dca29d..ac62ab2be 100644 --- a/examples/pipeline/examples/vxlan.spec +++ b/examples/pipeline/examples/vxlan.spec @@ -60,7 +60,7 @@ metadata instanceof metadata_t struct vxlan_encap_args_t { bit<48> ethernet_dst_addr bit<48> ethernet_src_addr - bit<16> ethernet_ether_type + bit<16> ethernet_ethertype bit<8> ipv4_ver_ihl bit<8> ipv4_diffserv bit<16> ipv4_total_len @@ -114,11 +114,40 @@ struct vxlan_encap_args_t { // action vxlan_encap args instanceof vxlan_encap_args_t { - //Copy from table entry to headers and metadata. - dma h.outer_ethernet t.ethernet_dst_addr - dma h.outer_ipv4 t.ipv4_ver_ihl - dma h.outer_udp t.udp_src_port - dma h.outer_vxlan t.vxlan_flags + //Set the outer Ethernet header. + mov h.outer_ethernet.dst_addr t.ethernet_dst_addr + mov h.outer_ethernet.src_addr t.ethernet_src_addr + mov h.outer_ethernet.ethertype t.ethernet_ethertype + validate h.outer_ethernet + + //Set the outer IPv4 header. + mov h.outer_ipv4.ver_ihl t.ipv4_ver_ihl + mov h.outer_ipv4.diffserv t.ipv4_diffserv + mov h.outer_ipv4.total_len t.ipv4_total_len + mov h.outer_ipv4.identification t.ipv4_identification + mov h.outer_ipv4.flags_offset t.ipv4_flags_offset + mov h.outer_ipv4.ttl t.ipv4_ttl + mov h.outer_ipv4.protocol t.ipv4_protocol + mov h.outer_ipv4.hdr_checksum t.ipv4_hdr_checksum + mov h.outer_ipv4.src_addr t.ipv4_src_addr + mov h.outer_ipv4.dst_addr t.ipv4_dst_addr + validate h.outer_ipv4 + + //Set the outer UDP header. + mov h.outer_udp.src_port t.udp_src_port + mov h.outer_udp.dst_port t.udp_dst_port + mov h.outer_udp.length t.udp_length + mov h.outer_udp.checksum t.udp_checksum + validate h.outer_udp + + //Set the outer VXLAN header. + mov h.outer_vxlan.flags t.vxlan_flags + mov h.outer_vxlan.reserved t.vxlan_reserved + mov h.outer_vxlan.vni t.vxlan_vni + mov h.outer_vxlan.reserved2 t.vxlan_reserved2 + validate h.outer_vxlan + + //Set the output port. mov m.port_out t.port_out //Update h.outer_ipv4.total_len field. diff --git a/examples/pipeline/examples/vxlan_table.py b/examples/pipeline/examples/vxlan_table.py index 820c208c7..b1c6f1acd 100755 --- a/examples/pipeline/examples/vxlan_table.py +++ b/examples/pipeline/examples/vxlan_table.py @@ -13,28 +13,28 @@ KEY = '0xaabbccdd{0:04x}' ACTION = 'vxlan_encap' -ETHERNET_HEADER = 'ethernet_dst_addr N(0xa0a1a2a3{0:04x}) ' \ - 'ethernet_src_addr N(0xb0b1b2b3{0:04x}) ' \ - 'ethernet_ether_type N(0x0800)' -IPV4_HEADER = 'ipv4_ver_ihl N(0x45) ' \ - 'ipv4_diffserv N(0) ' \ - 'ipv4_total_len N(50) ' \ - 'ipv4_identification N(0) ' \ - 'ipv4_flags_offset N(0) ' \ - 'ipv4_ttl N(64) ' \ - 'ipv4_protocol N(17) ' \ - 'ipv4_hdr_checksum N(0x{1:04x}) ' \ - 'ipv4_src_addr N(0xc0c1{0:04x}) ' \ - 'ipv4_dst_addr N(0xd0d1{0:04x})' -UDP_HEADER = 'udp_src_port N(0xe0{0:02x}) ' \ - 'udp_dst_port N(4789) ' \ - 'udp_length N(30) ' \ - 'udp_checksum N(0)' -VXLAN_HEADER = 'vxlan_flags N(0) ' \ - 'vxlan_reserved N(0) ' \ - 'vxlan_vni N({0:d}) ' \ - 'vxlan_reserved2 N(0)' -PORT_OUT = 'port_out H({0:d})' +ETHERNET_HEADER = 'ethernet_dst_addr 0xa0a1a2a3{0:04x} ' \ + 'ethernet_src_addr 0xb0b1b2b3{0:04x} ' \ + 'ethernet_ethertype 0x0800' +IPV4_HEADER = 'ipv4_ver_ihl 0x45 ' \ + 'ipv4_diffserv 0 ' \ + 'ipv4_total_len 50 ' \ + 'ipv4_identification 0 ' \ + 'ipv4_flags_offset 0 ' \ + 'ipv4_ttl 64 ' \ + 'ipv4_protocol 17 ' \ + 'ipv4_hdr_checksum 0x{1:04x} ' \ + 'ipv4_src_addr 0xc0c1{0:04x} ' \ + 'ipv4_dst_addr 0xd0d1{0:04x}' +UDP_HEADER = 'udp_src_port 0xe0{0:02x} ' \ + 'udp_dst_port 4789 ' \ + 'udp_length 30 ' \ + 'udp_checksum 0' +VXLAN_HEADER = 'vxlan_flags 0 ' \ + 'vxlan_reserved 0 ' \ + 'vxlan_vni {0:d} ' \ + 'vxlan_reserved2 0' +PORT_OUT = 'port_out {0:d}' def ipv4_header_checksum(i): cksum = (0x4500 + 0x0032) + (0x0000 + 0x0000) + (0x4011 + 0x0000) + (0xc0c1 + i) + (0xd0d1 + i) diff --git a/examples/pipeline/examples/vxlan_table.txt b/examples/pipeline/examples/vxlan_table.txt index acac80a38..25ca647ab 100644 --- a/examples/pipeline/examples/vxlan_table.txt +++ b/examples/pipeline/examples/vxlan_table.txt @@ -1,16 +1,16 @@ -match 0xaabbccdd0000 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30000) ethernet_src_addr N(0xb0b1b2b30000) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe928) ipv4_src_addr N(0xc0c10000) ipv4_dst_addr N(0xd0d10000) udp_src_port N(0xe000) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(0) vxlan_reserved2 N(0) port_out H(0) -match 0xaabbccdd0001 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30001) ethernet_src_addr N(0xb0b1b2b30001) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe926) ipv4_src_addr N(0xc0c10001) ipv4_dst_addr N(0xd0d10001) udp_src_port N(0xe001) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(1) vxlan_reserved2 N(0) port_out H(1) -match 0xaabbccdd0002 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30002) ethernet_src_addr N(0xb0b1b2b30002) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe924) ipv4_src_addr N(0xc0c10002) ipv4_dst_addr N(0xd0d10002) udp_src_port N(0xe002) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(2) vxlan_reserved2 N(0) port_out H(2) -match 0xaabbccdd0003 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30003) ethernet_src_addr N(0xb0b1b2b30003) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe922) ipv4_src_addr N(0xc0c10003) ipv4_dst_addr N(0xd0d10003) udp_src_port N(0xe003) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(3) vxlan_reserved2 N(0) port_out H(3) -match 0xaabbccdd0004 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30004) ethernet_src_addr N(0xb0b1b2b30004) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe920) ipv4_src_addr N(0xc0c10004) ipv4_dst_addr N(0xd0d10004) udp_src_port N(0xe004) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(4) vxlan_reserved2 N(0) port_out H(0) -match 0xaabbccdd0005 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30005) ethernet_src_addr N(0xb0b1b2b30005) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe91e) ipv4_src_addr N(0xc0c10005) ipv4_dst_addr N(0xd0d10005) udp_src_port N(0xe005) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(5) vxlan_reserved2 N(0) port_out H(1) -match 0xaabbccdd0006 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30006) ethernet_src_addr N(0xb0b1b2b30006) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe91c) ipv4_src_addr N(0xc0c10006) ipv4_dst_addr N(0xd0d10006) udp_src_port N(0xe006) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(6) vxlan_reserved2 N(0) port_out H(2) -match 0xaabbccdd0007 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30007) ethernet_src_addr N(0xb0b1b2b30007) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe91a) ipv4_src_addr N(0xc0c10007) ipv4_dst_addr N(0xd0d10007) udp_src_port N(0xe007) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(7) vxlan_reserved2 N(0) port_out H(3) -match 0xaabbccdd0008 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30008) ethernet_src_addr N(0xb0b1b2b30008) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe918) ipv4_src_addr N(0xc0c10008) ipv4_dst_addr N(0xd0d10008) udp_src_port N(0xe008) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(8) vxlan_reserved2 N(0) port_out H(0) -match 0xaabbccdd0009 action vxlan_encap ethernet_dst_addr N(0xa0a1a2a30009) ethernet_src_addr N(0xb0b1b2b30009) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe916) ipv4_src_addr N(0xc0c10009) ipv4_dst_addr N(0xd0d10009) udp_src_port N(0xe009) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(9) vxlan_reserved2 N(0) port_out H(1) -match 0xaabbccdd000a action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000a) ethernet_src_addr N(0xb0b1b2b3000a) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe914) ipv4_src_addr N(0xc0c1000a) ipv4_dst_addr N(0xd0d1000a) udp_src_port N(0xe00a) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(10) vxlan_reserved2 N(0) port_out H(2) -match 0xaabbccdd000b action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000b) ethernet_src_addr N(0xb0b1b2b3000b) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe912) ipv4_src_addr N(0xc0c1000b) ipv4_dst_addr N(0xd0d1000b) udp_src_port N(0xe00b) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(11) vxlan_reserved2 N(0) port_out H(3) -match 0xaabbccdd000c action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000c) ethernet_src_addr N(0xb0b1b2b3000c) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe910) ipv4_src_addr N(0xc0c1000c) ipv4_dst_addr N(0xd0d1000c) udp_src_port N(0xe00c) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(12) vxlan_reserved2 N(0) port_out H(0) -match 0xaabbccdd000d action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000d) ethernet_src_addr N(0xb0b1b2b3000d) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe90e) ipv4_src_addr N(0xc0c1000d) ipv4_dst_addr N(0xd0d1000d) udp_src_port N(0xe00d) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(13) vxlan_reserved2 N(0) port_out H(1) -match 0xaabbccdd000e action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000e) ethernet_src_addr N(0xb0b1b2b3000e) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe90c) ipv4_src_addr N(0xc0c1000e) ipv4_dst_addr N(0xd0d1000e) udp_src_port N(0xe00e) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(14) vxlan_reserved2 N(0) port_out H(2) -match 0xaabbccdd000f action vxlan_encap ethernet_dst_addr N(0xa0a1a2a3000f) ethernet_src_addr N(0xb0b1b2b3000f) ethernet_ether_type N(0x0800) ipv4_ver_ihl N(0x45) ipv4_diffserv N(0) ipv4_total_len N(50) ipv4_identification N(0) ipv4_flags_offset N(0) ipv4_ttl N(64) ipv4_protocol N(17) ipv4_hdr_checksum N(0xe90a) ipv4_src_addr N(0xc0c1000f) ipv4_dst_addr N(0xd0d1000f) udp_src_port N(0xe00f) udp_dst_port N(4789) udp_length N(30) udp_checksum N(0) vxlan_flags N(0) vxlan_reserved N(0) vxlan_vni N(15) vxlan_reserved2 N(0) port_out H(3) +match 0xaabbccdd0000 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30000 ethernet_src_addr 0xb0b1b2b30000 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe928 ipv4_src_addr 0xc0c10000 ipv4_dst_addr 0xd0d10000 udp_src_port 0xe000 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 0 vxlan_reserved2 0 port_out 0 +match 0xaabbccdd0001 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30001 ethernet_src_addr 0xb0b1b2b30001 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe926 ipv4_src_addr 0xc0c10001 ipv4_dst_addr 0xd0d10001 udp_src_port 0xe001 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 1 vxlan_reserved2 0 port_out 1 +match 0xaabbccdd0002 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30002 ethernet_src_addr 0xb0b1b2b30002 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe924 ipv4_src_addr 0xc0c10002 ipv4_dst_addr 0xd0d10002 udp_src_port 0xe002 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 2 vxlan_reserved2 0 port_out 2 +match 0xaabbccdd0003 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30003 ethernet_src_addr 0xb0b1b2b30003 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe922 ipv4_src_addr 0xc0c10003 ipv4_dst_addr 0xd0d10003 udp_src_port 0xe003 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 3 vxlan_reserved2 0 port_out 3 +match 0xaabbccdd0004 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30004 ethernet_src_addr 0xb0b1b2b30004 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe920 ipv4_src_addr 0xc0c10004 ipv4_dst_addr 0xd0d10004 udp_src_port 0xe004 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 4 vxlan_reserved2 0 port_out 0 +match 0xaabbccdd0005 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30005 ethernet_src_addr 0xb0b1b2b30005 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe91e ipv4_src_addr 0xc0c10005 ipv4_dst_addr 0xd0d10005 udp_src_port 0xe005 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 5 vxlan_reserved2 0 port_out 1 +match 0xaabbccdd0006 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30006 ethernet_src_addr 0xb0b1b2b30006 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe91c ipv4_src_addr 0xc0c10006 ipv4_dst_addr 0xd0d10006 udp_src_port 0xe006 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 6 vxlan_reserved2 0 port_out 2 +match 0xaabbccdd0007 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30007 ethernet_src_addr 0xb0b1b2b30007 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe91a ipv4_src_addr 0xc0c10007 ipv4_dst_addr 0xd0d10007 udp_src_port 0xe007 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 7 vxlan_reserved2 0 port_out 3 +match 0xaabbccdd0008 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30008 ethernet_src_addr 0xb0b1b2b30008 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe918 ipv4_src_addr 0xc0c10008 ipv4_dst_addr 0xd0d10008 udp_src_port 0xe008 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 8 vxlan_reserved2 0 port_out 0 +match 0xaabbccdd0009 action vxlan_encap ethernet_dst_addr 0xa0a1a2a30009 ethernet_src_addr 0xb0b1b2b30009 ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe916 ipv4_src_addr 0xc0c10009 ipv4_dst_addr 0xd0d10009 udp_src_port 0xe009 udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 9 vxlan_reserved2 0 port_out 1 +match 0xaabbccdd000a action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000a ethernet_src_addr 0xb0b1b2b3000a ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe914 ipv4_src_addr 0xc0c1000a ipv4_dst_addr 0xd0d1000a udp_src_port 0xe00a udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 10 vxlan_reserved2 0 port_out 2 +match 0xaabbccdd000b action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000b ethernet_src_addr 0xb0b1b2b3000b ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe912 ipv4_src_addr 0xc0c1000b ipv4_dst_addr 0xd0d1000b udp_src_port 0xe00b udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 11 vxlan_reserved2 0 port_out 3 +match 0xaabbccdd000c action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000c ethernet_src_addr 0xb0b1b2b3000c ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe910 ipv4_src_addr 0xc0c1000c ipv4_dst_addr 0xd0d1000c udp_src_port 0xe00c udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 12 vxlan_reserved2 0 port_out 0 +match 0xaabbccdd000d action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000d ethernet_src_addr 0xb0b1b2b3000d ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe90e ipv4_src_addr 0xc0c1000d ipv4_dst_addr 0xd0d1000d udp_src_port 0xe00d udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 13 vxlan_reserved2 0 port_out 1 +match 0xaabbccdd000e action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000e ethernet_src_addr 0xb0b1b2b3000e ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe90c ipv4_src_addr 0xc0c1000e ipv4_dst_addr 0xd0d1000e udp_src_port 0xe00e udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 14 vxlan_reserved2 0 port_out 2 +match 0xaabbccdd000f action vxlan_encap ethernet_dst_addr 0xa0a1a2a3000f ethernet_src_addr 0xb0b1b2b3000f ethernet_ethertype 0x0800 ipv4_ver_ihl 0x45 ipv4_diffserv 0 ipv4_total_len 50 ipv4_identification 0 ipv4_flags_offset 0 ipv4_ttl 64 ipv4_protocol 17 ipv4_hdr_checksum 0xe90a ipv4_src_addr 0xc0c1000f ipv4_dst_addr 0xd0d1000f udp_src_port 0xe00f udp_dst_port 4789 udp_length 30 udp_checksum 0 vxlan_flags 0 vxlan_reserved 0 vxlan_vni 15 vxlan_reserved2 0 port_out 3 diff --git a/lib/librte_pipeline/rte_swx_ctl.c b/lib/librte_pipeline/rte_swx_ctl.c index ca30767ef..4d1ff9ead 100644 --- a/lib/librte_pipeline/rte_swx_ctl.c +++ b/lib/librte_pipeline/rte_swx_ctl.c @@ -1721,30 +1721,19 @@ rte_swx_ctl_pipeline_table_entry_read(struct rte_swx_ctl_pipeline *ctl, struct rte_swx_ctl_action_arg_info *arg = &action->args[i]; char *arg_name, *arg_val; uint64_t val; - int is_nbo = 0; arg_name = tokens[2 + i * 2]; arg_val = tokens[2 + i * 2 + 1]; - if (strcmp(arg_name, arg->name) || - (strlen(arg_val) < 4) || - ((arg_val[0] != 'H') && (arg_val[0] != 'N')) || - (arg_val[1] != '(') || - (arg_val[strlen(arg_val) - 1] != ')')) + if (strcmp(arg_name, arg->name)) goto error; - if (arg_val[0] == 'N') - is_nbo = 1; - - arg_val[strlen(arg_val) - 1] = 0; /* Remove the ')'. */ - arg_val += 2; /* Remove the "H(" or "N(". */ - val = strtoull(arg_val, &arg_val, 0); if (arg_val[0]) goto error; /* Endianness conversion. */ - if (is_nbo) + if (arg->is_network_byte_order) val = field_hton(val, arg->n_bits); /* Copy to entry. */ diff --git a/lib/librte_pipeline/rte_swx_ctl.h b/lib/librte_pipeline/rte_swx_ctl.h index b8f22c516..4e5befb50 100644 --- a/lib/librte_pipeline/rte_swx_ctl.h +++ b/lib/librte_pipeline/rte_swx_ctl.h @@ -168,6 +168,12 @@ struct rte_swx_ctl_action_arg_info { /** Action argument size (in bits). */ uint32_t n_bits; + + /** Non-zero (true) when this action argument must be stored in the + * table in network byte order (NBO), zero when it must be stored in + * host byte order (HBO). + */ + int is_network_byte_order; }; /** diff --git a/lib/librte_pipeline/rte_swx_pipeline.c b/lib/librte_pipeline/rte_swx_pipeline.c index ba828cbda..d9f47b07e 100644 --- a/lib/librte_pipeline/rte_swx_pipeline.c +++ b/lib/librte_pipeline/rte_swx_pipeline.c @@ -733,6 +733,7 @@ struct action { TAILQ_ENTRY(action) node; char name[RTE_SWX_NAME_SIZE]; struct struct_type *st; + int *args_endianness; /* 0 = Host Byte Order (HBO). */ struct instruction *instructions; uint32_t n_instructions; uint32_t id; @@ -2342,6 +2343,18 @@ header_find(struct rte_swx_pipeline *p, const char *name) return NULL; } +static struct header * +header_find_by_struct_id(struct rte_swx_pipeline *p, uint32_t struct_id) +{ + struct header *elem; + + TAILQ_FOREACH(elem, &p->headers, node) + if (elem->struct_id == struct_id) + return elem; + + return NULL; +} + static struct header * header_parse(struct rte_swx_pipeline *p, const char *name) @@ -3722,37 +3735,6 @@ instr_mov_i_exec(struct rte_swx_pipeline *p) /* * dma. */ -static int -instr_dma_translate(struct rte_swx_pipeline *p, - struct action *action, - char **tokens, - int n_tokens, - struct instruction *instr, - struct instruction_data *data __rte_unused) -{ - char *dst = tokens[1]; - char *src = tokens[2]; - struct header *h; - struct field *tf; - - CHECK(action, EINVAL); - CHECK(n_tokens == 3, EINVAL); - - h = header_parse(p, dst); - CHECK(h, EINVAL); - - tf = action_field_parse(action, src); - CHECK(tf, EINVAL); - - instr->type = INSTR_DMA_HT; - instr->dma.dst.header_id[0] = h->id; - instr->dma.dst.struct_id[0] = h->struct_id; - instr->dma.n_bytes[0] = h->st->n_bits / 8; - instr->dma.src.offset[0] = tf->offset / 8; - - return 0; -} - static inline void __instr_dma_ht_exec(struct rte_swx_pipeline *p, uint32_t n_dma); @@ -7710,14 +7692,6 @@ instr_translate(struct rte_swx_pipeline *p, instr, data); - if (!strcmp(tokens[tpos], "dma")) - return instr_dma_translate(p, - action, - &tokens[tpos], - n_tokens - tpos, - instr, - data); - if (!strcmp(tokens[tpos], "add")) return instr_alu_add_translate(p, action, @@ -8294,6 +8268,180 @@ instr_pattern_emit_many_tx_optimize(struct instruction *instructions, return n_instructions; } +static uint32_t +action_arg_src_mov_count(struct action *a, + uint32_t arg_id, + struct instruction *instructions, + struct instruction_data *instruction_data, + uint32_t n_instructions); + +static int +instr_pattern_mov_all_validate_search(struct rte_swx_pipeline *p, + struct action *a, + struct instruction *instr, + struct instruction_data *data, + uint32_t n_instr, + struct instruction *instructions, + struct instruction_data *instruction_data, + uint32_t n_instructions, + uint32_t *n_pattern_instr) +{ + struct header *h; + uint32_t src_field_id, i, j; + + /* Prerequisites. */ + if (!a || !a->st) + return 0; + + /* First instruction: MOV_HM. */ + if (data[0].invalid || (instr[0].type != INSTR_MOV_HM)) + return 0; + + h = header_find_by_struct_id(p, instr[0].mov.dst.struct_id); + if (!h) + return 0; + + for (src_field_id = 0; src_field_id < a->st->n_fields; src_field_id++) + if (instr[0].mov.src.offset == a->st->fields[src_field_id].offset / 8) + break; + + if (src_field_id == a->st->n_fields) + return 0; + + if (instr[0].mov.dst.offset || + (instr[0].mov.dst.n_bits != h->st->fields[0].n_bits) || + instr[0].mov.src.struct_id || + (instr[0].mov.src.n_bits != a->st->fields[src_field_id].n_bits) || + (instr[0].mov.dst.n_bits != instr[0].mov.src.n_bits)) + return 0; + + if ((n_instr < h->st->n_fields + 1) || + (a->st->n_fields < src_field_id + h->st->n_fields + 1)) + return 0; + + /* Subsequent instructions: MOV_HM. */ + for (i = 1; i < h->st->n_fields; i++) + if (data[i].invalid || + data[i].n_users || + (instr[i].type != INSTR_MOV_HM) || + (instr[i].mov.dst.struct_id != h->struct_id) || + (instr[i].mov.dst.offset != h->st->fields[i].offset / 8) || + (instr[i].mov.dst.n_bits != h->st->fields[i].n_bits) || + instr[i].mov.src.struct_id || + (instr[i].mov.src.offset != a->st->fields[src_field_id + i].offset / 8) || + (instr[i].mov.src.n_bits != a->st->fields[src_field_id + i].n_bits) || + (instr[i].mov.dst.n_bits != instr[i].mov.src.n_bits)) + return 0; + + /* Last instruction: HDR_VALIDATE. */ + if ((instr[i].type != INSTR_HDR_VALIDATE) || + (instr[i].valid.header_id != h->id)) + return 0; + + /* Check that none of the action args that are used as source for this + * DMA transfer are not used as source in any other mov instruction. + */ + for (j = src_field_id; j < src_field_id + h->st->n_fields; j++) { + uint32_t n_users; + + n_users = action_arg_src_mov_count(a, + j, + instructions, + instruction_data, + n_instructions); + if (n_users > 1) + return 0; + } + + *n_pattern_instr = 1 + i; + return 1; +} + +static void +instr_pattern_mov_all_validate_replace(struct rte_swx_pipeline *p, + struct action *a, + struct instruction *instr, + struct instruction_data *data, + uint32_t n_instr) +{ + struct header *h; + uint32_t src_field_id, src_offset, i; + + /* Read from the instructions before they are modified. */ + h = header_find_by_struct_id(p, instr[0].mov.dst.struct_id); + if (!h) + return; + + for (src_field_id = 0; src_field_id < a->st->n_fields; src_field_id++) + if (instr[0].mov.src.offset == a->st->fields[src_field_id].offset / 8) + break; + + if (src_field_id == a->st->n_fields) + return; + + src_offset = instr[0].mov.src.offset; + + /* Modify the instructions. */ + instr[0].type = INSTR_DMA_HT; + instr[0].dma.dst.header_id[0] = h->id; + instr[0].dma.dst.struct_id[0] = h->struct_id; + instr[0].dma.src.offset[0] = (uint8_t)src_offset; + instr[0].dma.n_bytes[0] = h->st->n_bits / 8; + + for (i = 1; i < n_instr; i++) + data[i].invalid = 1; + + /* Update the endianness of the action arguments to header endianness. */ + for (i = 0; i < h->st->n_fields; i++) + a->args_endianness[src_field_id + i] = 1; +} + +static uint32_t +instr_pattern_mov_all_validate_optimize(struct rte_swx_pipeline *p, + struct action *a, + struct instruction *instructions, + struct instruction_data *instruction_data, + uint32_t n_instructions) +{ + uint32_t i; + + if (!a || !a->st) + return n_instructions; + + for (i = 0; i < n_instructions; ) { + struct instruction *instr = &instructions[i]; + struct instruction_data *data = &instruction_data[i]; + uint32_t n_instr = 0; + int detected; + + /* Mov all + validate. */ + detected = instr_pattern_mov_all_validate_search(p, + a, + instr, + data, + n_instructions - i, + instructions, + instruction_data, + n_instructions, + &n_instr); + if (detected) { + instr_pattern_mov_all_validate_replace(p, a, instr, data, n_instr); + i += n_instr; + continue; + } + + /* No pattern starting at the current instruction. */ + i++; + } + + /* Eliminate the invalid instructions that have been optimized out. */ + n_instructions = instr_compact(instructions, + instruction_data, + n_instructions); + + return n_instructions; +} + static int instr_pattern_dma_many_search(struct instruction *instr, struct instruction_data *data, @@ -8378,7 +8526,9 @@ instr_pattern_dma_many_optimize(struct instruction *instructions, } static uint32_t -instr_optimize(struct instruction *instructions, +instr_optimize(struct rte_swx_pipeline *p, + struct action *a, + struct instruction *instructions, struct instruction_data *instruction_data, uint32_t n_instructions) { @@ -8392,6 +8542,13 @@ instr_optimize(struct instruction *instructions, instruction_data, n_instructions); + /* Mov all + validate. */ + n_instructions = instr_pattern_mov_all_validate_optimize(p, + a, + instructions, + instruction_data, + n_instructions); + /* DMA many. */ n_instructions = instr_pattern_dma_many_optimize(instructions, instruction_data, @@ -8453,7 +8610,7 @@ instruction_config(struct rte_swx_pipeline *p, if (err) goto error; - n_instructions = instr_optimize(instr, data, n_instructions); + n_instructions = instr_optimize(p, a, instr, data, n_instructions); err = instr_jmp_resolve(instr, data, n_instructions); if (err) @@ -8742,6 +8899,13 @@ rte_swx_pipeline_action_config(struct rte_swx_pipeline *p, /* Node allocation. */ a = calloc(1, sizeof(struct action)); CHECK(a, ENOMEM); + if (args_struct_type) { + a->args_endianness = calloc(args_struct_type->n_fields, sizeof(int)); + if (!a->args_endianness) { + free(a); + CHECK(0, ENOMEM); + } + } /* Node initialization. */ strcpy(a->name, name); @@ -8751,6 +8915,7 @@ rte_swx_pipeline_action_config(struct rte_swx_pipeline *p, /* Instruction translation. */ err = instruction_config(p, a, instructions, n_instructions); if (err) { + free(a->args_endianness); free(a); return err; } @@ -8802,6 +8967,40 @@ action_free(struct rte_swx_pipeline *p) } } +static uint32_t +action_arg_src_mov_count(struct action *a, + uint32_t arg_id, + struct instruction *instructions, + struct instruction_data *instruction_data, + uint32_t n_instructions) +{ + uint32_t offset, n_users = 0, i; + + if (!a->st || + (arg_id >= a->st->n_fields) || + !instructions || + !instruction_data || + !n_instructions) + return 0; + + offset = a->st->fields[arg_id].offset / 8; + + for (i = 0; i < n_instructions; i++) { + struct instruction *instr = &instructions[i]; + struct instruction_data *data = &instruction_data[i]; + + if (data->invalid || + ((instr->type != INSTR_MOV) && (instr->type != INSTR_MOV_HM)) || + instr->mov.src.struct_id || + (instr->mov.src.offset != offset)) + continue; + + n_users++; + } + + return n_users; +} + /* * Table. */ @@ -9898,6 +10097,7 @@ rte_swx_ctl_action_arg_info_get(struct rte_swx_pipeline *p, arg = &a->st->fields[action_arg_id]; strcpy(action_arg->name, arg->name); action_arg->n_bits = arg->n_bits; + action_arg->is_network_byte_order = a->args_endianness[action_arg_id]; return 0; } diff --git a/lib/librte_pipeline/rte_swx_pipeline.h b/lib/librte_pipeline/rte_swx_pipeline.h index 156b1fd67..feeb10a5c 100644 --- a/lib/librte_pipeline/rte_swx_pipeline.h +++ b/lib/librte_pipeline/rte_swx_pipeline.h @@ -406,10 +406,6 @@ rte_swx_pipeline_packet_metadata_register(struct rte_swx_pipeline *p, *
+------------+----------------------+-------------------+------+--------+*
| mov | dst = src | mov dst src | HMEF | HMEFTI |*
+------------+----------------------+-------------------+------+--------+- *
| dma | memcpy(h.hdr, | dma h.hdr t.field | hdr | T |- *
| | &t.field, | | | |- *
| | sizeof(h.hdr) | | | |- *
+------------+----------------------+-------------------+------+--------+*
| add | dst += src | add dst src | HMEF | HMEFTI |*
+------------+----------------------+-------------------+------+--------+*
| sub | dst -= src | add dst src | HMEF | HMEFTI |