2
0
mirror of https://github.com/openvswitch/ovs synced 2025-08-22 01:51:26 +00:00

conntrack: Allow inner NAT of related fragments.

Currently conntrack will refuse to extract metadata from fragmented
IPv4 packets. Usually the fragments would be processed by the ipf
module, but this isn't the case for ICMP related packets. The current
handling will result in these being incorrectly processed.

This patch checks for a frag offset instead of just frag flags, which is
similar to how conntrack handles fragments in the kernel.

Reported-at: https://issues.redhat.com/browse/FDP-136
Reported-by: Ales Musil <amusil@redhat.com>
Fixes: a489b16854b5 ("conntrack: New userspace connection tracker.")
Signed-off-by: Mike Pattrick <mkp@redhat.com>
Signed-off-by: Aaron Conole <aconole@redhat.com>
This commit is contained in:
Mike Pattrick 2025-06-05 13:41:34 -04:00 committed by Aaron Conole
parent ca9e67c801
commit 614029aac0
3 changed files with 35 additions and 1 deletions

View File

@ -1705,7 +1705,7 @@ extract_l3_ipv4(struct conn_key *key, const void *data, size_t size,
return false;
}
if (IP_IS_FRAGMENT(ip->ip_frag_off)) {
if (IP_IS_LATER_FRAG(ip->ip_frag_off)) {
return false;
}

View File

@ -736,6 +736,8 @@ IP_ECN_is_ce(uint8_t dsfield)
#define IP_FRAG_OFF_MASK 0x1fff /* Fragment offset. */
#define IP_IS_FRAGMENT(ip_frag_off) \
((ip_frag_off) & htons(IP_MORE_FRAGMENTS | IP_FRAG_OFF_MASK))
#define IP_IS_LATER_FRAG(ip_frag_off) \
((ip_frag_off) & htons(IP_FRAG_OFF_MASK))
#define IP_HEADER_LEN 20
struct ip_header {

View File

@ -11597,6 +11597,38 @@ udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=4,dport=3),reply=(src=10.1.1.1,dst=10.
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - conntrack - related nat])
OVS_VSWITCHD_START
add_of_ports --pcap br0 1 2
AT_DATA([flows.txt], [dnl
table=0,priority=100,arp,action=normal
table=0,priority=10,ip,in_port=1,udp,action=ct(commit,table=1,nat(dst=1.2.3.4:10000-10000))
table=0,priority=10,ip,in_port=2,action=ct(nat,table=1)
table=0,priority=1,action=drop
table=1,priority=10,in_port=1,ct_state=+trk,action=2
table=1,priority=10,in_port=2,ct_state=+trk,action=1
table=1,priority=1,action=drop
])
AT_CHECK([ovs-ofctl add-flows br0 flows.txt])
dnl 1. Send and UDP packet to port 5555.
packet1=c6f94ecb72dbe64c473528c9080045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a
AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=$packet1 actions=resubmit(,0)"])
dnl 2. Send an fragmented ICMP related reply from 1.2.3.4:10000.
packet2=e64c473528c9c6f94ecb72db080045c000382e87000040019b6701020304ac1000010303ad2d000000004500001c317020004011794aac10000101020304a28e2710000d8623
AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=$packet2 actions=resubmit(,0)"])
dnl 3. Check that the inner packet is translated.
packet3=e64c473528c9c6f94ecb72db080045c000382e8700004001f35aac100002ac1000010303553a000000004500001c317020004011d13dac100001ac100002a28e15b3000def73
OVS_WAIT_UNTIL([ovs-pcap p1-tx.pcap | grep -q "$packet3"])
OVS_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([ofproto-dpif - conntrack - ipv6])
OVS_VSWITCHD_START