AT_BANNER([datapath-sanity]) AT_SETUP([datapath - ping between two ports]) OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - ping between two ports on vlan]) OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VLAN(p0, at_ns0, 100, "10.2.2.1/24") ADD_VLAN(p1, at_ns1, 100, "10.2.2.2/24") NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - ping6 between two ports]) OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - ping6 between two ports on vlan]) OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") ADD_VLAN(p0, at_ns0, 100, "fc00:1::1/96") ADD_VLAN(p1, at_ns1, 100, "fc00:1::2/96") dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00:1::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00:1::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00:1::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - ping over vxlan tunnel]) OVS_CHECK_VXLAN() OVS_TRAFFIC_VSWITCHD_START() ADD_BR([br-underlay]) AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"]) ADD_NAMESPACES(at_ns0) dnl Set up underlay link from host into the namespace using veth pair. ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24") AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"]) AT_CHECK([ip link set dev br-underlay up]) dnl Set up tunnel endpoints on OVS outside the namespace and with a native dnl linux device inside the namespace. ADD_OVS_TUNNEL([vxlan], [br0], [at_vxlan0], [172.31.1.1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], [10.1.1.1/24], [id 0 dstport 4789]) dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Okay, now check the overlay with different packet sizes NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - controller]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=1,udp,action=ct(commit),controller priority=100,in_port=2,ct_state=-trk,udp,action=ct(table=0) priority=100,in_port=2,ct_state=+trk+est,udp,action=controller ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) AT_CAPTURE_FILE([ofctl_monitor.log]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl --detach --no-chdir --pidfile 2> ofctl_monitor.log]) dnl Send an unsolicited reply from port 2. This should be dropped. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0\) '50540000000a50540000000908004500001c00000000001100000a0101020a0101010002000100080000']) dnl OK, now start a new connection from port 1. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 ct\(commit\),controller '50540000000a50540000000908004500001c00000000001100000a0101010a0101020001000200080000']) dnl Now try a reply from port 2. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0\) '50540000000a50540000000908004500001c00000000001100000a0101020a0101010002000100080000']) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): total_len=42 in_port=1 (via action) data_len=42 (unbuffered) udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.1,nw_dst=10.1.1.2,nw_tos=0,nw_ecn=0,nw_ttl=0,tp_src=1,tp_dst=2 udp_csum:0 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=42 ct_state=est|rpl|trk,in_port=2 (via action) data_len=42 (unbuffered) udp,vlan_tci=0x0000,dl_src=50:54:00:00:00:09,dl_dst=50:54:00:00:00:0a,nw_src=10.1.1.2,nw_dst=10.1.1.1,nw_tos=0,nw_ecn=0,nw_ttl=0,tp_src=2,tp_dst=1 udp_csum:0 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 HTTP]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(commit),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=2,ct_state=+trk+est,tcp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 >/dev/null]) dnl HTTP requests from ns0->ns1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) dnl HTTP requests from ns1->ns0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns1], [wget 10.1.1.1 -t 3 -T 1 -v -o wget1.log], [4]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 HTTP]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,icmp6,action=normal priority=100,in_port=1,tcp6,action=ct(commit),2 priority=100,in_port=2,ct_state=-trk,tcp6,action=ct(table=0) priority=100,in_port=2,ct_state=+trk+est,tcp6,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; dnl HTTP requests from ns0->ns1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py http6]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget http://[[fc00::2]] -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl tcp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::1,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) dnl HTTP requests from ns1->ns0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py http6]], [http1.pid]) NS_CHECK_EXEC([at_ns1], [wget http://[[fc00::1]] -t 3 -T 1 -v -o wget1.log], [4]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - commit, recirc]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow any traffic from ns0->ns1, ns2->ns3. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,ct_state=-trk,action=ct(commit,table=0) priority=100,in_port=1,tcp,ct_state=+trk,action=2 priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,tcp,ct_state=+trk,action=1 priority=100,in_port=3,tcp,ct_state=-trk,action=set_field:0->metadata,ct(table=0) priority=100,in_port=3,tcp,ct_state=+trk,metadata=0,action=set_field:1->metadata,ct(commit,table=0) priority=100,in_port=3,tcp,ct_state=+trk,metadata=1,action=4 priority=100,in_port=4,tcp,ct_state=-trk,action=ct(commit,table=0) priority=100,in_port=4,tcp,ct_state=+trk,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl HTTP requests from p2->p3 should work fine. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 --retry-connrefused -v -o wget1.log]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - preserve registers]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow any traffic from ns0->ns1, ns2->ns3. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,ct_state=-trk,action=ct(commit,table=0) priority=100,in_port=1,tcp,ct_state=+trk,action=2 priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,tcp,ct_state=+trk,action=1 priority=100,in_port=3,tcp,ct_state=-trk,action=load:0->NXM_NX_REG0[[]],ct(table=0) priority=100,in_port=3,tcp,ct_state=+trk,reg0=0,action=load:1->NXM_NX_REG0[[]],ct(commit,table=0) priority=100,in_port=3,tcp,ct_state=+trk,reg0=1,action=4 priority=100,in_port=4,tcp,ct_state=-trk,action=ct(commit,table=0) priority=100,in_port=4,tcp,ct_state=+trk,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl HTTP requests from p2->p3 should work fine. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 --retry-connrefused -v -o wget1.log]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - invalid]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Pass traffic from ns0->ns1 without committing, but attempt to track in dnl the opposite direction. This should fail. dnl Pass traffic from ns3->ns4 without committing, and this time match dnl invalid traffic and allow it through. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=2,ct_state=+trk+new,tcp,action=1 priority=100,in_port=3,tcp,action=ct(),4 priority=100,in_port=4,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=4,ct_state=+trk+inv,tcp,action=3 priority=100,in_port=4,ct_state=+trk+new,tcp,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl We set up our rules to allow the request without committing. The return dnl traffic can't be identified, because the initial request wasn't committed. dnl For the first pair of ports, this means that the connection fails. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log], [4]) dnl For the second pair, we allow packets from invalid connections, so it works. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 --retry-connrefused -v -o wget1.log]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - zones]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow any traffic from ns0->ns1. Allow return traffic, matching on zone. dnl For ns2->ns3, use a different zone and see that the match fails. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(commit,zone=1),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=1) priority=100,in_port=2,ct_state=+trk,ct_zone=1,tcp,action=1 priority=100,in_port=3,tcp,action=ct(commit,zone=2),4 priority=100,in_port=4,ct_state=-trk,tcp,action=ct(table=0,zone=2) priority=100,in_port=4,ct_state=+trk,ct_zone=1,tcp,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.4)], [0], [dnl tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=,dport=),reply=(src=10.1.1.4,dst=10.1.1.3,sport=,dport=),zone=2,protoinfo=(state=ESTABLISHED) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - zones from field]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=load:0x1001->NXM_NX_REG0[[0..15]],ct(commit,zone=NXM_NX_REG0[[0..15]]),2 priority=100,in_port=2,ct_state=-trk,tcp,action=load:0x1001->NXM_NX_REG0[[0..15]],ct(table=0,zone=NXM_NX_REG0[[0..15]]) priority=100,in_port=2,ct_state=+trk,ct_zone=0x1001,tcp,action=1 priority=100,in_port=3,tcp,action=load:0x1002->NXM_NX_REG0[[0..15]],ct(commit,zone=NXM_NX_REG0[[0..15]]),4 priority=100,in_port=4,ct_state=-trk,tcp,action=load:0x1002->NXM_NX_REG0[[0..15]],ct(table=0,zone=NXM_NX_REG0[[0..15]]) priority=100,in_port=4,ct_state=+trk,ct_zone=0x1001,tcp,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=4097,protoinfo=(state=TIME_WAIT) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.4)], [0], [dnl tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=,dport=),reply=(src=10.1.1.4,dst=10.1.1.3,sport=,dport=),zone=4098,protoinfo=(state=ESTABLISHED) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - multiple bridges]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START( [_ADD_BR([br1]) --\ add-port br0 patch+ -- set int patch+ type=patch options:peer=patch- --\ add-port br1 patch- -- set int patch- type=patch options:peer=patch+ --]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br1, "10.1.1.2/24") dnl Allow any traffic from ns0->br1, allow established in reverse. AT_DATA([flows-br0.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=2,tcp,ct_state=-trk,action=ct(commit,zone=1),1 priority=100,in_port=1,tcp,ct_state=-trk,action=ct(table=0,zone=1) priority=100,in_port=1,tcp,ct_state=+trk+est,ct_zone=1,action=2 ]) dnl Allow any traffic from br0->ns1, allow established in reverse. AT_DATA([flows-br1.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,ct_state=-trk,action=ct(table=0,zone=2) priority=100,in_port=1,tcp,ct_state=+trk+new,ct_zone=2,action=ct(commit,zone=2),2 priority=100,in_port=1,tcp,ct_state=+trk+est,ct_zone=2,action=2 priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0,zone=2) priority=100,in_port=2,tcp,ct_state=+trk+est,ct_zone=2,action=ct(commit,zone=2),1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) AT_CHECK([ovs-ofctl --bundle add-flows br1 flows-br1.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - multiple zones]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(commit,zone=1),ct(commit,zone=2),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=2) priority=100,in_port=2,ct_state=+trk,ct_zone=2,tcp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl (again) HTTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=SYN_SENT) tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=2,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - multiple zones, local]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0) AT_CHECK([ip addr add dev br0 "10.1.1.1/24"]) AT_CHECK([ip link set dev br0 up]) on_exit 'ip addr del dev br0 "10.1.1.1/24"' ADD_VETH(p0, at_ns0, br0, "10.1.1.2/24") dnl Allow traffic from local stack to ns0. Only allow neighbour discovery, dnl return traffic from ns0 back to the local stack. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=LOCAL,ip,ct_state=-trk,action=drop priority=100,in_port=LOCAL,ip,ct_state=+trk+new,action=ct(commit,zone=1),ct(commit,zone=2),1 priority=100,in_port=LOCAL,ip,ct_state=+trk+est,action=ct(commit,zone=1),ct(commit,zone=2),1 priority=100,in_port=1,ip,ct_state=-trk,action=ct(table=1,zone=1) table=1,priority=100,in_port=1,ip,ct_state=+trk+est,ct_zone=1,action=ct(table=2,zone=2) table=2,priority=100,in_port=1,ip,ct_state=+trk+est,ct_zone=2,action=LOCAL ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) AT_CHECK([ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl HTTP requests from root namespace to p0 should work fine. NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) AT_CHECK([wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl (again) HTTP requests from root namespace to p0 should work fine. AT_CHECK([wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep "zone"], [0], [dnl icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=),reply=(src=10.1.1.2,dst=10.1.1.1,id=),zone=1 icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=),reply=(src=10.1.1.2,dst=10.1.1.1,id=),zone=2 tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=2,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - multiple namespaces, internal ports]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START( [set-fail-mode br0 secure -- ]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_INT(p0, at_ns0, br0, "10.1.1.1/24") ADD_INT(p1, at_ns1, br0, "10.1.1.2/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. dnl dnl If skb->nfct is leaking from inside the namespace, this test will fail. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,ct_state=-trk,action=ct(commit,zone=1),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0,zone=1) priority=100,in_port=2,ct_state=+trk,ct_zone=1,tcp,action=1 ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl (again) HTTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP(["dnl /ioctl(SIOCGIFINDEX) on .* device failed: No such device/d /removing policing failed: No such device/d"]) AT_CLEANUP AT_SETUP([conntrack - multi-stage pipeline, local]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0) AT_CHECK([ip addr add dev br0 "10.1.1.1/24"]) AT_CHECK([ip link set dev br0 up]) on_exit 'ip addr del dev br0 "10.1.1.1/24"' ADD_VETH(p0, at_ns0, br0, "10.1.1.2/24") dnl Allow traffic from local stack to ns0. Only allow neighbour discovery, dnl return traffic from ns0 back to the local stack. AT_DATA([flows.txt], [dnl dnl default table=0,priority=1,action=drop table=0,priority=10,arp,action=normal dnl Load the output port to REG0 table=0,priority=100,ip,in_port=LOCAL,action=load:1->NXM_NX_REG0[[0..15]],goto_table:1 table=0,priority=100,ip,in_port=1,action=load:65534->NXM_NX_REG0[[0..15]],goto_table:1 dnl Ingress pipeline dnl - Allow all connections from LOCAL port (commit and proceed to egress) dnl - All other connections go through conntracker using the input port as dnl a connection tracking zone. table=1,priority=150,in_port=LOCAL,ip,ct_state=+trk+new,action=ct(commit,zone=OXM_OF_IN_PORT[[0..15]]),goto_table:2 table=1,priority=100,ip,action=ct(table=2,zone=OXM_OF_IN_PORT[[0..15]]) table=1,priority=1,action=drop dnl Egress pipeline dnl - Allow all connections from LOCAL port (commit and skip to output) dnl - Allow other established connections to go through conntracker using dnl output port as a connection tracking zone. table=2,priority=150,in_port=LOCAL,ip,ct_state=+trk+new,action=ct(commit,zone=NXM_NX_REG0[[0..15]]),goto_table:4 table=2,priority=100,ip,ct_state=+trk+est,action=ct(table=3,zone=NXM_NX_REG0[[0..15]]) table=2,priority=1,action=drop dnl Only allow established traffic from egress ct lookup table=3,priority=100,ip,ct_state=+trk+est,action=goto_table:4 table=3,priority=1,action=drop dnl output table table=4,priority=100,ip,action=output:NXM_NX_REG0[[]] ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) AT_CHECK([ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl HTTP requests from root namespace to p0 should work fine. NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) AT_CHECK([wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl (again) HTTP requests from root namespace to p0 should work fine. AT_CHECK([wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep "zone"], [0], [dnl icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=),reply=(src=10.1.1.2,dst=10.1.1.1,id=),zone=1 icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=),reply=(src=10.1.1.2,dst=10.1.1.1,id=),zone=65534 tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=65534,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ct_mark]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow traffic between ns0<->ns1 using the ct_mark. dnl Check that different marks do not match for traffic between ns2<->ns3. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(commit,exec(set_field:1->ct_mark)),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=2,ct_state=+trk,ct_mark=1,tcp,action=1 priority=100,in_port=3,tcp,action=ct(commit,exec(set_field:2->ct_mark)),4 priority=100,in_port=4,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=4,ct_state=+trk,ct_mark=1,tcp,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep TIME], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),mark=1,protoinfo=(state=TIME_WAIT) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.4)], [0], [dnl tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=,dport=),reply=(src=10.1.1.4,dst=10.1.1.3,sport=,dport=),mark=2,protoinfo=(state=ESTABLISHED) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ct_mark from register]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=load:1->NXM_NX_REG0[[0..31]],ct(commit,exec(move:NXM_NX_REG0[[0..31]]->NXM_NX_CT_MARK[[]])),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=2,ct_state=+trk,ct_mark=1,tcp,action=1 priority=100,in_port=3,tcp,action=load:2->NXM_NX_REG0[[0..31]],ct(commit,exec(move:NXM_NX_REG0[[0..31]]->NXM_NX_CT_MARK[[]])),4 priority=100,in_port=4,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=4,ct_state=+trk,ct_mark=1,tcp,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep TIME], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),mark=1,protoinfo=(state=TIME_WAIT) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.4)], [0], [dnl tcp,orig=(src=10.1.1.3,dst=10.1.1.4,sport=,dport=),reply=(src=10.1.1.4,dst=10.1.1.3,sport=,dport=),mark=2,protoinfo=(state=ESTABLISHED) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ct_label]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2, at_ns3) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.3/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.4/24") dnl Allow traffic between ns0<->ns1 using the ct_label. dnl Check that different labels do not match for traffic between ns2<->ns3. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(commit,exec(set_field:0x0a000d000005000001->ct_label)),2 priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=2,ct_state=+trk,ct_label=0x0a000d000005000001,tcp,action=1 priority=100,in_port=3,tcp,action=ct(commit,exec(set_field:0x2->ct_label)),4 priority=100,in_port=4,ct_state=-trk,tcp,action=ct(table=0) priority=100,in_port=4,ct_state=+trk,ct_label=0x0a000d000005000001,tcp,action=3 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns3], [[$PYTHON $srcdir/test-l7.py]], [http1.pid]) NS_CHECK_EXEC([at_ns2], [wget 10.1.1.4 -t 3 -T 1 -v -o wget1.log], [4]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ICMP related]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Allow UDP traffic from ns0->ns1. Only allow related ICMP responses back. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=1,udp,action=ct(commit,exec(set_field:1->ct_mark)),2 priority=100,in_port=2,icmp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,icmp,ct_state=+trk+rel,ct_mark=1,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) 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"]) AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort | grep -v drop], [0], [dnl n_packets=1, n_bytes=44, priority=100,udp,in_port=1 actions=ct(commit,exec(load:0x1->NXM_NX_CT_MARK[[]])),output:2 n_packets=1, n_bytes=72, priority=100,ct_state=+rel+trk,ct_mark=0x1,icmp,in_port=2 actions=output:1 n_packets=1, n_bytes=72, priority=100,ct_state=-trk,icmp,in_port=2 actions=ct(table=0) n_packets=2, n_bytes=84, priority=10,arp actions=NORMAL NXST_FLOW reply: ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ICMP related 2]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "172.16.0.1/24") ADD_VETH(p1, at_ns1, br0, "172.16.0.2/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=1,udp,ct_state=-trk,action=ct(commit,table=0) priority=100,in_port=1,ip,ct_state=+trk,actions=controller priority=100,in_port=2,ip,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,ip,ct_state=+trk+rel+rpl,action=controller ]) AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows.txt]) AT_CAPTURE_FILE([ofctl_monitor.log]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl --detach --no-chdir --pidfile 2> ofctl_monitor.log]) dnl 1. Send an ICMP port unreach reply for port 8738, without any previous request AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0\) 'f64c473528c9c6f54ecb72db080045c0003d2e8700004001f355ac100004ac1000030303553f0000000045000021317040004011b138ac100003ac10000411112222000d20966369616f0a']) dnl 2. Send and UDP packet to port 5555 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 ct\(commit,table=0\) 'c6f94ecb72dbe64c473528c9080045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a']) dnl 3. Send an ICMP port unreach reply for port 5555, related to the first packet AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0\) 'e64c473528c9c6f94ecb72db080045c0003d2e8700004001f355ac100002ac1000010303553f0000000045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a']) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=47 ct_state=new|trk,in_port=1 (via action) data_len=47 (unbuffered) udp,vlan_tci=0x0000,dl_src=e6:4c:47:35:28:c9,dl_dst=c6:f9:4e:cb:72:db,nw_src=172.16.0.1,nw_dst=172.16.0.2,nw_tos=0,nw_ecn=0,nw_ttl=64,tp_src=41614,tp_dst=5555 udp_csum:2096 NXT_PACKET_IN (xid=0x0): cookie=0x0 total_len=75 ct_state=rel|rpl|trk,in_port=2 (via action) data_len=75 (unbuffered) icmp,vlan_tci=0x0000,dl_src=c6:f9:4e:cb:72:db,dl_dst=e6:4c:47:35:28:c9,nw_src=172.16.0.2,nw_dst=172.16.0.1,nw_tos=192,nw_ecn=0,nw_ttl=64,icmp_type=3,icmp_code=3 icmp_csum:553f ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP]) AT_SKIP_IF([test $HAVE_PYFTPDLIB = no]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows1.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,action=ct(alg=ftp,commit),2 priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,tcp,ct_state=+trk+est,action=1 priority=100,in_port=2,tcp,ct_state=+trk+rel,action=1 ]) dnl Similar policy but without allowing all traffic from ns0->ns1. AT_DATA([flows2.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,ct_state=-trk,action=ct(table=0) priority=100,in_port=1,tcp,ct_state=+trk+new,action=ct(commit,alg=ftp),2 priority=100,in_port=1,tcp,ct_state=+trk+est,action=2 priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,tcp,ct_state=+trk+new+rel,action=ct(commit),1 priority=100,in_port=2,tcp,ct_state=+trk+est,action=1 priority=100,in_port=2,tcp,ct_state=+trk-new+rel,action=1 ]) AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows1.txt]) NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp1.pid]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) dnl FTP requests from p1->p0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NS_CHECK_EXEC([at_ns1], [wget ftp://10.1.1.1 --no-passive-ftp -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl ]) dnl FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp ]) dnl Try the second set of flows. AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows2.txt]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) dnl FTP requests from p1->p0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NS_CHECK_EXEC([at_ns1], [wget ftp://10.1.1.1 --no-passive-ftp -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl ]) dnl Active FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v -o wget0-1.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) dnl Passive FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0-2.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),protoinfo=(state=TIME_WAIT) tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 FTP]) AT_SKIP_IF([test $HAVE_PYFTPDLIB = no]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") dnl Allow any traffic from ns0->ns1. dnl Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl dnl Track all IPv6 traffic and drop the rest. dnl Allow ICMPv6 both ways. No commit, so pings will not be tracked. table=0 priority=100 in_port=1 icmp6, action=2 table=0 priority=100 in_port=2 icmp6, action=1 table=0 priority=10 ip6, action=ct(table=1) table=0 priority=0 action=drop dnl dnl Table 1 dnl dnl Allow new TCPv6 FTP control connections from port 1. table=1 in_port=1 ct_state=+new, tcp6, tp_dst=21, action=ct(alg=ftp,commit),2 dnl Allow related TCPv6 connections from port 2. table=1 in_port=2 ct_state=+new+rel, tcp6, action=ct(commit),1 dnl Allow established TCPv6 connections both ways. table=1 in_port=1 ct_state=+est, tcp6, action=2 table=1 in_port=2 ct_state=+est, tcp6, action=1 dnl Drop everything else. table=1 priority=0, action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) dnl FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://[[fc00::2]] -6 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v --server-response --no-proxy --no-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2) | grep -v "FIN" | grep -v "CLOS"], [0], [dnl tcp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::1,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=fc00::2,dst=fc00::1,sport=,dport=),reply=(src=fc00::1,dst=fc00::2,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP with multiple expectations]) AT_SKIP_IF([test $HAVE_PYFTPDLIB = no]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Dual-firewall, allow all from ns1->ns2, allow established and ftp ns2->ns1. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=10,icmp,action=normal priority=100,in_port=1,tcp,ct_state=-trk,action=ct(table=0,zone=1) priority=100,in_port=1,tcp,ct_zone=1,ct_state=+trk+new,action=ct(commit,alg=ftp,zone=1),ct(commit,alg=ftp,zone=2),2 priority=100,in_port=1,tcp,ct_zone=1,ct_state=+trk+est,action=ct(table=0,zone=2) priority=100,in_port=1,tcp,ct_zone=2,ct_state=+trk+new,action=ct(commit,alg=ftp,zone=2) priority=100,in_port=1,tcp,ct_zone=2,ct_state=+trk+est,action=2 priority=100,in_port=2,tcp,ct_state=-trk,action=ct(table=0,zone=2) priority=100,in_port=2,tcp,ct_zone=2,ct_state=+trk+rel,action=ct(commit,zone=2),ct(commit,zone=1),1 priority=100,in_port=2,tcp,ct_zone=2,ct_state=+trk+est,action=ct(table=0,zone=1) priority=100,in_port=2,tcp,ct_zone=1,ct_state=+trk+rel,action=ct(commit,zone=2),ct(commit,zone=1),1 priority=100,in_port=2,tcp,ct_zone=1,ct_state=+trk+est,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp1.pid]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) dnl FTP requests from p1->p0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NS_CHECK_EXEC([at_ns1], [wget ftp://10.1.1.1 --no-passive-ftp -t 3 -T 1 -v -o wget1.log], [4]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl ]) dnl Active FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=2,protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) tcp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),zone=2,protoinfo=(state=TIME_WAIT) ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) dnl Passive FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=2,protoinfo=(state=TIME_WAIT) tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=2,protoinfo=(state=TIME_WAIT),helper=ftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation ]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") dnl Sending ping through conntrack AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=1,icmp,action=ct(commit,zone=9),2 priority=100,in_port=2,ct_state=-trk,icmp,action=ct(table=0,zone=9) priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 larger fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation expiry]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal dnl Only allow non-fragmented messages and 1st fragments of each message priority=100,in_port=1,icmp,ip_frag=no,action=ct(commit,zone=9),2 priority=100,in_port=1,icmp,ip_frag=firstaction=ct(commit,zone=9),2 priority=100,in_port=2,ct_state=-trk,icmp,action=ct(table=0,zone=9) priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 1 -i 0.3 -w 2 10.1.1.2 | FORMAT_PING], [0], [dnl 7 packets transmitted, 0 received, 100% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation + vlan]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") ADD_VLAN(p0, at_ns0, 100, "10.2.2.1/24") ADD_VLAN(p1, at_ns1, 100, "10.2.2.2/24") dnl Sending ping through conntrack AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=1,icmp,action=ct(commit,zone=9),2 priority=100,in_port=2,ct_state=-trk,icmp,action=ct(table=0,zone=9) priority=100,in_port=2,ct_state=+trk+est-new,icmp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 larger fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.2.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") dnl Sending ping through conntrack AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,in_port=1,ipv6,action=ct(commit,zone=9),2 priority=10,in_port=2,ct_state=-trk,ipv6,action=ct(table=0,zone=9) priority=10,in_port=2,ct_state=+trk+est-new,ipv6,action=1 priority=100,icmp6,icmp_type=135,action=normal priority=100,icmp6,icmp_type=136,action=normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv6 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv6 larger fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation expiry]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") AT_DATA([flows.txt], [dnl priority=1,action=drop dnl Only allow non-fragmented messages and 1st fragments of each message priority=10,in_port=1,ipv6,ip_frag=first,action=ct(commit,zone=9),2 priority=10,in_port=1,ipv6,ip_frag=no,action=ct(commit,zone=9),2 priority=10,in_port=2,ct_state=-trk,ipv6,action=ct(table=0,zone=9) priority=10,in_port=2,ct_state=+trk+est-new,ipv6,action=1 dnl Neighbour Discovery priority=100,icmp6,icmp_type=135,action=normal priority=100,icmp6,icmp_type=136,action=normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Send an IPv6 fragment. Some time later, it should expire. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 1 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 7 packets transmitted, 0 received, 100% packet loss, time 0ms ]) dnl At this point, the kernel will either crash or everything is OK. OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 fragmentation + vlan]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") ADD_VETH(p1, at_ns1, br0, "fc00::2/96") ADD_VLAN(p0, at_ns0, 100, "fc00:1::3/96") ADD_VLAN(p1, at_ns1, 100, "fc00:1::4/96") dnl Sending ping through conntrack AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,in_port=1,ipv6,action=ct(commit,zone=9),2 priority=10,in_port=2,ct_state=-trk,ipv6,action=ct(table=0,zone=9) priority=10,in_port=2,ct_state=+trk+est-new,ipv6,action=1 priority=100,icmp6,icmp_type=135,action=normal priority=100,icmp6,icmp_type=136,action=normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; dnl Basic connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00:1::4 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00:1::4 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv4 larger fragmentation connectivity check. NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00:1::4 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - Fragmentation over vxlan]) OVS_CHECK_VXLAN() CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_BR([br-underlay]) AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"]) ADD_NAMESPACES(at_ns0) dnl Sending ping through conntrack AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,arp,action=normal priority=100,in_port=1,icmp,action=ct(commit,zone=9),LOCAL priority=100,in_port=LOCAL,icmp,action=ct(table=1,zone=9) table=1,priority=100,in_port=LOCAL,ct_state=+trk+est,icmp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Set up underlay link from host into the namespace using veth pair. ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24") AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"]) AT_CHECK([ip link set dev br-underlay up]) dnl Set up tunnel endpoints on OVS outside the namespace and with a native dnl linux device inside the namespace. ADD_OVS_TUNNEL([vxlan], [br0], [at_ns0], [172.31.1.1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], [10.1.1.1/24], [id 0 dstport 4789]) dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Okay, now check the overlay with different packet sizes NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 Fragmentation over vxlan]) AT_SKIP_IF([! ip link help 2>&1 | grep vxlan >/dev/null]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_BR([br-underlay]) AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"]) ADD_NAMESPACES(at_ns0) dnl Sending ping through conntrack AT_DATA([flows.txt], [dnl priority=1,action=drop priority=100,in_port=1,ipv6,action=ct(commit,zone=9),LOCAL priority=100,in_port=LOCAL,ipv6,action=ct(table=1,zone=9) table=1,priority=100,in_port=LOCAL,ct_state=+trk+est,ipv6,action=1 dnl Neighbour Discovery priority=1000,icmp6,icmp_type=135,action=normal priority=1000,icmp6,icmp_type=136,action=normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Set up underlay link from host into the namespace using veth pair. ADD_VETH(p0, at_ns0, br-underlay, "172.31.1.1/24") AT_CHECK([ip addr add dev br-underlay "172.31.1.100/24"]) AT_CHECK([ip link set dev br-underlay up]) dnl Set up tunnel endpoints on OVS outside the namespace and with a native dnl linux device inside the namespace. ADD_OVS_TUNNEL([vxlan], [br0], [at_ns0], [172.31.1.1], ["fc00::2/96"]) ADD_NATIVE_TUNNEL([vxlan], [at_vxlan1], [at_ns0], [172.31.1.100], ["fc00::1/96"], [id 0 dstport 4789]) dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 172.31.1.100 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Okay, now check the overlay with different packet sizes NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00::2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - resubmit to ct multiple times]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START( [set-fail-mode br0 secure -- ]) ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") AT_DATA([flows.txt], [dnl table=0,priority=150,arp,action=normal table=0,priority=100,ip,in_port=1,action=resubmit(,1),resubmit(,2) table=1,priority=100,ip,action=ct(table=3) table=2,priority=100,ip,action=ct(table=3) table=3,ip,action=drop ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) NS_CHECK_EXEC([at_ns0], [ping -q -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl 1 packets transmitted, 0 received, 100% packet loss, time 0ms ]) AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort], [0], [dnl n_packets=1, n_bytes=98, priority=100,ip,in_port=1 actions=resubmit(,1),resubmit(,2) n_packets=2, n_bytes=84, priority=150,arp actions=NORMAL table=1, n_packets=1, n_bytes=98, priority=100,ip actions=ct(table=3) table=2, n_packets=1, n_bytes=98, priority=100,ip actions=ct(table=3) table=3, n_packets=2, n_bytes=196, ip actions=drop NXST_FLOW reply: ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - simple SNAT]) CHECK_CONNTRACK() 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 any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl in_port=1,ip,action=ct(commit,zone=1,nat(src=10.1.1.240-10.1.1.255)),2 in_port=2,ct_state=-trk,ip,action=ct(table=0,zone=1,nat) in_port=2,ct_state=+trk,ct_zone=1,ip,action=1 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]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 5 -T 1 --retry-connrefused -v -o wget0.log]) 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 tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - SNAT with port range]) CHECK_CONNTRACK() 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 any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl in_port=1,tcp,action=ct(commit,zone=1,nat(src=10.1.1.240-10.1.1.255:34567-34568,random)),2 in_port=2,ct_state=-trk,tcp,tp_dst=34567,action=ct(table=0,zone=1,nat) in_port=2,ct_state=-trk,tcp,tp_dst=34568,action=ct(table=0,zone=1,nat) in_port=2,ct_state=+trk,ct_zone=1,tcp,action=1 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]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 5 -T 1 --retry-connrefused -v -o wget0.log]) 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 tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - more complex SNAT]) CHECK_CONNTRACK() 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") AT_DATA([flows.txt], [dnl dnl Track all IP traffic, NAT existing connections. priority=100 ip action=ct(table=1,zone=1,nat) dnl dnl Allow ARP, but generate responses for NATed addresses 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 Allow any traffic from ns0->ns1. SNAT ns0 to 10.1.1.240-10.1.1.255 table=1 priority=100 in_port=1 ip ct_state=+trk+new-est action=ct(commit,zone=1,nat(src=10.1.1.240-10.1.1.255)),2 table=1 priority=100 in_port=1 ip ct_state=+trk-new+est action=2 dnl Only allow established traffic from ns1->ns0. table=1 priority=100 in_port=2 ip ct_state=+trk-new+est action=1 table=1 priority=0 action=drop dnl dnl MAC resolution table for IP in reg2, stores mac in OXM_OF_PKT_REG0 table=8 priority=100 reg2=0x0a0101f0/0xfffffff0 action=load:0x808888888888->OXM_OF_PKT_REG0[[]] dnl Zero result means not found. 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 ARP TPA IP in reg2. table=10 priority=100 arp xreg0=0 action=normal dnl Swaps the fields of the ARP message to turn a query to a response. 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]) dnl HTTP requests from p0->p1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 5 -T 1 --retry-connrefused -v -o wget0.log]) 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 tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - simple DNAT]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address 80:88:88:88:88:88]) dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=100 in_port=1,ip,nw_dst=10.1.1.64,action=ct(zone=1,nat(dst=10.1.1.2),commit),2 priority=10 in_port=1,ip,action=ct(commit,zone=1),2 priority=100 in_port=2,ct_state=-trk,ip,action=ct(table=0,nat,zone=1) priority=100 in_port=2,ct_state=+trk+est,ct_zone=1,ip,action=1 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=0x0a010140,action=load:0x808888888888->OXM_OF_PKT_REG0[[]] dnl Zero result means not found. 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. table=10 priority=100 arp xreg0=0 action=normal dnl Swaps the fields of the ARP message to turn a query to a response. 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]) dnl Should work with the virtual IP address through NAT NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.64) ], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.64,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) dnl Should work with the assigned IP address as well NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) ], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - more complex DNAT]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address 80:88:88:88:88:88]) dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl dnl Track all IP traffic table=0 priority=100 ip action=ct(table=1,zone=1,nat) dnl dnl Allow ARP, but generate responses for NATed addresses table=0 priority=100 arp arp_op=1 action=move:OXM_OF_ARP_TPA[[]]->NXM_NX_REG2[[]],resubmit(,8),goto_table:10 table=0 priority=10 arp action=normal table=0 priority=0 action=drop dnl dnl Allow any IP traffic from ns0->ns1. DNAT ns0 from 10.1.1.64 to 10.1.1.2 table=1 priority=100 in_port=1 ct_state=+new ip nw_dst=10.1.1.64 action=ct(zone=1,nat(dst=10.1.1.2),commit),2 table=1 priority=10 in_port=1 ct_state=+new ip action=ct(commit,zone=1),2 table=1 priority=100 in_port=1 ct_state=+est ct_zone=1 action=2 dnl Only allow established traffic from ns1->ns0. table=1 priority=100 in_port=2 ct_state=+est ct_zone=1 action=1 table=1 priority=0 action=drop dnl dnl MAC resolution table for IP in reg2, stores mac in OXM_OF_PKT_REG0 table=8,reg2=0x0a010140,action=load:0x808888888888->OXM_OF_PKT_REG0[[]] dnl Zero result means not found. 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. table=10 priority=100 arp xreg0=0 action=normal dnl Swaps the fields of the ARP message to turn a query to a response. 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]) dnl Should work with the virtual IP address through NAT NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.64) ], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.64,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) dnl Should work with the assigned IP address as well NS_CHECK_EXEC([at_ns0], [wget 10.1.1.2 -t 3 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) ], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.1,sport=,dport=),zone=1,protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ICMP related with NAT]) CHECK_CONNTRACK() 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 UDP traffic from ns0->ns1. Only allow related ICMP responses back. dnl Make sure ICMP responses are reverse-NATted. AT_DATA([flows.txt], [dnl in_port=1,udp,action=ct(commit,nat(src=10.1.1.240-10.1.1.255),exec(set_field:1->ct_mark)),2 in_port=2,icmp,ct_state=-trk,action=ct(table=0,nat) in_port=2,icmp,nw_dst=10.1.1.1,ct_state=+trk+rel,ct_mark=1,action=1 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]) 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"]) AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl -O OpenFlow15 dump-flows br0 | ofctl_strip | sort | grep -v drop], [0], [dnl n_packets=1, n_bytes=42, priority=10,arp actions=NORMAL n_packets=1, n_bytes=44, udp,in_port=1 actions=ct(commit,nat(src=10.1.1.240-10.1.1.255),exec(set_field:0x1->ct_mark)),output:2 n_packets=1, n_bytes=72, ct_state=+rel+trk,ct_mark=0x1,icmp,in_port=2,nw_dst=10.1.1.1 actions=output:1 n_packets=1, n_bytes=72, ct_state=-trk,icmp,in_port=2 actions=ct(table=0,nat) n_packets=2, n_bytes=84, priority=100,arp,arp_op=1 actions=move:NXM_OF_ARP_TPA[[]]->NXM_NX_REG2[[]],resubmit(,8),goto_table:10 table=10, n_packets=1, n_bytes=42, 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, n_bytes=42, priority=100,arp,reg0=0,reg1=0 actions=NORMAL table=8, n_packets=1, n_bytes=42, priority=0 actions=set_field:0->xreg0 table=8, n_packets=1, n_bytes=42, 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=,dport=),reply=(src=10.1.1.2,dst=10.1.1.2XX,sport=,dport=),mark=1 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP with NAT]) AT_SKIP_IF([test $HAVE_PYFTPDLIB = no]) CHECK_CONNTRACK() 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 any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl dnl track all IP traffic, de-mangle non-NEW connections table=0 in_port=1, ip, action=ct(table=1,nat) table=0 in_port=2, ip, action=ct(table=2,nat) dnl dnl ARP dnl table=0 priority=100 arp arp_op=1 action=move:OXM_OF_ARP_TPA[[]]->NXM_NX_REG2[[]],resubmit(,8),goto_table:10 table=0 priority=10 arp action=normal table=0 priority=0 action=drop dnl dnl Table 1: port 1 -> 2 dnl dnl Allow new FTP connections. These need to be commited. table=1 ct_state=+new, tcp, tp_dst=21, nw_src=10.1.1.1, action=ct(alg=ftp,commit,nat(src=10.1.1.240)),2 dnl Allow established TCP connections, make sure they are NATted already. table=1 ct_state=+est, tcp, nw_src=10.1.1.240, action=2 dnl dnl Table 1: droppers dnl table=1 priority=10, tcp, action=drop table=1 priority=0,action=drop dnl dnl Table 2: port 2 -> 1 dnl dnl Allow established TCP connections, make sure they are reverse NATted table=2 ct_state=+est, tcp, nw_dst=10.1.1.1, action=1 dnl Allow (new) related (data) connections. These need to be commited. table=2 ct_state=+new+rel, tcp, nw_dst=10.1.1.240, action=ct(commit,nat),1 dnl Allow related ICMP packets, make sure they are reverse NATted table=2 ct_state=+rel, icmp, nw_dst=10.1.1.1, action=1 dnl dnl Table 2: droppers dnl table=2 priority=10, tcp, action=drop table=2 priority=0, action=drop dnl dnl MAC resolution table for IP in reg2, stores mac in OXM_OF_PKT_REG0 dnl 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]) dnl NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp1.pid]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) dnl FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 -4 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v --server-response --no-proxy --no-remove-listing -o wget0.log -d]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.240,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=10.1.1.2,dst=10.1.1.240,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP with NAT 2]) AT_SKIP_IF([test $HAVE_PYFTPDLIB = no]) CHECK_CONNTRACK() 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 any traffic from ns0->ns1. dnl Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl dnl track all IP traffic (this includes a helper call to non-NEW packets.) table=0 ip, action=ct(table=1) dnl dnl ARP dnl table=0 priority=100 arp arp_op=1 action=move:OXM_OF_ARP_TPA[[]]->NXM_NX_REG2[[]],resubmit(,8),goto_table:10 table=0 priority=10 arp action=normal table=0 priority=0 action=drop dnl dnl Table 1 dnl dnl Allow new FTP connections. These need to be commited. dnl This does helper for new packets. table=1 in_port=1 ct_state=+new, tcp, tp_dst=21, action=ct(alg=ftp,commit,nat(src=10.1.1.240)),2 dnl Allow and NAT established TCP connections table=1 in_port=1 ct_state=+est, tcp, action=ct(nat),2 table=1 in_port=2 ct_state=+est, tcp, action=ct(nat),1 dnl Allow and NAT (new) related active (data) connections. dnl These need to be commited. table=1 in_port=2 ct_state=+new+rel, tcp, action=ct(commit,nat),1 dnl Allow related ICMP packets. table=1 in_port=2 ct_state=+rel, icmp, action=ct(nat),1 dnl Drop everything else. table=1 priority=0, action=drop dnl dnl MAC resolution table for IP in reg2, stores mac in OXM_OF_PKT_REG0 dnl 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]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) dnl FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 -4 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v --server-response --no-proxy --no-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2) | grep -v "FIN" | grep -v "CLOS"], [0], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=10.1.1.240,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=10.1.1.2,dst=10.1.1.240,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 HTTP with NAT]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") NS_CHECK_EXEC([at_ns0], [ip link set dev p0 address 80:88:88:88:88:88]) ADD_VETH(p1, at_ns1, br0, "fc00::2/96") NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::240 lladdr 80:88:88:88:88:88 dev p1]) dnl Allow any traffic from ns0->ns1. Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl priority=1,action=drop priority=10,icmp6,action=normal priority=100,in_port=1,ip6,action=ct(commit,nat(src=fc00::240)),2 priority=100,in_port=2,ct_state=-trk,ip6,action=ct(nat,table=0) priority=100,in_port=2,ct_state=+trk+est,ip6,action=1 priority=200,in_port=2,ct_state=+trk+new,icmp6,icmpv6_code=0,icmpv6_type=135,nd_target=fc00::240,action=ct(commit,nat(dst=fc00::1)),1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Without this sleep, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" sleep 2; dnl HTTP requests from ns0->ns1 should work fine. NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py http6]], [http0.pid]) NS_CHECK_EXEC([at_ns0], [wget http://[[fc00::2]] -t 3 -T 1 --retry-connrefused -v -o wget0.log]) dnl HTTP requests from ns1->ns0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NETNS_DAEMONIZE([at_ns0], [[$PYTHON $srcdir/test-l7.py http6]], [http1.pid]) NS_CHECK_EXEC([at_ns1], [wget http://[[fc00::1]] -t 3 -T 1 -v -o wget1.log], [4]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 FTP with NAT]) AT_SKIP_IF([test $HAVE_PYFTPDLIB = no]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "fc00::1/96") NS_CHECK_EXEC([at_ns0], [ip link set dev p0 address 80:88:88:88:88:88]) ADD_VETH(p1, at_ns1, br0, "fc00::2/96") dnl Would be nice if NAT could translate neighbor discovery messages, too. NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::240 lladdr 80:88:88:88:88:88 dev p1]) dnl Allow any traffic from ns0->ns1. dnl Only allow nd, return traffic from ns1->ns0. AT_DATA([flows.txt], [dnl dnl Allow other ICMPv6 both ways (without commit). table=1 priority=100 in_port=1 icmp6, action=2 table=1 priority=100 in_port=2 icmp6, action=1 dnl track all IPv6 traffic (this includes NAT & help to non-NEW packets.) table=0 priority=10 ip6, action=ct(nat,table=1) table=0 priority=0 action=drop dnl dnl Table 1 dnl dnl Allow new TCPv6 FTP control connections. table=1 in_port=1 ct_state=+new tcp6 ipv6_src=fc00::1 tp_dst=21 action=ct(alg=ftp,commit,nat(src=fc00::240)),2 dnl Allow related TCPv6 connections from port 2 to the NATted address. table=1 in_port=2 ct_state=+new+rel tcp6 ipv6_dst=fc00::240 action=ct(commit,nat),1 dnl Allow established TCPv6 connections both ways, enforce NATting table=1 in_port=1 ct_state=+est tcp6 ipv6_src=fc00::240 action=2 table=1 in_port=2 ct_state=+est tcp6 ipv6_dst=fc00::1 action=1 dnl Drop everything else. table=1 priority=0, action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) dnl FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://[[fc00::2]] -6 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v --server-response --no-proxy --no-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2) | grep -v "FIN" | grep -v "CLOS"], [0], [dnl tcp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::240,sport=,dport=),protoinfo=(state=TIME_WAIT),helper=ftp tcp,orig=(src=fc00::2,dst=fc00::240,sport=,dport=),reply=(src=fc00::1,dst=fc00::2,sport=,dport=),protoinfo=(state=TIME_WAIT) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP