Re: [vpp-dev] Query regarding packet validation checks in ip6_local

2021-11-05 Thread pankajmalhotra83
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]
-=-=-=-=-=-=-=-=-=-=-=-



[vpp-dev] Query regarding packet validation checks in ip6_local

2021-11-02 Thread pankajmalhotra83
Hi,
In file vnet/ip/ip6_forward.c(VPP 21.01), function ip6_local_inline(), the 
node's packet processing has the following check:

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;
}

Kindly explain the reason behind the checksum and the length validation being 
under the if-else check, making the length validation not applicable for the 
case when checksum validation is applicable.

Also, in the function ip6_tcp_udp_icmp_bad_length (refer the below snippet), 
the function seems to assume that the hop-by-hop extension header shall always 
be present. Is it that, IPv6 hop-by-hop extension header has to be mandatorily 
present?

static_always_inline u8
ip6_tcp_udp_icmp_bad_length (vlib_main_t * vm, vlib_buffer_t * p0)
{

u16 payload_length_host_byte_order;
u32 n_this_buffer, n_bytes_left;
ip6_header_t *ip0 = vlib_buffer_get_current (p0);
u32 headers_size = sizeof (ip0[0]);
u8 *data_this_buffer;

data_this_buffer = (u8 *) (ip0 + 1);

ip6_hop_by_hop_ext_t *ext_hdr = (ip6_hop_by_hop_ext_t *) data_this_buffer;

/* validate really icmp6 next */

if (!(ext_hdr->next_hdr == IP_PROTOCOL_ICMP6)
|| (ext_hdr->next_hdr == IP_PROTOCOL_UDP))
return 0;
::
::

Thanks,
Pankaj Malhotra

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#20409): https://lists.fd.io/g/vpp-dev/message/20409
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]
-=-=-=-=-=-=-=-=-=-=-=-



[vpp-dev] VPP RX Checksum Offload query

2021-10-27 Thread pankajmalhotra83
Hi,
I have enabled the TCP/UDP Checksum Offload feature using the 
enable-tcp-udp-checksum in the startup.conf file. The feature gets enabled and 
the received locally destined IPV6 UDP/TCP packets at dpdk-input node have the 
bits corresponding to PKT_RX_IP_CKSUM_GOOD and PKT_RX_L4_CKSUM_GOOD set as part 
of the MBUF Packet Offload Flags.

What is observed is that, for the locally destined IPv6 TCP/UDP packets being 
RX'ed, when the packet eventually lands up in the ip6-local node, it tries 
verifying the checksum status in this node using the vlib_buffer_t flags 
field(on the basis of the VNET_BUFFER_F_L4_CHECKSUM_CORRECT, 
VNET_BUFFER_F_OFFLOAD_TCP_CKSUM, VNET_BUFFER_F_OFFLOAD_UDP_CKSUM), and as these 
particular bits are not set(from the code, the transition of the RX offload 
checksum status from the DPDK MBUF rx checksum offload bits to VLIB buffer bits 
is also not evident(currently using VPP 21.01, also checked this on the master 
branch)), it invokes ip6_tcp_udp_icmp_validate_checksum for the checksum 
verification which re-computes the L4 checksum.

My query is that, when the checksum offload is enabled in the Rx direction, for 
the locally destined IPv6 packets, is this understanding correct that the L4 
checksum would get recomputed in the software again, and if not, is there any 
other configuration setting available which I may be missing on my end, to 
avoid this re-computation.

Thanks,
Pankaj Malhotra

-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.
View/Reply Online (#20392): https://lists.fd.io/g/vpp-dev/message/20392
Mute This Topic: https://lists.fd.io/mt/86623150/21656
Group Owner: vpp-dev+ow...@lists.fd.io
Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-