2
0
mirror of https://github.com/openvswitch/ovs synced 2025-09-04 00:05:15 +00:00

system-tests: Test openflow matching for ct related packets with SNAT.

Linux kernel commit ebddb1404900 ("net: move the nat function to
nf_nat_ovs for ovs and tc") introduced a regression into the kernel
datapath which prevented the openvswitch match key from being updated
when nat was undone for packets in the related conntrack state. This
issue caused these packets (usually ICMP/ICMPv6 error packets) to
match the wrong openflow rule.

This issue was fixed in linux kernel commit e6345d2824a3 ("netfilter:
nf_nat: fix action not being set for all ct states").

This test will fail for linux kernel versions v6.2 to v6.6, so test is
skipped for versions lower than v6.7.

Link: https://lore.kernel.org/netdev/20231221224311.130319-1-brad@faucet.nz/
Suggested-by: Aaron Conole <aconole@redhat.com>
Signed-off-by: Brad Cowie <brad@faucet.nz>
Signed-off-by: Aaron Conole <aconole@redhat.com>
This commit is contained in:
Brad Cowie
2024-01-05 17:58:31 +13:00
committed by Aaron Conole
parent 7404d25ea7
commit 7b74454c72
2 changed files with 94 additions and 0 deletions

View File

@@ -19,6 +19,11 @@ s/dir\/[0-9]*\/br0.mgmt/dir\/XXXX\/br0.mgmt/
'
}
# Strips out byte counters from ovs-ofctl output
ofctl_strip_bytes () {
sed 's/ n_bytes=[0-9]*,//'
}
# Filter (multiline) vconn debug messages from ovs-vswitchd.log.
# Use with vconn_sub() and ofctl_strip()
print_vconn_debug () { awk -F\| < ovs-vswitchd.log '

View File

@@ -6473,6 +6473,95 @@ AT_CHECK([tcpdump -n -v "icmp" -r p0.pcap 2>/dev/null | grep -E 'wrong|bad'], [1
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
AT_SETUP([conntrack - ICMP related with SNAT])
AT_SKIP_IF([test $HAVE_NC = no])
AT_SKIP_IF([test $HAVE_TCPDUMP = no])
OVS_CHECK_MIN_KERNEL(6, 7)
CHECK_CONNTRACK()
CHECK_CONNTRACK_NAT()
OVS_TRAFFIC_VSWITCHD_START()
ADD_NAMESPACES(at_ns0, at_ns1)
ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
NS_CHECK_EXEC([at_ns0], [ip link set dev p0 address 80:88:88:88:88:88])
ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24")
dnl Allow IP traffic from ns0->ns1, rewrite source IP with SNAT to 10.1.1.254.
dnl Only allow related ICMP responses back and undo NAT to restore original IP.
AT_DATA([flows.txt], [dnl
ct_state=-trk,ip actions=ct(table=0)
ct_state=+trk,ip,in_port=1 actions=ct(commit,nat(src=10.1.1.254)),2
ct_state=+rel+trk,icmp,in_port=2,nw_dst=10.1.1.254 actions=ct(commit,table=1,nat)
dnl
dnl Handle ICMP related packets.
dnl These should match first rule with original IPs before SNAT.
dnl The second rule, which matches on the SNAT IP, shouldn't match any packets.
table=1,in_port=2,ct_state=+rel+trk,icmp,nw_src=10.1.1.2,nw_dst=10.1.1.1 action=1
table=1,in_port=2,ct_state=+rel+trk,icmp,nw_dst=10.1.1.254 action=goto_table:2
table=1,priority=0,action=drop
dnl
dnl Drop any ICMP related packets that incorrectly reach this table.
table=2,priority=0,action=drop
dnl
dnl ARP
priority=100 arp arp_op=1 action=move:OXM_OF_ARP_TPA[[]]->NXM_NX_REG2[[]],resubmit(,8),goto_table:10
priority=10 arp action=normal
priority=0,action=drop
dnl
dnl MAC resolution table for IP in reg2, stores mac in OXM_OF_PKT_REG0
table=8,reg2=0x0a0101f0/0xfffffff0,action=load:0x808888888888->OXM_OF_PKT_REG0[[]]
table=8,priority=0,action=load:0->OXM_OF_PKT_REG0[[]]
dnl ARP responder mac filled in at OXM_OF_PKT_REG0, or 0 for normal action.
dnl TPA IP in reg2.
dnl Swaps the fields of the ARP message to turn a query to a response.
table=10 priority=100 arp xreg0=0 action=normal
table=10 priority=10,arp,arp_op=1,action=load:2->OXM_OF_ARP_OP[[]],move:OXM_OF_ARP_SHA[[]]->OXM_OF_ARP_THA[[]],move:OXM_OF_PKT_REG0[[0..47]]->OXM_OF_ARP_SHA[[]],move:OXM_OF_ARP_SPA[[]]->OXM_OF_ARP_TPA[[]],move:NXM_NX_REG2[[]]->OXM_OF_ARP_SPA[[]],move:NXM_OF_ETH_SRC[[]]->NXM_OF_ETH_DST[[]],move:OXM_OF_PKT_REG0[[0..47]]->NXM_OF_ETH_SRC[[]],move:NXM_OF_IN_PORT[[]]->NXM_NX_REG3[[0..15]],load:0->NXM_OF_IN_PORT[[]],output:NXM_NX_REG3[[0..15]]
table=10 priority=0 action=drop
])
AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt])
rm p0.pcap
OVS_DAEMONIZE([tcpdump -n -U -i ovs-p0 -w p0.pcap], [tcpdump.pid])
sleep 1
dnl UDP packets from ns0->ns1 should solicit "destination unreachable" response.
NS_CHECK_EXEC([at_ns0], [bash -c "echo a | nc $NC_EOF_OPT -u 10.1.1.2 10000"])
dnl Flush conntrack state.
dnl To verify related packets are handled exactly the same as before flushing.
AT_CHECK([ovs-appctl dpctl/flush-conntrack], [0])
dnl Solicit another "destination unreachable" response.
dnl To verify that after flushing, the same openflow rules are matched.
NS_CHECK_EXEC([at_ns0], [bash -c "echo a | nc $NC_EOF_OPT -u 10.1.1.2 10000"])
AT_CHECK([ovs-appctl revalidator/purge], [0])
AT_CHECK([ovs-ofctl -O OpenFlow15 dump-flows br0 | ofctl_strip | ofctl_strip_bytes | sort | grep -v drop], [0], [dnl
n_packets=1, priority=10,arp actions=NORMAL
n_packets=2, ct_state=+rel+trk,icmp,in_port=2,nw_dst=10.1.1.254 actions=ct(commit,table=1,nat)
n_packets=2, ct_state=+trk,ip,in_port=1 actions=ct(commit,nat(src=10.1.1.254)),output:2
n_packets=2, priority=100,arp,arp_op=1 actions=move:NXM_OF_ARP_TPA[[]]->NXM_NX_REG2[[]],resubmit(,8),goto_table:10
n_packets=4, ct_state=-trk,ip actions=ct(table=0)
table=1, ct_state=+rel+trk,icmp,in_port=2,nw_dst=10.1.1.254 actions=goto_table:2
table=1, n_packets=2, ct_state=+rel+trk,icmp,in_port=2,nw_src=10.1.1.2,nw_dst=10.1.1.1 actions=output:1
table=10, n_packets=1, priority=10,arp,arp_op=1 actions=set_field:2->arp_op,move:NXM_NX_ARP_SHA[[]]->NXM_NX_ARP_THA[[]],move:OXM_OF_PKT_REG0[[0..47]]->NXM_NX_ARP_SHA[[]],move:NXM_OF_ARP_SPA[[]]->NXM_OF_ARP_TPA[[]],move:NXM_NX_REG2[[]]->NXM_OF_ARP_SPA[[]],move:NXM_OF_ETH_SRC[[]]->NXM_OF_ETH_DST[[]],move:OXM_OF_PKT_REG0[[0..47]]->NXM_OF_ETH_SRC[[]],move:NXM_OF_IN_PORT[[]]->NXM_NX_REG3[[0..15]],set_field:0->in_port,output:NXM_NX_REG3[[0..15]]
table=10, n_packets=1, priority=100,arp,reg0=0,reg1=0 actions=NORMAL
table=8, n_packets=1, priority=0 actions=set_field:0->xreg0
table=8, n_packets=1, reg2=0xa0101f0/0xfffffff0 actions=set_field:0x808888888888->xreg0
OFPST_FLOW reply (OF1.5):
])
AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | sed -e 's/dst=10.1.1.2[[45]][[0-9]]/dst=10.1.1.2XX/'], [0], [dnl
udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=<cleared>,dport=<cleared>),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=<cleared>,dport=<cleared>)
])
AT_CHECK([tcpdump -n -v "icmp" -r p0.pcap 2>/dev/null | grep -E 'wrong|bad'], [1], [ignore-nolog])
OVS_TRAFFIC_VSWITCHD_STOP
AT_CLEANUP
dnl CHECK_FTP_NAT(TITLE, IP_ADDR, FLOWS, CT_DUMP)
dnl
dnl Checks the implementation of conntrack with FTP ALGs in combination with