-
Improvement
-
Resolution: Open
-
Medium
-
None
-
None
-
None
I'm preparing packets in Scapy the following way:
>>> data = "A"*5000
>>> pkts = fragment6(Ether(src="90:e2:ba:3f:c7:69", dst="00:1c:73:f5:52:bd")/IPv6(src="127:2:3:4::2", dst="2001:db8::2")/IPv6ExtHdrFragment(nh=4) /IP(src="100.64.0.2", dst="100.64.0.1")/ICMP()/data,1024)
>>> sendp(pkts, iface="enp4s0f0")
When they reach VPP I could see the following errors:
{{vpp# sh err
Count Node Reason}}
{{ 2 ip6-map-ip6-reass could not cache fragment
4 ip6-map-ip6-reass dropped cached fragment
Packet traces were like this:
22:26:34:109020: dpdk-input
TenGigabitEthernet4/0/1 rx queue 0
buffer 0xdefa8e: current data 14, length 1008, free-list 0, clone-count 0, totlen-nifb 0, trace 0x2
PKT MBUF: port 1, nb_segs 1, pkt_len 1022
buf_len 2176, data_len 1022, ol_flags 0x182, data_off 128, phys_addr 0x13e6280
packet_type 0x0
Packet Offload Flags
PKT_RX_RSS_HASH (0x0002) RX packet with RSS hash result
PKT_RX_IP_CKSUM_GOOD (0x0080) IP cksum of RX pkt. is valid
PKT_RX_L4_CKSUM_GOOD (0x0100) L4 cksum of RX pkt. is valid
IP6: 00:1c:73:f5:52:bd -> 22:22:22:22:01:04
IPV6_FRAGMENTATION: 127:2:3:4::2 -> 2001:db8::2
tos 0x00, flow label 0x0, hop limit 63, payload length 968
22:26:34:109057: ip6-input
IPV6_FRAGMENTATION: 127:2:3:4::2 -> 2001:db8::2
tos 0x00, flow label 0x0, hop limit 63, payload length 968
22:26:34:109083: ip6-lookup
fib 0 dpo-idx 20 flow hash: 0x00000000
IPV6_FRAGMENTATION: 127:2:3:4::2 -> 2001:db8::2
tos 0x00, flow label 0x0, hop limit 63, payload length 968
22:26:34:109086: ip6-map
MAP domain index: -1 L4 port: 0
22:26:34:109087: ip6-map-ip6-reass
Offset: 16704 Fragment length: 58567 Status: in
22:26:34:109090: error-drop
ip6-map-ip6-reass: could not cache fragment
}}
{{What is weird here, starts in ip6-map-ip6-reass node (offset and fragment length). Even weirder is fragments show:
sh map fr
ip6-reass src=4500:13a4:1:0:4001:9ed5:6440:2 dst=6440:1:800:b6be::4141:4141 protocol=65 identifier=1094795585 lifetime=-1.000
ip6-reass src=4141:4141:4141:4141:4141:4141:4141:4141 dst=4141:4141:4141:4141:4141:4141:4141:4141 protocol=65 identifier=1094795585 lifetime=-1.000}}
{{414141... matches "A" paylod I encoded. First src address also resembles somethig common (IPv4 header).
I pinned the problem with gdb: pointer used in ip6_map_ip6_reass() was 40 bytes farther than it should. The culprit are these lines in ip6_map()}}
{{ ip60 = vlib_buffer_get_current (p0);
ip61 = vlib_buffer_get_current (p1);
vlib_buffer_advance (p0, sizeof (ip6_header_t));
vlib_buffer_advance (p1, sizeof (ip6_header_t));
ip40 = vlib_buffer_get_current (p0);
ip41 = vlib_buffer_get_current (p1);
So in order to take IPv4 header pointer the buffer gets advanced by sizeof(ip6_header_t), which is exactly 40 bytes. And ip6_map_ip6_reass() expects vlib buffer to still point to IPv6 header, thus the confusion.
To better fix that, I tried to lookup in history the commit that introduced vlib_buffer_advance(), but unfortunately I ended up on the root of public repository :/
So far I managed to fix that by moving back the pointer in ip6_map_ip6_reass(), but my gut feeling is that the fix is incomplete and aforementioned buffer advance may have more side-effects. Definitely something is still not right, especially with tunneled traffic directed towards ip4-local node.}}
{{On the other hand I'm a bit reluctant to change ip6_map() without prior knowledge of full scope of changes in which the buffer advance was introduced.
Is there anyone experienced in map that could help me or remember that change?
}}