From 89d7be27cd6b49e460ae1bd73d2c1ac6f451e30a Mon Sep 17 00:00:00 2001 From: Farhan Tariq Date: Tue, 12 Aug 2025 21:29:54 +0500 Subject: [PATCH] Update ENCAP_U1 functionality by u1_* headers emission and u1_ipv4 checksum update - Added emission of all u1_* headers in dash_deparser so U1 encapsulation is serialized into the outgoing packet. - Added IPv4 checksum update for hdr.u1_ipv4 alongside hdr.u0_ipv4. - Restored and fixed saidashflow-FlowHitActionEncapU0EncapU1 test to validate double encapsulation packet formation. ENCAP_U1 logic was missing components (header emission and checksum) prevented correct packet output. This change updates the ENCAP_U1 functionality and also updates the test coverage. Signed-off-by: Farhan Tariq --- dash-pipeline/bmv2/dash_bmv2_v1model.p4 | 38 ++++--- dash-pipeline/bmv2/dash_parser.p4 | 10 ++ test/test-cases/functional/ptf/saidashflow.py | 104 +++++++++--------- 3 files changed, 86 insertions(+), 66 deletions(-) diff --git a/dash-pipeline/bmv2/dash_bmv2_v1model.p4 b/dash-pipeline/bmv2/dash_bmv2_v1model.p4 index 6a93f962a..52e20f3a9 100644 --- a/dash-pipeline/bmv2/dash_bmv2_v1model.p4 +++ b/dash-pipeline/bmv2/dash_bmv2_v1model.p4 @@ -5,28 +5,32 @@ control dash_verify_checksum(inout headers_t hdr, apply { } } +#define UPDATE_IPV4_CHECKSUM(IPHDR) \ + update_checksum( \ + IPHDR.isValid(), \ + { \ + IPHDR.version, \ + IPHDR.ihl, \ + IPHDR.diffserv, \ + IPHDR.total_len, \ + IPHDR.identification, \ + IPHDR.frag_offset, \ + IPHDR.flags, \ + IPHDR.ttl, \ + IPHDR.protocol, \ + IPHDR.src_addr, \ + IPHDR.dst_addr \ + }, \ + IPHDR.hdr_checksum, \ + HashAlgorithm.csum16) + control dash_compute_checksum(inout headers_t hdr, inout metadata_t meta) { apply { #ifdef TARGET_BMV2_V1MODEL - update_checksum( - hdr.u0_ipv4.isValid(), - { - hdr.u0_ipv4.version, - hdr.u0_ipv4.ihl, - hdr.u0_ipv4.diffserv, - hdr.u0_ipv4.total_len, - hdr.u0_ipv4.identification, - hdr.u0_ipv4.frag_offset, - hdr.u0_ipv4.flags, - hdr.u0_ipv4.ttl, - hdr.u0_ipv4.protocol, - hdr.u0_ipv4.src_addr, - hdr.u0_ipv4.dst_addr - }, - hdr.u0_ipv4.hdr_checksum, - HashAlgorithm.csum16); + UPDATE_IPV4_CHECKSUM(hdr.u0_ipv4); + UPDATE_IPV4_CHECKSUM(hdr.u1_ipv4); #endif // TARGET_BMV2_V1MODEL } } diff --git a/dash-pipeline/bmv2/dash_parser.p4 b/dash-pipeline/bmv2/dash_parser.p4 index fcb6929f5..0cc32290e 100644 --- a/dash-pipeline/bmv2/dash_parser.p4 +++ b/dash-pipeline/bmv2/dash_parser.p4 @@ -183,6 +183,15 @@ control dash_deparser( packet.emit(hdr.flow_u0_encap_data); packet.emit(hdr.flow_u1_encap_data); + packet.emit(hdr.u1_ethernet); + packet.emit(hdr.u1_ipv4); + packet.emit(hdr.u1_ipv4options); + packet.emit(hdr.u1_ipv6); + packet.emit(hdr.u1_udp); + packet.emit(hdr.u1_tcp); + packet.emit(hdr.u1_vxlan); + packet.emit(hdr.u1_nvgre); + packet.emit(hdr.u0_ethernet); packet.emit(hdr.u0_ipv4); packet.emit(hdr.u0_ipv4options); @@ -191,6 +200,7 @@ control dash_deparser( packet.emit(hdr.u0_tcp); packet.emit(hdr.u0_vxlan); packet.emit(hdr.u0_nvgre); + packet.emit(hdr.customer_ethernet); packet.emit(hdr.customer_ipv4); packet.emit(hdr.customer_ipv6); diff --git a/test/test-cases/functional/ptf/saidashflow.py b/test/test-cases/functional/ptf/saidashflow.py index ab3d18eb2..c375d2081 100644 --- a/test/test-cases/functional/ptf/saidashflow.py +++ b/test/test-cases/functional/ptf/saidashflow.py @@ -6,9 +6,11 @@ # 2. Flow hit (ENI AMC, VNI, 5 tuple), UDP packet, flow action: ENCAP_U0 # 3. Flow hit (ENI AMC, VNI, 5 tuple), UDP packet, flow action: SET_DMAC (overlay dmac rewrite) # 4. Flow hit (ENI AMC, VNI, 5 tuple), UDP packet, flow action: ENCAP_U0 | SET_DMAC +# 5. Flow hit (ENI AMC, VNI, 5 tuple), UDP packet, flow action: ENCAP_U0 | SET_SMAC (Disabled due to lack of implementation for overlay smac rewrite) +# 6. Flow hit (ENI AMC, VNI, 5 tuple), UDP packet, flow action: ENCAP_U0 | ENCAP_U1 # SET_SMAC, SNAT, DNAT, SNAT_PORT, DNAT_PORT are not yet implemented so they are not covered in the test cases. # NAT46 and NAT64 are not yet supported (ipv6 address not supported) so they are not covered in the test cases. -# ENCAP_U1 implementation seems to have some error. + import copy from sai_thrift.sai_headers import * @@ -150,7 +152,11 @@ def runTest(self): exp_u0_dip_t = sai_thrift_ip_address_t(addr_family=SAI_IP_ADDR_FAMILY_IPV4, addr=sai_thrift_ip_addr_t(ip4=self.exp_u0_dip)) exp_u0_sip_t = sai_thrift_ip_address_t(addr_family=SAI_IP_ADDR_FAMILY_IPV4, - addr=sai_thrift_ip_addr_t(ip4=self.exp_u0_sip)) + addr=sai_thrift_ip_addr_t(ip4=self.exp_u0_sip)) + exp_u1_dip_t = sai_thrift_ip_address_t(addr_family=SAI_IP_ADDR_FAMILY_IPV4, + addr=sai_thrift_ip_addr_t(ip4=self.exp_u1_dip)) + exp_u1_sip_t = sai_thrift_ip_address_t(addr_family=SAI_IP_ADDR_FAMILY_IPV4, + addr=sai_thrift_ip_addr_t(ip4=self.exp_u1_sip)) # Assemble flow entry self.fe = sai_thrift_flow_entry_t(switch_id=self.switch_id, eni_mac=self.eni_mac, vnet_id=self.vnet_vni, ip_proto=self.protocol, src_ip=sip_t, dst_ip=dip_t, src_port=self.inner_sport, dst_port=self.inner_dport) self.create_flow_entry( @@ -179,12 +185,12 @@ def runTest(self): underlay0_smac=self.exp_u0_smac, underlay0_dmac=self.exp_u0_dmac, underlay0_dash_encapsulation=SAI_DASH_ENCAPSULATION_VXLAN, - underlay1_vnet_id=None, - underlay1_sip=None, - underlay1_dip=None, - underlay1_smac="00:00:00:00:00:00", - underlay1_dmac="00:00:00:00:00:00", - underlay1_dash_encapsulation=SAI_DASH_ENCAPSULATION_INVALID, + underlay1_vnet_id=self.vnet_vni, + underlay1_sip=exp_u1_sip_t, + underlay1_dip=exp_u1_dip_t, + underlay1_smac=self.exp_u1_smac, + underlay1_dmac=self.exp_u1_dmac, + underlay1_dash_encapsulation=SAI_DASH_ENCAPSULATION_VXLAN, # Flow overlay rewrite related attributes dst_mac=self.exp_inner_dmac, # sip=self.exp_inner_sip, @@ -512,47 +518,6 @@ def setupTest(self): exp_inner_dport = self.dst_port )) - # # Test case xx: flow hit (5 tuple) - # # action: encap_u0 | encap_u1 - # # expected: pass - # self.tests.append(FlowTest(saithrift = self, - # name = "FlowHitActionEncapU0EncapU1", - # create_entry = True, - # switch_id = self.switch_id, - # vnet_vni = self.vnet_vni, - # vnet_id = self.vnet_id, - # outbound_vni = self.outbound_vni, - # eni_mac = self.vm_mac, - # outer_smac = "00:00:00:00:00:00", - # outer_dmac = "00:00:00:00:00:00", - # outer_sip = self.src_vm_pa_ip, - # outer_dip = self.vip, - # inner_smac = self.vm_mac, - # inner_dmac = self.dst_ca_mac, - # protocol = 17, - # inner_sip = self.src_vm_ca_ip, - # inner_dip = self.dst_ca_ip, - # inner_sport = self.src_vm_port, - # inner_dport = self.dst_port, - # priority = 1, - # action = SAI_DASH_FLOW_ACTION_ENCAP_U0 | SAI_DASH_FLOW_ACTION_ENCAP_U1, - # exp_receive = True, - # exp_u0_smac = self.eni_mac, - # exp_u0_dmac = self.underlay_dmac, - # exp_u0_sip = self.src_vm_pa_ip, - # exp_u0_dip = self.dst_pa_ip, - # exp_u1_smac = "11:22:33:44:55:66", - # exp_u1_dmac = "77:88:99:aa:bb:cc", - # exp_u1_sip = "200.0.1.2", - # exp_u1_dip = "200.3.4.5", - # exp_inner_smac = self.vm_mac, - # exp_inner_dmac = self.dst_ca_mac, - # exp_inner_sip = self.src_vm_ca_ip, - # exp_inner_dip = self.dst_ca_ip, - # exp_inner_sport = self.src_vm_port, - # exp_inner_dport = self.dst_port - # )) - # Test case 3: flow hit (5 tuple) # action: overlay dmac rewrite # expected: pass @@ -660,6 +625,47 @@ def setupTest(self): # exp_inner_dport = self.dst_port # )) + # Test case 6: flow hit (5 tuple) + # action: encap_u0 | encap_u1 + # expected: pass + self.tests.append(FlowTest(saithrift = self, + name = "FlowHitActionEncapU0EncapU1", + create_entry = True, + switch_id = self.switch_id, + vnet_vni = self.vnet_vni, + vnet_id = self.vnet_id, + outbound_vni = self.outbound_vni, + eni_mac = self.vm_mac, + outer_smac = "00:00:00:00:00:00", + outer_dmac = "00:00:00:00:00:00", + outer_sip = self.src_vm_pa_ip, + outer_dip = self.vip, + inner_smac = self.vm_mac, + inner_dmac = self.dst_ca_mac, + protocol = 17, + inner_sip = self.src_vm_ca_ip, + inner_dip = self.dst_ca_ip, + inner_sport = self.src_vm_port, + inner_dport = self.dst_port, + priority = 1, + action = SAI_DASH_FLOW_ACTION_ENCAP_U0 | SAI_DASH_FLOW_ACTION_ENCAP_U1, + exp_receive = True, + exp_u0_smac = self.eni_mac, + exp_u0_dmac = self.underlay_dmac, + exp_u0_sip = self.src_vm_pa_ip, + exp_u0_dip = self.dst_pa_ip, + exp_u1_smac = "11:22:33:44:55:66", + exp_u1_dmac = "77:88:99:aa:bb:cc", + exp_u1_sip = "200.0.1.2", + exp_u1_dip = "200.3.4.5", + exp_inner_smac = self.vm_mac, + exp_inner_dmac = self.dst_ca_mac, + exp_inner_sip = self.src_vm_ca_ip, + exp_inner_dip = self.dst_ca_ip, + exp_inner_sport = self.src_vm_port, + exp_inner_dport = self.dst_port + )) + def setUp(self): super(SaiThriftDashFlowTest, self).setUp() self.cleaned_up = False