Hi Ole, The problem I am facing is a bit different. It is not that it is failing for me in any scenario, but the implementation seems a little confusing and hence I posted this query for clarification. I'll try explaining my test scenario.
The documentation for VPP Configuration File - ‘startup.conf’, specifies a parameter 'enable-tcp-udp-checksum' under the dpdk parameters with the description 'Enables UDP/TCP RX checksum offload', which, from the description seems like can be used to enable L4 Rx checksum offload. But what is observed is that irrespective of this parameter being enabled/disabled, the hardware computes the checksum and sets the corresponding Rx checksum offload bits(this gets reflected in the DPDK MBUF ol_flags)( due to 'no-tx-checksum-offload' not being specified in the config file, the default Tx/Rx checksum offload config is applicable) The function dpdk_init() sets the default behavior in the buffer_flags_template, which by default assumes that L4 checksum is computed and is correct. /* Default vlib_buffer_t flags, DISABLES tcp/udp checksumming... */ dm->buffer_flags_template = (VLIB_BUFFER_TOTAL_LENGTH_VALID | VLIB_BUFFER_EXT_HDR_VALID | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED | VNET_BUFFER_F_L4_CHECKSUM_CORRECT); In dpdk_lib_init(), if the 'enable-tcp-udp-checksum' is enabled in config file, the flag bits are disabled by the following check. if (dm->conf->enable_tcp_udp_checksum) dm->buffer_flags_template &= ~(VNET_BUFFER_F_L4_CHECKSUM_CORRECT | VNET_BUFFER_F_L4_CHECKSUM_COMPUTED); Now once hardware has set the corresponding DPDK MBUF bits(PKT_RX_L4_CKSUM_GOOD/PKT_RX_L4_CKSUM_BAD), and the packet is locally destined IPv6 packet(lands in function ip6_local_inline()): Scenario 1 : parameter 'enable-tcp-udp-checksum' is added to config file, meaning 'Enable UDP/TCP RX checksum offload' Due to the VNET_BUFFER_F_L4_CHECKSUM_COMPUTED/VNET_BUFFER_F_L4_CHECKSUM_CORRECT bits getting negated in dpdk_lib_init(), need_csum would be computed 'True' in ip6_local_inline and hence, ip6_tcp_udp_icmp_validate_checksum() would get called, which would recompute the checksum again in software, a behavior different from what 'enable-tcp-udp-checksum' intends(checksum computation/validation is offloaded to H/W but still recomputed in S/W). if (PREDICT_FALSE (need_csum)) { flags = ip6_tcp_udp_icmp_validate_checksum (vm, b[0]); good_l4_csum = flags & VNET_BUFFER_F_L4_CHECKSUM_CORRECT; error = IP6_ERROR_UNKNOWN_PROTOCOL; } else { if (ip6_tcp_udp_icmp_bad_length (vm, b[0])) error = IP6_ERROR_BAD_LENGTH; } Scenario 2 : parameter 'enable-tcp-udp-checksum' is not present, hence by default VNET_BUFFER_F_L4_CHECKSUM_COMPUTED/VNET_BUFFER_F_L4_CHECKSUM_CORRECT bits are set for all Rx'ed packets, need_csum gets computed 'False', hence, no checksum is computed in software, and the packet lands in else part, meaning that even if the packet checksum is incorrect, it would still get further processed, which again doesn't seems correct. With 'enable-tcp-udp-checksum' not present, the IPv6/UDP(no IPv6 extension options present) packets land in else part and ip6_tcp_udp_icmp_bad_length() further validates this packet, but the implementation mandatorily expects the hop-by-hop extension header to be present and hence incorrectly typecasts the hop-by-hop extension header to the UDP header immediately following the IPv6 header(the ip6_hop_by_hop_ext_t next_hdr field overlapping the udp header source_port field), and hence returns a 0 due to this check: if (!(ext_hdr->next_hdr == IP_PROTOCOL_ICMP6) || (ext_hdr->next_hdr == IP_PROTOCOL_UDP)) return 0; The return value 0 here falsely implies that the ip6_tcp_udp_icmp_bad_length() has passed its length validation and proceeds further, but in essence, the length validation for IPv6/UDP packet didn't happen. Hi Florin, I think, you are partly right in you response, in stating - 'As for the length check being done only on the else branch, ip6_tcp_udp_icmp_validate_checksum needs to compute the length so I’m guessing the expectation is that the checksum validation will fail for bogus length packets.', but this shall be true for L4 only, i.e. L4 checksum validation and correctness shall implicitly also validate the L4 payload length. I think, the L3 length validation shall still be required(payload_length in ipv6 header). The function ip6_tcp_udp_icmp_bad_length() also seems to be validating the payload_length in the IPv6 header. Thanks Pankaj
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#20439): https://lists.fd.io/g/vpp-dev/message/20439 Mute This Topic: https://lists.fd.io/mt/86774091/21656 Group Owner: vpp-dev+ow...@lists.fd.io Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-