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 - http 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 ]) OVS_START_L7([at_ns1], [http]) 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([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 - ping between two ports on cvlan]) 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_SVLAN(p0, at_ns0, 4094, "10.255.2.1/24") ADD_SVLAN(p1, at_ns1, 4094, "10.255.2.2/24") ADD_CVLAN(p0.4094, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p1.4094, at_ns1, 100, "10.2.2.2/24") OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) 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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::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 - ping6 between two ports on cvlan]) 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_SVLAN(p0, at_ns0, 4094, "fc00:ffff::1/96") ADD_SVLAN(p1, at_ns1, 4094, "fc00:ffff::2/96") ADD_CVLAN(p0.4094, at_ns0, 100, "fc00:1::1/96") ADD_CVLAN(p1.4094, at_ns1, 100, "fc00:1::2/96") OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::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 bond]) 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_BOND(p1 p2, at_ns1, br0, bond0, lacp=active bond_mode=balance-tcp, "10.1.1.2/24") OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.1.1.2]) 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 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([datapath - ping over vxlan6 tunnel]) OVS_CHECK_VXLAN_UDP6ZEROCSUM() 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, "fc00::1/64", [], [], "nodad") AT_CHECK([ip addr add dev br-underlay "fc00::100/64" nodad]) 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_TUNNEL6([vxlan], [br0], [at_vxlan0], [fc00::1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL6([vxlan], [at_vxlan1], [at_ns0], [fc00::100], [10.1.1.1/24], [id 0 dstport 4789 udp6zerocsumtx udp6zerocsumrx]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::100]) dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::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([datapath - ping over gre tunnel]) OVS_CHECK_GRE() 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([gre], [br0], [at_gre0], [172.31.1.1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL([gretap], [ns_gre0], [at_ns0], [172.31.1.100], [10.1.1.1/24]) 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([datapath - ping over erspan v1 tunnel]) OVS_CHECK_GRE() OVS_CHECK_ERSPAN() 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([erspan], [br0], [at_erspan0], [172.31.1.1], [10.1.1.100/24], [options:key=1 options:erspan_ver=1 options:erspan_idx=7]) ADD_NATIVE_TUNNEL([erspan], [ns_erspan0], [at_ns0], [172.31.1.100], [10.1.1.1/24], [seq key 1 erspan_ver 1 erspan 7]) 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 dnl NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl NS_CHECK_EXEC([at_ns0], [ping -s 1200 -i 0.3 -c 3 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([datapath - ping over erspan v2 tunnel]) OVS_CHECK_GRE() OVS_CHECK_ERSPAN() 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([erspan], [br0], [at_erspan0], [172.31.1.1], [10.1.1.100/24], [options:key=1 options:erspan_ver=2 options:erspan_dir=1 options:erspan_hwid=0x7]) ADD_NATIVE_TUNNEL([erspan], [ns_erspan0], [at_ns0], [172.31.1.100], [10.1.1.1/24], [seq key 1 erspan_ver 2 erspan_dir egress erspan_hwid 7]) 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 dnl NS_CHECK_EXEC([at_ns0], [ping -q -c 3 -i 0.3 -w 2 10.1.1.100 | FORMAT_PING], [0], [dnl NS_CHECK_EXEC([at_ns0], [ping -s 1200 -i 0.3 -c 3 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([datapath - ping over ip6erspan v1 tunnel]) OVS_CHECK_GRE() OVS_CHECK_ERSPAN() 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, "fc00:100::1/96", [], [], nodad) AT_CHECK([ip addr add dev br-underlay "fc00:100::100/96" nodad]) 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_TUNNEL6([ip6erspan], [br0], [at_erspan0], [fc00:100::1], [10.1.1.100/24], [options:key=123 options:erspan_ver=1 options:erspan_idx=0x7]) ADD_NATIVE_TUNNEL6([ip6erspan], [ns_erspan0], [at_ns0], [fc00:100::100], [10.1.1.1/24], [local fc00:100::1 seq key 123 erspan_ver 1 erspan 7]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 2 fc00:100::100]) dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00:100::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 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - ping over ip6erspan v2 tunnel]) OVS_CHECK_GRE() OVS_CHECK_ERSPAN() 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, "fc00:100::1/96", [], [], nodad) AT_CHECK([ip addr add dev br-underlay "fc00:100::100/96" nodad]) 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_TUNNEL6([ip6erspan], [br0], [at_erspan0], [fc00:100::1], [10.1.1.100/24], [options:key=121 options:erspan_ver=2 options:erspan_dir=0 options:erspan_hwid=0x7]) ADD_NATIVE_TUNNEL6([ip6erspan], [ns_erspan0], [at_ns0], [fc00:100::100], [10.1.1.1/24], [local fc00:100::1 seq key 121 erspan_ver 2 erspan_dir ingress erspan_hwid 0x7]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 2 fc00:100::100]) dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00:100::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 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - ping over geneve tunnel]) OVS_CHECK_GENEVE() 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([geneve], [br0], [at_gnv0], [172.31.1.1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL([geneve], [ns_gnv0], [at_ns0], [172.31.1.100], [10.1.1.1/24], [vni 0]) 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([datapath - ping over geneve6 tunnel]) OVS_CHECK_GENEVE_UDP6ZEROCSUM() 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, "fc00::1/64", [], [], "nodad") AT_CHECK([ip addr add dev br-underlay "fc00::100/64" nodad]) 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_TUNNEL6([geneve], [br0], [at_gnv0], [fc00::1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL6([geneve], [ns_gnv0], [at_ns0], [fc00::100], [10.1.1.1/24], [vni 0 udp6zerocsumtx udp6zerocsumrx]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::100]) dnl First, check the underlay NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::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([datapath - clone action]) OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") AT_CHECK([ovs-vsctl -- set interface ovs-p0 ofport_request=1 \ -- set interface ovs-p1 ofport_request=2]) AT_DATA([flows.txt], [dnl priority=1 actions=NORMAL priority=10 in_port=1,ip,actions=clone(mod_dl_dst(50:54:00:00:00:0a),set_field:192.168.3.3->ip_dst), output:2 priority=10 in_port=2,ip,actions=clone(mod_dl_src(ae:c6:7e:54:8d:4d),mod_dl_dst(50:54:00:00:00:0b),set_field:192.168.4.4->ip_dst, controller), output:1 ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl --detach --no-chdir --pidfile 2> ofctl_monitor.log]) 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 ]) AT_CHECK([cat ofctl_monitor.log | STRIP_MONITOR_CSUM], [0], [dnl icmp,vlan_tci=0x0000,dl_src=ae:c6:7e:54:8d:4d,dl_dst=50:54:00:00:00:0b,nw_src=10.1.1.2,nw_dst=192.168.4.4,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=0,icmp_code=0 icmp_csum: icmp,vlan_tci=0x0000,dl_src=ae:c6:7e:54:8d:4d,dl_dst=50:54:00:00:00:0b,nw_src=10.1.1.2,nw_dst=192.168.4.4,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=0,icmp_code=0 icmp_csum: icmp,vlan_tci=0x0000,dl_src=ae:c6:7e:54:8d:4d,dl_dst=50:54:00:00:00:0b,nw_src=10.1.1.2,nw_dst=192.168.4.4,nw_tos=0,nw_ecn=0,nw_ttl=64,icmp_type=0,icmp_code=0 icmp_csum: ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - mpls actions]) OVS_TRAFFIC_VSWITCHD_START([_ADD_BR([br1])]) 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") AT_CHECK([ip link add patch0 type veth peer name patch1]) on_exit 'ip link del patch0' AT_CHECK([ip link set dev patch0 up]) AT_CHECK([ip link set dev patch1 up]) AT_CHECK([ovs-vsctl add-port br0 patch0]) AT_CHECK([ovs-vsctl add-port br1 patch1]) AT_DATA([flows.txt], [dnl table=0,priority=100,dl_type=0x0800 actions=push_mpls:0x8847,set_mpls_label:3,resubmit(,1) table=0,priority=100,dl_type=0x8847,mpls_label=3 actions=pop_mpls:0x0800,resubmit(,1) table=0,priority=10 actions=resubmit(,1) table=1,priority=10 actions=normal ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) AT_CHECK([ovs-ofctl add-flows br1 flows.txt]) 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_ns1], [ping -q -c 3 -i 0.3 -w 2 10.1.1.1 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([datapath - basic truncate action]) AT_SKIP_IF([test $HAVE_NC = no]) OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-ofctl del-flows br0]) dnl Create p0 and ovs-p0(1) ADD_NAMESPACES(at_ns0) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24") NS_CHECK_EXEC([at_ns0], [ip link set dev p0 address e6:66:c1:11:11:11]) NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22]) dnl Create p1(3) and ovs-p1(2), packets received from ovs-p1 will appear in p1 AT_CHECK([ip link add p1 type veth peer name ovs-p1]) on_exit 'ip link del ovs-p1' AT_CHECK([ip link set dev ovs-p1 up]) AT_CHECK([ip link set dev p1 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p1 -- set interface ovs-p1 ofport_request=2]) dnl Use p1 to check the truncated packet AT_CHECK([ovs-vsctl add-port br0 p1 -- set interface p1 ofport_request=3]) dnl Create p2(5) and ovs-p2(4) AT_CHECK([ip link add p2 type veth peer name ovs-p2]) on_exit 'ip link del ovs-p2' AT_CHECK([ip link set dev ovs-p2 up]) AT_CHECK([ip link set dev p2 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p2 -- set interface ovs-p2 ofport_request=4]) dnl Use p2 to check the truncated packet AT_CHECK([ovs-vsctl add-port br0 p2 -- set interface p2 ofport_request=5]) dnl basic test AT_CHECK([ovs-ofctl del-flows br0]) AT_DATA([flows.txt], [dnl in_port=3 dl_dst=e6:66:c1:22:22:22 actions=drop in_port=5 dl_dst=e6:66:c1:22:22:22 actions=drop in_port=1 dl_dst=e6:66:c1:22:22:22 actions=output(port=2,max_len=100),output:4 ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) dnl use this file as payload file for ncat AT_CHECK([dd if=/dev/urandom of=payload200.bin bs=200 count=1 2> /dev/null]) on_exit 'rm -f payload200.bin' NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 1234 < payload200.bin]) dnl packet with truncated size AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=3" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=100 ]) dnl packet with original size AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=5" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=242 ]) dnl more complicated output actions AT_CHECK([ovs-ofctl del-flows br0]) AT_DATA([flows.txt], [dnl in_port=3 dl_dst=e6:66:c1:22:22:22 actions=drop in_port=5 dl_dst=e6:66:c1:22:22:22 actions=drop in_port=1 dl_dst=e6:66:c1:22:22:22 actions=output(port=2,max_len=100),output:4,output(port=2,max_len=100),output(port=4,max_len=100),output:2,output(port=4,max_len=200),output(port=2,max_len=65535) ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 1234 < payload200.bin]) dnl 100 + 100 + 242 + min(65535,242) = 684 AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=3" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=684 ]) dnl 242 + 100 + min(242,200) = 542 AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=5" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=542 ]) dnl SLOW_ACTION: disable kernel datapath truncate support dnl Repeat the test above, but exercise the SLOW_ACTION code path AT_CHECK([ovs-appctl dpif/set-dp-features br0 trunc false], [0]) dnl SLOW_ACTION test1: check datapatch actions AT_CHECK([ovs-ofctl del-flows br0]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) AT_CHECK([ovs-appctl ofproto/trace br0 "in_port=1,dl_type=0x800,dl_src=e6:66:c1:11:11:11,dl_dst=e6:66:c1:22:22:22,nw_src=192.168.0.1,nw_dst=192.168.0.2,nw_proto=6,tp_src=8,tp_dst=9"], [0], [stdout]) AT_CHECK([tail -3 stdout], [0], [Datapath actions: trunc(100),3,5,trunc(100),3,trunc(100),5,3,trunc(200),5,trunc(65535),3 This flow is handled by the userspace slow path because it: - Uses action(s) not supported by datapath. ]) dnl SLOW_ACTION test2: check actual packet truncate AT_CHECK([ovs-ofctl del-flows br0]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 1234 < payload200.bin]) dnl 100 + 100 + 242 + min(65535,242) = 684 AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=3" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=684 ]) dnl 242 + 100 + min(242,200) = 542 AT_CHECK([ovs-ofctl dump-flows br0 table=0 | grep "in_port=5" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=542 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP dnl Create 2 bridges and 2 namespaces to test truncate over dnl GRE tunnel: dnl br0: overlay bridge dnl ns1: connect to br0, with IP:10.1.1.2 dnl br-underlay: with IP: 172.31.1.100 dnl ns0: connect to br-underlay, with IP: 10.1.1.1 AT_SETUP([datapath - truncate and output to gre tunnel]) AT_SKIP_IF([test $HAVE_NC = no]) OVS_CHECK_GRE() OVS_TRAFFIC_VSWITCHD_START() ADD_BR([br-underlay]) ADD_NAMESPACES(at_ns0) ADD_NAMESPACES(at_ns1) AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"]) AT_CHECK([ovs-ofctl add-flow br-underlay "actions=normal"]) 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([gre], [br0], [at_gre0], [172.31.1.1], [10.1.1.100/24]) ADD_NATIVE_TUNNEL([gretap], [ns_gre0], [at_ns0], [172.31.1.100], [10.1.1.1/24], [], [address e6:66:c1:11:11:11]) AT_CHECK([ovs-vsctl -- set interface at_gre0 ofport_request=1]) NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22]) dnl Set up (p1 and ovs-p1) at br0 ADD_VETH(p1, at_ns1, br0, '10.1.1.2/24') AT_CHECK([ovs-vsctl -- set interface ovs-p1 ofport_request=2]) NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address e6:66:c1:22:22:22]) NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e6:66:c1:11:11:11]) dnl Set up (p2 and ovs-p2) as loopback for verifying packet size AT_CHECK([ip link add p2 type veth peer name ovs-p2]) on_exit 'ip link del ovs-p2' AT_CHECK([ip link set dev ovs-p2 up]) AT_CHECK([ip link set dev p2 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p2 -- set interface ovs-p2 ofport_request=3]) AT_CHECK([ovs-vsctl add-port br0 p2 -- set interface p2 ofport_request=4]) dnl use this file as payload file for ncat AT_CHECK([dd if=/dev/urandom of=payload200.bin bs=200 count=1 2> /dev/null]) on_exit 'rm -f payload200.bin' AT_CHECK([ovs-ofctl del-flows br0]) AT_DATA([flows.txt], [dnl priority=99,in_port=1,actions=output(port=2,max_len=100),output(port=3,max_len=100) priority=99,in_port=2,udp,actions=output(port=1,max_len=100) priority=1,in_port=4,ip,actions=drop priority=1,actions=drop ]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) AT_CHECK([ovs-ofctl del-flows br-underlay]) AT_DATA([flows-underlay.txt], [dnl priority=99,dl_type=0x0800,nw_proto=47,in_port=1,actions=LOCAL priority=99,dl_type=0x0800,nw_proto=47,in_port=LOCAL,ip_dst=172.31.1.1/24,actions=1 priority=1,actions=drop ]) AT_CHECK([ovs-ofctl add-flows br-underlay flows-underlay.txt]) dnl check tunnel push path, from at_ns1 to at_ns0 NS_CHECK_EXEC([at_ns1], [nc $NC_EOF_OPT -u 10.1.1.1 1234 < payload200.bin]) AT_CHECK([ovs-appctl revalidator/purge], [0]) dnl Before truncation = ETH(14) + IP(20) + UDP(8) + 200 = 242B AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=2" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=242 ]) dnl After truncation = outer ETH(14) + outer IP(20) + GRE(4) + 100 = 138B AT_CHECK([ovs-ofctl dump-flows br-underlay | grep "in_port=LOCAL" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=138 ]) dnl check tunnel pop path, from at_ns0 to at_ns1 NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 5678 < payload200.bin]) dnl After truncation = 100 byte at loopback device p2(4) AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=4" | ofctl_strip], [0], [dnl n_packets=1, n_bytes=100, priority=1,ip,in_port=4 actions=drop ]) dnl SLOW_ACTION: disable datapath truncate support dnl Repeat the test above, but exercise the SLOW_ACTION code path AT_CHECK([ovs-appctl dpif/set-dp-features br0 trunc false], [0]) dnl SLOW_ACTION test1: check datapatch actions AT_CHECK([ovs-ofctl del-flows br0]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) dnl SLOW_ACTION test2: check actual packet truncate AT_CHECK([ovs-ofctl del-flows br0]) AT_CHECK([ovs-ofctl add-flows br0 flows.txt]) AT_CHECK([ovs-ofctl del-flows br-underlay]) AT_CHECK([ovs-ofctl add-flows br-underlay flows-underlay.txt]) dnl check tunnel push path, from at_ns1 to at_ns0 NS_CHECK_EXEC([at_ns1], [nc $NC_EOF_OPT -u 10.1.1.1 1234 < payload200.bin]) AT_CHECK([ovs-appctl revalidator/purge], [0]) dnl Before truncation = ETH(14) + IP(20) + UDP(8) + 200 = 242B AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=2" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=242 ]) dnl After truncation = outer ETH(14) + outer IP(20) + GRE(4) + 100 = 138B AT_CHECK([ovs-ofctl dump-flows br-underlay | grep "in_port=LOCAL" | sed -n 's/.*\(n\_bytes=[[0-9]]*\).*/\1/p'], [0], [dnl n_bytes=138 ]) dnl check tunnel pop path, from at_ns0 to at_ns1 NS_CHECK_EXEC([at_ns0], [nc $NC_EOF_OPT -u 10.1.1.2 5678 < payload200.bin]) dnl After truncation = 100 byte at loopback device p2(4) AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 | grep "in_port=4" | ofctl_strip], [0], [dnl n_packets=1, n_bytes=100, priority=1,ip,in_port=4 actions=drop ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_BANNER([conntrack]) AT_SETUP([conntrack - controller]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg ofproto_dpif_upcall:dbg]) 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\) '50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000']) dnl OK, now start a new connection from port 1. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 ct\(commit\),controller '50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000']) dnl Now try a reply from port 2. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 ct\(table=0\) '50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000']) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN2 (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_IN2 (xid=0x0): cookie=0x0 total_len=42 ct_state=est|rpl|trk,ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2,ip,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 - force commit]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() AT_CHECK([ovs-appctl vlog/set dpif:dbg dpif_netdev:dbg ofproto_dpif_upcall:dbg]) 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 priority=100,in_port=1,udp,action=ct(force,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=ct(force,commit,table=1) table=1,in_port=2,ct_state=+trk,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 "in_port=2 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000 actions=resubmit(,0)"]) dnl OK, now start a new connection from port 1. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) dnl Now try a reply from port 2. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl revalidator/purge], [0]) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN2 (xid=0x0): cookie=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_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=42 ct_state=new|trk,ct_nw_src=10.1.1.2,ct_nw_dst=10.1.1.1,ct_nw_proto=17,ct_tp_src=2,ct_tp_dst=1,ip,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 ]) dnl dnl Check that the directionality has been changed by force commit. dnl AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.2,"], [], [dnl udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2) ]) dnl OK, now send another packet from port 1 and see that it switches again AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.1,"], [], [dnl udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ct flush by 5-tuple]) 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 priority=100,in_port=1,udp,action=ct(commit),2 priority=100,in_port=2,udp,action=ct(zone=5,commit),1 priority=100,in_port=1,icmp,action=ct(commit),2 priority=100,in_port=2,icmp,action=ct(zone=5,commit),1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Test UDP from port 1 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=1 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101010a0101020001000200080000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.1,"], [], [dnl udp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),reply=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1) ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack 'ct_nw_src=10.1.1.2,ct_nw_dst=10.1.1.1,ct_nw_proto=17,ct_tp_src=2,ct_tp_dst=1']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.1,"], [1], [dnl ]) dnl Test UDP from port 2 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 "in_port=2 packet=50540000000a50540000000908004500001c000000000011a4cd0a0101020a0101010002000100080000 actions=resubmit(,0)"]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.2,"], [0], [dnl udp,orig=(src=10.1.1.2,dst=10.1.1.1,sport=2,dport=1),reply=(src=10.1.1.1,dst=10.1.1.2,sport=1,dport=2),zone=5 ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=5 'ct_nw_src=10.1.1.1,ct_nw_dst=10.1.1.2,ct_nw_proto=17,ct_tp_src=1,ct_tp_dst=2']) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl ]) dnl Test ICMP traffic NS_CHECK_EXEC([at_ns1], [ping -q -c 3 -i 0.3 -w 2 10.1.1.1 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.2,"], [0], [stdout]) AT_CHECK([cat stdout | FORMAT_CT(10.1.1.1)], [0],[dnl icmp,orig=(src=10.1.1.2,dst=10.1.1.1,id=,type=8,code=0),reply=(src=10.1.1.1,dst=10.1.1.2,id=,type=0,code=0),zone=5 ]) ICMP_ID=`cat stdout | cut -d ',' -f4 | cut -d '=' -f2` ICMP_TUPLE=ct_nw_src=10.1.1.2,ct_nw_dst=10.1.1.1,ct_nw_proto=1,icmp_id=$ICMP_ID,icmp_type=8,icmp_code=0 AT_CHECK([ovs-appctl dpctl/flush-conntrack zone=5 $ICMP_TUPLE]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep "orig=.src=10\.1\.1\.2,"], [1], [dnl ]) OVS_TRAFFIC_VSWITCHD_STOP(["/could not create datapath/d"]) AT_CLEANUP AT_SETUP([conntrack - IPv4 ping]) 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,icmp,action=ct(commit),2 priority=100,in_port=2,icmp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,icmp,ct_state=+trk+est,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Pings from ns0->ns1 should work fine. 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 ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0) ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) dnl Pings from ns1->ns0 should fail. NS_CHECK_EXEC([at_ns1], [ping -q -c 3 -i 0.3 -w 2 10.1.1.1 | FORMAT_PING], [0], [dnl 7 packets transmitted, 0 received, 100% packet loss, time 0ms ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - get_nconns and get/set_maxconns]) CHECK_CONNTRACK() CHECK_CT_DPIF_SET_GET_MAXCONNS() CHECK_CT_DPIF_GET_NCONNS() 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,icmp,action=ct(commit),2 priority=100,in_port=2,icmp,ct_state=-trk,action=ct(table=0) priority=100,in_port=2,icmp,ct_state=+trk+est,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Pings from ns0->ns1 should work fine. 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 ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [0], [dnl icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0) ]) AT_CHECK([ovs-appctl dpctl/ct-set-maxconns one-bad-dp], [2], [], [dnl ovs-vswitchd: maxconns missing or malformed (Invalid argument) ovs-appctl: ovs-vswitchd: server returned an error ]) AT_CHECK([ovs-appctl dpctl/ct-set-maxconns a], [2], [], [dnl ovs-vswitchd: maxconns missing or malformed (Invalid argument) ovs-appctl: ovs-vswitchd: server returned an error ]) AT_CHECK([ovs-appctl dpctl/ct-set-maxconns one-bad-dp 10], [2], [], [dnl ovs-vswitchd: opening datapath (Address family not supported by protocol) ovs-appctl: ovs-vswitchd: server returned an error ]) AT_CHECK([ovs-appctl dpctl/ct-get-maxconns one-bad-dp], [2], [], [dnl ovs-vswitchd: opening datapath (Address family not supported by protocol) ovs-appctl: ovs-vswitchd: server returned an error ]) AT_CHECK([ovs-appctl dpctl/ct-get-nconns one-bad-dp], [2], [], [dnl ovs-vswitchd: opening datapath (Address family not supported by protocol) ovs-appctl: ovs-vswitchd: server returned an error ]) AT_CHECK([ovs-appctl dpctl/ct-get-nconns], [], [dnl 1 ]) AT_CHECK([ovs-appctl dpctl/ct-get-maxconns], [], [dnl 3000000 ]) AT_CHECK([ovs-appctl dpctl/ct-set-maxconns 10], [], [dnl setting maxconns successful ]) AT_CHECK([ovs-appctl dpctl/ct-get-maxconns], [], [dnl 10 ]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) AT_CHECK([ovs-appctl dpctl/ct-get-nconns], [], [dnl 0 ]) AT_CHECK([ovs-appctl dpctl/ct-get-maxconns], [], [dnl 10 ]) OVS_TRAFFIC_VSWITCHD_STOP(["/could not create datapath one-bad-dp of unknown type system/d"]) AT_CLEANUP AT_SETUP([conntrack - IPv6 ping]) 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 dnl ICMPv6 echo request and reply go to table 1. The rest of the traffic goes dnl through normal action. table=0,priority=10,icmp6,icmp_type=128,action=goto_table:1 table=0,priority=10,icmp6,icmp_type=129,action=goto_table:1 table=0,priority=1,action=normal dnl Allow everything from ns0->ns1. Only allow return traffic from ns1->ns0. table=1,priority=100,in_port=1,icmp6,action=ct(commit),2 table=1,priority=100,in_port=2,icmp6,ct_state=-trk,action=ct(table=0) table=1,priority=100,in_port=2,icmp6,ct_state=+trk+est,action=1 table=1,priority=1,action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) dnl The above ping creates state in the connection tracker. We're not dnl interested in that state. AT_CHECK([ovs-appctl dpctl/flush-conntrack]) dnl Pings from ns1->ns0 should fail. NS_CHECK_EXEC([at_ns1], [ping6 -q -c 3 -i 0.3 -w 2 fc00::1 | FORMAT_PING], [0], [dnl 7 packets transmitted, 0 received, 100% packet loss, time 0ms ]) dnl Pings from ns0->ns1 should work fine. 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 ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl icmpv6,orig=(src=fc00::1,dst=fc00::2,id=,type=128,code=0),reply=(src=fc00::2,dst=fc00::1,id=,type=129,code=0) ]) 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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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]) dnl HTTP requests from p2->p3 should work fine. 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. OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) 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. 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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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=) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. 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=) ]) 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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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=4097,protoinfo=(state=) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. 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=) ]) 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. OVS_START_L7([at_ns1], [http]) 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]) OVS_START_L7([at_ns1], [http]) dnl 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]) 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=) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - multiple namespaces, internal ports]) CHECK_CONNTRACK() CHECK_CONNTRACK_LOCAL_STACK() 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]) OVS_START_L7([at_ns1], [http]) dnl 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]) 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=) ]) 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 - 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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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=),mark=1,protoinfo=(state=) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ct_mark bit-fiddling]) 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") dnl Allow traffic between ns0<->ns1 using the ct_mark. Return traffic should dnl cause an additional bit to be set in the connection (and be allowed). AT_DATA([flows.txt], [dnl table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal table=0,priority=100,in_port=1,tcp,action=ct(table=1) table=0,priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=1,commit,exec(set_field:0x2/0x6->ct_mark)) table=1,in_port=1,ct_state=+new,tcp,action=ct(commit,exec(set_field:0x5/0x5->ct_mark)),2 table=1,in_port=1,ct_state=-new,tcp,action=2 table=1,in_port=2,ct_state=+trk,ct_mark=3,tcp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_START_L7([at_ns1], [http]) dnl 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=),mark=3,protoinfo=(state=) ]) 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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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=),mark=1,protoinfo=(state=) ]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. 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=) ]) 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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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]) dnl HTTP requests from p2->p3 should fail due to network failure. dnl Try 3 times, in 1 second intervals. 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 - ct_label bit-fiddling]) 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") dnl Allow traffic between ns0<->ns1 using the ct_labels. Return traffic should dnl cause an additional bit to be set in the connection labels (and be allowed) AT_DATA([flows.txt], [dnl table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal table=0,priority=100,in_port=1,tcp,action=ct(table=1) table=0,priority=100,in_port=2,ct_state=-trk,tcp,action=ct(table=1,commit,exec(set_field:0x200000000/0x200000004->ct_label)) table=1,in_port=1,tcp,ct_state=+new,action=ct(commit,exec(set_field:0x5/0x5->ct_label)),2 table=1,in_port=1,tcp,ct_state=-new,action=2 table=1,in_port=2,ct_state=+trk,ct_label=0x200000001,tcp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_START_L7([at_ns1], [http]) dnl 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=),labels=0x200000001,protoinfo=(state=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ct metadata, multiple 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") dnl Allow traffic between ns0<->ns1 using the ct_mark and ct_labels in zone=1, dnl but do *not* set any of these for the ct() in zone=2. Traffic should pass, dnl and we should see that the conntrack entries only apply the ct_mark and dnl ct_labels to the connection in zone=1. AT_DATA([flows.txt], [dnl table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal table=0,priority=100,in_port=1,tcp,action=ct(zone=1,table=1) table=0,priority=100,in_port=2,ct_state=-trk,tcp,action=ct(zone=1,table=1,commit,exec(set_field:0x200000000/0x200000004->ct_label,set_field:0x2/0x6->ct_mark)) table=1,in_port=1,tcp,ct_state=+new,action=ct(zone=1,commit,exec(set_field:0x5/0x5->ct_label,set_field:0x5/0x5->ct_mark)),ct(commit,zone=2),2 table=1,in_port=1,tcp,ct_state=-new,action=ct(zone=2),2 table=1,in_port=2,tcp,action=ct(zone=2),1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_START_L7([at_ns1], [http]) dnl 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,mark=3,labels=0x200000001,protoinfo=(state=) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ICMP related]) AT_SKIP_IF([test $HAVE_NC = 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 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 to original direction]) AT_SKIP_IF([test $HAVE_NC = 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 UDP traffic from ns0->ns1. Only allow related ICMP responses back. AT_DATA([flows.txt], [dnl priority=1000,arp,action=normal priority=100,ip,action=ct(table=1) priority=1,action=drop table=1,ip,action=ct(zone=34673,table=2) table=2,in_port=2,udp,action=ct(commit,zone=34673),1 table=2,in_port=1,udp,action=ct(commit,zone=34673),2 table=2,in_port=2,ct_state=+rel,icmp,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl 1. Send and UDP packet to port 53 (src=192.100.1.8,dst=192.100.2.5) AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 resubmit\(,0\) '00010200020400232211223308004500001c000100004011f6fac0640108c06402050035003500087b9e']) dnl 2. Send and UDP packet to port 53 (src=192.100.2.5,dst=192.100.1.8) AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 resubmit\(,0\) '00232211223300010200020408004500001c000100004011f6fac0640205c06401080035003500087b9e']) dnl 3. Send an ICMP port unreach reply for port 53, related to the 2nd dnl packet, but in the original direction of the conntrack entry created dnl for the 1st packet. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 resubmit\(,0\) '000102000204002322112233080045000038000100003f01f7eec0640108c0640205030a80e5ffffffff4500001c000100003f11f7fac0640205c06401080035003500087b9e']) AT_CHECK([ovs-appctl revalidator/purge], [0]) dnl 4. Repeat 3. AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 resubmit\(,0\) '000102000204002322112233080045000038000100003f01f7eec0640108c0640205030a80e5ffffffff4500001c000100003f11f7fac0640205c06401080035003500087b9e']) AT_CHECK([ovs-appctl revalidator/purge], [0]) AT_CHECK([ovs-ofctl dump-flows br0 | ofctl_strip | sort | grep -v drop], [0], [dnl n_packets=4, n_bytes=224, priority=100,ip actions=ct(table=1) priority=1000,arp actions=NORMAL table=1, n_packets=4, n_bytes=224, ip actions=ct(table=2,zone=34673) table=2, n_packets=1, n_bytes=42, udp,in_port=1 actions=ct(commit,zone=34673),output:2 table=2, n_packets=1, n_bytes=42, udp,in_port=2 actions=ct(commit,zone=34673),output:1 table=2, n_packets=2, n_bytes=140, ct_state=+rel,icmp,in_port=2 actions=output:1 NXST_FLOW reply: ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(192.100.1.8)], [0], [dnl udp,orig=(src=192.100.1.8,dst=192.100.2.5,sport=,dport=),reply=(src=192.100.2.5,dst=192.100.1.8,sport=,dport=),zone=34673 ]) 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 table=0,ip,action=ct(commit,table=1) table=1,ip,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 resubmit\(,0\) 'f64c473528c9c6f54ecb72db080045c0003d2e8700004001f351ac100004ac1000030303da490000000045000021317040004011b138ac100003ac10000411112222000d20966369616f0a']) dnl 2. Send and UDP packet to port 5555 AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 1 resubmit\(,0\) 'c6f94ecb72dbe64c473528c9080045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a']) dnl 3. Send an ICMP port unreach reply from a path midpoint for port 5555, related to the first packet AT_CHECK([ovs-ofctl -O OpenFlow13 packet-out br0 2 resubmit\(,0\) 'e64c473528c9c6f94ecb72db080045c0003d2e8700004001f354ac100003ac1000010303553f0000000045000021317040004011b138ac100001ac100002a28e15b3000d20966369616f0a']) dnl Check this output. We only see the latter two packets, not the first. AT_CHECK([cat ofctl_monitor.log], [0], [dnl NXT_PACKET_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=75 ct_state=inv|trk,ip,in_port=2 (via action) data_len=75 (unbuffered) icmp,vlan_tci=0x0000,dl_src=c6:f5:4e:cb:72:db,dl_dst=f6:4c:47:35:28:c9,nw_src=172.16.0.4,nw_dst=172.16.0.3,nw_tos=192,nw_ecn=0,nw_ttl=64,icmp_type=3,icmp_code=3 icmp_csum:da49 NXT_PACKET_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=47 ct_state=new|trk,ct_nw_src=172.16.0.1,ct_nw_dst=172.16.0.2,ct_nw_proto=17,ct_tp_src=41614,ct_tp_dst=5555,ip,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_IN2 (xid=0x0): table_id=1 cookie=0x0 total_len=75 ct_state=rel|rpl|trk,ct_nw_src=172.16.0.1,ct_nw_dst=172.16.0.2,ct_nw_proto=17,ct_tp_src=41614,ct_tp_dst=5555,ip,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.3,nw_dst=172.16.0.1,nw_tos=192,nw_ecn=0,nw_ttl=64,icmp_type=3,icmp_code=3 icmp_csum:553f ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.0.1)], [0], [dnl udp,orig=(src=172.16.0.1,dst=172.16.0.2,sport=,dport=),reply=(src=172.16.0.2,dst=172.16.0.1,sport=,dport=) ]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(172.16.0.3)], [0], [dnl ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 fragmentation]) CHECK_CONNTRACK() CHECK_CONNTRACK_FRAG() 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 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() CHECK_CONNTRACK_FRAG() 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 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() CHECK_CONNTRACK_FRAG() 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 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 - IPv4 fragmentation + cvlan]) CHECK_CONNTRACK() CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() 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_SVLAN(p0, at_ns0, 4094, "10.255.2.1/24") ADD_SVLAN(p1, at_ns1, 4094, "10.255.2.2/24") ADD_CVLAN(p0.4094, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p1.4094, 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]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) 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 fragmentation connectivity check. (outer svlan) NS_CHECK_EXEC([at_ns0], [ping -s 1600 -q -c 3 -i 0.3 -w 2 10.255.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 ]) dnl Ipv4 larger fragmentation connectivity check. (outer svlan) NS_CHECK_EXEC([at_ns0], [ping -s 3200 -q -c 3 -i 0.3 -w 2 10.255.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() CHECK_CONNTRACK_FRAG() 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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) 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() CHECK_CONNTRACK_FRAG() 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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) 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() CHECK_CONNTRACK_FRAG() 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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) 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 - IPv6 fragmentation + cvlan]) CHECK_CONNTRACK() CHECK_CONNTRACK_FRAG() OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() 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_SVLAN(p0, at_ns0, 4094, "fc00:ffff::3/96") ADD_SVLAN(p1, at_ns1, 4094, "fc00:ffff::4/96") ADD_CVLAN(p0.4094, at_ns0, 100, "fc00:1::3/96") ADD_CVLAN(p1.4094, 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]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00:1::4]) dnl Ipv6 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 Ipv6 fragmentation connectivity check. (outer svlan) NS_CHECK_EXEC([at_ns0], [ping6 -s 1600 -q -c 3 -i 0.3 -w 2 fc00:ffff::4 | 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:1::4 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Ipv6 larger fragmentation connectivity check. (outer svlan) NS_CHECK_EXEC([at_ns0], [ping6 -s 3200 -q -c 3 -i 0.3 -w 2 fc00:ffff::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() CHECK_CONNTRACK_FRAG() 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,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_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 - IPv6 Fragmentation over vxlan]) OVS_CHECK_VXLAN() CHECK_CONNTRACK() CHECK_CONNTRACK_FRAG() 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,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_vxlan0], [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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::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,ip,action=ct(table=3) table=2,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, ip actions=ct(table=3) table=2, n_packets=1, n_bytes=98, 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_BANNER([conntrack - L7]) 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]) OVS_START_L7([at_ns0], [http]) OVS_START_L7([at_ns1], [http]) dnl HTTP requests from ns0->ns1 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=),protoinfo=(state=) ]) dnl HTTP requests from ns1->ns0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NS_CHECK_EXEC([at_ns1], [wget 10.1.1.1 -t 3 -T 1 --retry-connrefused -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 Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) OVS_START_L7([at_ns0], [http6]) OVS_START_L7([at_ns1], [http6]) dnl HTTP requests from ns0->ns1 should work fine. 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=) ]) dnl HTTP requests from ns1->ns0 should fail due to network failure. dnl Try 3 times, in 1 second intervals. NS_CHECK_EXEC([at_ns1], [wget http://[[fc00::1]] -t 3 -T 1 --retry-connrefused -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]) OVS_START_L7([at_ns1], [http]) OVS_START_L7([at_ns3], [http]) dnl 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]) dnl HTTP requests from p2->p3 should work fine. 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 - multiple zones, local]) CHECK_CONNTRACK() CHECK_CONNTRACK_LOCAL_STACK() 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,in_port=1,ip,ct_state=+trk+est,ct_zone=1,action=ct(table=2,zone=2) table=2,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 ]) OVS_START_L7([at_ns0], [http]) dnl 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]) 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=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0),zone=1 icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0),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=) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - multi-stage pipeline, local]) CHECK_CONNTRACK() CHECK_CONNTRACK_LOCAL_STACK() 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,table=2,zone=OXM_OF_IN_PORT[[0..15]]) 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,table=4,zone=NXM_NX_REG0[[0..15]]) 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 ]) OVS_START_L7([at_ns0], [http]) dnl 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]) 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=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0),zone=1 icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.1,id=,type=0,code=0),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=) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([FTP - no conntrack]) AT_SKIP_IF([test $HAVE_FTP = no]) 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 table=0,action=normal ]) AT_CHECK([ovs-ofctl --bundle replace-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]) OVS_WAIT_UNTIL([ip netns exec at_ns1 netstat -l | grep ftp]) 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([find -name index.html], [0], [dnl ./index.html ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_ALG() 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 table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal table=0,priority=100,in_port=1,tcp,action=ct(alg=ftp,commit),2 table=0,priority=100,in_port=2,tcp,action=ct(table=1) table=1,in_port=2,tcp,ct_state=+trk+est,action=1 table=1,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 table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal dnl Allow outgoing TCP connections, and treat them as FTP table=0,priority=100,in_port=1,tcp,action=ct(table=1) table=1,in_port=1,tcp,ct_state=+trk+new,action=ct(commit,alg=ftp),2 table=1,in_port=1,tcp,ct_state=+trk+est,action=2 dnl Allow incoming FTP data connections and responses to existing connections table=0,priority=100,in_port=2,tcp,action=ct(table=1) table=1,in_port=2,tcp,ct_state=+trk+new+rel,action=ct(commit),1 table=1,in_port=2,tcp,ct_state=+trk+est,action=1 table=1,in_port=2,tcp,ct_state=+trk-new+rel,action=1 ]) dnl flows3 is same as flows1, except no ALG is specified. AT_DATA([flows3.txt], [dnl table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal table=0,priority=100,in_port=1,tcp,action=ct(commit),2 table=0,priority=100,in_port=2,tcp,action=ct(table=1) table=1,in_port=2,tcp,ct_state=+trk+est,action=1 table=1,in_port=2,tcp,ct_state=+trk+rel,action=1 ]) AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows1.txt]) OVS_START_L7([at_ns0], [ftp]) OVS_START_L7([at_ns1], [ftp]) 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)], [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=),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)], [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=),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=) ]) 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)], [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=),helper=ftp ]) dnl Try the third set of flows, without alg specifier. AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows3.txt]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) dnl FTP control requests from p0->p1 should work fine, but helper will not be assigned. NS_CHECK_EXEC([at_ns0], [wget ftp://10.1.1.2 --no-passive-ftp -t 3 -T 1 --retry-connrefused -v -o wget0-3.log], [4]) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP over IPv6]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_ALG() 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]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2 >/dev/null]) OVS_START_L7([at_ns1], [ftp]) 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-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING 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=),helper=ftp tcp,orig=(src=fc00::2,dst=fc00::1,sport=,dport=),reply=(src=fc00::1,dst=fc00::2,sport=,dport=),protoinfo=(state=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 FTP Passive]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_ALG() 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 link set dev p1 address 80:88:88:88:88:99]) NS_CHECK_EXEC([at_ns0], [ip -6 neigh add fc00::2 lladdr 80:88:88:88:88:99 dev p0]) NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::1 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 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 1. table=1 in_port=1 ct_state=+new+rel, tcp6, action=ct(commit),2 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]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2 >/dev/null]) OVS_START_L7([at_ns1], [ftp]) dnl FTP passive requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://[[fc00::2]] -6 -t 3 -T 1 --retry-connrefused -v --server-response --no-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING 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=) tcp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::1,sport=,dport=),protoinfo=(state=),helper=ftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - FTP with multiple expectations]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_ALG() 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 table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal dnl Traffic from ns1 table=0,priority=100,in_port=1,tcp,action=ct(table=1,zone=1) table=1,in_port=1,tcp,ct_zone=1,ct_state=+trk+new-rel,action=ct(commit,alg=ftp,zone=1),ct(commit,alg=ftp,zone=2),2 table=1,in_port=1,tcp,ct_zone=1,ct_state=+trk+new+rel,action=ct(commit,zone=1),ct(commit,zone=2),2 table=1,in_port=1,tcp,ct_zone=1,ct_state=+trk+est,action=ct(table=2,zone=2) table=2,in_port=1,tcp,ct_zone=2,ct_state=+trk+est,action=2 dnl Traffic from ns2 table=0,priority=100,in_port=2,tcp,action=ct(table=1,zone=2) table=1,in_port=2,tcp,ct_zone=2,ct_state=+trk+rel,action=ct(commit,zone=2),ct(commit,zone=1),1 table=1,in_port=2,tcp,ct_zone=2,ct_state=+trk+est,action=ct(table=2,zone=1) table=2,in_port=2,tcp,ct_zone=1,ct_state=+trk+rel,action=ct(commit,zone=2),ct(commit,zone=1),1 table=2,in_port=2,tcp,ct_zone=1,ct_state=+trk+est,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_START_L7([at_ns0], [ftp]) OVS_START_L7([at_ns1], [ftp]) 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)], [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=),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=),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=) 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=) ]) 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)], [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=) 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=),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=) 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=),helper=ftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - TFTP]) AT_SKIP_IF([test $HAVE_TFTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_ALG() 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 table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal table=0,priority=100,in_port=1,udp,action=ct(alg=tftp,commit),2 table=0,priority=100,in_port=2,udp,action=ct(table=1) table=1,in_port=2,udp,ct_state=+trk+est,action=1 table=1,in_port=2,udp,ct_state=+trk+rel,action=1 ]) dnl Similar policy but without allowing all traffic from ns0->ns1. AT_DATA([flows2.txt], [dnl table=0,priority=1,action=drop table=0,priority=10,arp,action=normal table=0,priority=10,icmp,action=normal dnl Allow outgoing UDP connections, and treat them as TFTP table=0,priority=100,in_port=1,udp,action=ct(table=1) table=1,in_port=1,udp,ct_state=+trk+new-rel,action=ct(commit,alg=tftp),2 table=1,in_port=1,udp,ct_state=+trk+new+rel,action=ct(commit),2 table=1,in_port=1,udp,ct_state=+trk+est,action=2 dnl Allow incoming TFTP data connections and responses to existing connections table=0,priority=100,in_port=2,udp,action=ct(table=1) table=1,in_port=2,udp,ct_state=+trk+est,action=1 table=1,in_port=2,udp,ct_state=+trk+new+rel,action=1 ]) AT_CHECK([ovs-ofctl --bundle replace-flows br0 flows1.txt]) OVS_START_L7([at_ns0], [tftp]) OVS_START_L7([at_ns1], [tftp]) dnl TFTP requests from p1->p0 should fail due to network failure. NS_CHECK_EXEC([at_ns1], [[curl $CURL_OPT tftp://10.1.1.1/flows1.txt -o foo 2>curl0.log]], [28]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl ]) dnl TFTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [[curl $CURL_OPT tftp://10.1.1.2/flows1.txt -o foo 2>curl1.log]]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [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.1,sport=,dport=),helper=tftp ]) 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 TFTP requests from p1->p0 should fail due to network failure. NS_CHECK_EXEC([at_ns1], [[curl $CURL_OPT tftp://10.1.1.1/flows1.txt -o foo 2>curl2.log]], [28]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.1)], [0], [dnl ]) dnl TFTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [[curl $CURL_OPT tftp://10.1.1.2/flows1.txt -o foo 2>curl3.log]]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [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.1,sport=,dport=),helper=tftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_BANNER([conntrack - NAT]) AT_SETUP([conntrack - simple SNAT]) 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 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. OVS_START_L7([at_ns1], [http]) 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/' | uniq], [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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - SNAT with ct_mark change on reply]) 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 e6:66:c1:11:11:11]) NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22]) ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address e6:66:c1:22:22:22]) NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.240 e6:66:c1:11:11:11]) 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)),2 in_port=2,ct_state=-trk,ip,action=ct(table=0,zone=1,nat) dnl dnl Setting the mark fails if the datapath can't find the existing conntrack dnl entry after NAT has been reversed and the skb was lost due to an upcall. dnl in_port=2,ct_state=+trk,ct_zone=1,ip,action=ct(table=1,commit,zone=1,exec(set_field:1->ct_mark)),1 table=1,in_port=2,ct_mark=1,ct_state=+rpl,ct_zone=1,ip,action=1 dnl priority=0,action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl ICMP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [ping -c 1 10.1.1.2 | FORMAT_PING], [0], [dnl 1 packets transmitted, 1 received, 0% packet loss, time 0ms ]) 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 icmp,orig=(src=10.1.1.1,dst=10.1.1.2,id=,type=8,code=0),reply=(src=10.1.1.2,dst=10.1.1.2XX,id=,type=0,code=0),zone=1,mark=1 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - SNAT with port range]) 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 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. OVS_START_L7([at_ns1], [http]) 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/' | uniq], [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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - more complex SNAT]) 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") 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. OVS_START_L7([at_ns1], [http]) 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/' | uniq], [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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - simple DNAT]) 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") 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 OVS_START_L7([at_ns1], [http]) 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=) ]) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - more complex DNAT]) 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") 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 OVS_START_L7([at_ns1], [http]) 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=) ]) 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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - ICMP related with NAT]) AT_SKIP_IF([test $HAVE_NC = no]) AT_SKIP_IF([test $HAVE_TCPDUMP = no]) 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 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]) rm p0.pcap tcpdump -U -i ovs-p0 -w p0.pcap & 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"]) 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 ]) AT_CHECK([tcpdump -v "icmp" -r p0.pcap 2>/dev/null | egrep '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 dnl NAT, using the provided flow table. m4_define([CHECK_FTP_NAT], [AT_SETUP([conntrack - FTP NAT $1]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() 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], [$3]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) OVS_START_L7([at_ns1], [ftp]) 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-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)], [0], [$4]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP]) dnl CHECK_FTP_NAT_PRE_RECIRC(TITLE, IP_ADDR, IP_ADDR_AS_HEX) dnl dnl Checks the implementation of conntrack with FTP ALGs in combination with dnl NAT, with flow tables that implement the NATing as part of handling of dnl initial incoming packets - ie, the first flow is ct(nat,table=foo). dnl dnl IP_ADDR must specify the NAT address in standard "10.1.1.x" format, dnl and IP_ADDR_AS_HEX must specify the same address as hex, eg 0x0a0101xx. m4_define([CHECK_FTP_NAT_PRE_RECIRC], [dnl CHECK_FTP_NAT([prerecirc $1], [$2], [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=$2)),2 dnl Allow established TCP connections, make sure they are NATted already. table=1 ct_state=+est, tcp, nw_src=$2, 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=$2, 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=$3/0xffffffff,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 ], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=$2,sport=,dport=),protoinfo=(state=),helper=ftp tcp,orig=(src=10.1.1.2,dst=$2,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),protoinfo=(state=) ]) ]) dnl Check that ct(nat,table=foo) works without TCP sequence adjustment. CHECK_FTP_NAT_PRE_RECIRC([], [10.1.1.9], [0x0a010109]) dnl Check that ct(nat,table=foo) works with TCP sequence adjustment. dnl dnl The FTP PORT command includes the ASCII representation of the address, dnl so when these messages need to be NATed between addresses that have dnl different lengths when represented in ASCII (such as the original address dnl of 10.1.1.1 used in the test and 10.1.1.240 here), the FTP NAT ALG must dnl resize the packet and adjust TCP sequence numbers. This test is kept dnl separate from the above to easier identify issues in this code on different dnl kernels. CHECK_FTP_NAT_PRE_RECIRC([seqadj], [10.1.1.240], [0x0a0101f0]) dnl CHECK_FTP_NAT_POST_RECIRC(TITLE, IP_ADDR, IP_ADDR_AS_HEX) dnl dnl Checks the implementation of conntrack with FTP ALGs in combination with dnl NAT, with flow tables that implement the NATing after the first round dnl of recirculation - that is, the first flow ct(table=foo) then a subsequent dnl flow will implement the NATing with ct(nat..),output:foo. dnl dnl IP_ADDR must specify the NAT address in standard "10.1.1.x" format, dnl and IP_ADDR_AS_HEX must specify the same address as hex, eg 0x0a0101xx. m4_define([CHECK_FTP_NAT_POST_RECIRC], [dnl CHECK_FTP_NAT([postrecirc $1], [$2], [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=$2)),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=$3/0xffffffff,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 ], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=$2,sport=,dport=),protoinfo=(state=),helper=ftp tcp,orig=(src=10.1.1.2,dst=$2,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),protoinfo=(state=) ]) ]) dnl Check that ct(nat,table=foo) works without TCP sequence adjustment. CHECK_FTP_NAT_POST_RECIRC([], [10.1.1.9], [0x0a010109]) dnl Check that ct(nat,table=foo) works with TCP sequence adjustment. dnl dnl The FTP PORT command includes the ASCII representation of the address, dnl so when these messages need to be NATed between addresses that have dnl different lengths when represented in ASCII (such as the original address dnl of 10.1.1.1 used in the test and 10.1.1.240 here), the FTP NAT ALG must dnl resize the packet and adjust TCP sequence numbers. This test is kept dnl separate from the above to easier identify issues in this code on different dnl kernels. CHECK_FTP_NAT_POST_RECIRC([seqadj], [10.1.1.240], [0x0a0101f0]) dnl CHECK_FTP_NAT_ORIG_TUPLE(TITLE, IP_ADDR, IP_ADDR_AS_HEX) dnl dnl Checks the implementation of conntrack original direction tuple matching dnl with FTP ALGs in combination with NAT, with flow tables that implement dnl the NATing before the first round of recirculation - that is, the first dnl flow ct(nat, table=foo) then a subsequent flow will implement the dnl commiting of NATed and other connections with ct(nat..),output:foo. dnl dnl IP_ADDR must specify the NAT address in standard "10.1.1.x" format, dnl and IP_ADDR_AS_HEX must specify the same address as hex, eg 0x0a0101xx. m4_define([CHECK_FTP_NAT_ORIG_TUPLE], [dnl CHECK_FTP_NAT([orig tuple $1], [$2], [dnl dnl Store zone in reg4 and packet direction in reg3 (IN=1, OUT=2). dnl NAT is only applied to OUT-direction packets, so that ACL dnl processing can be done with non-NATted headers. dnl dnl Track all IP traffic in the IN-direction (IN from Port 1). table=0 in_port=1, ip, action=set_field:1->reg4,set_field:1->reg3,ct(zone=NXM_NX_REG4[[0..15]],table=1) dnl Track all IP traffic in the OUT-direction (OUT to the Port 1). table=0 in_port=2, ip, action=set_field:1->reg4,set_field:2->reg3,ct(zone=NXM_NX_REG4[[0..15]],nat,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 Pass tracked traffic through ACL, drop everything else. dnl Non-REPLY/RELATED packets get the ACL lookup with the packet headers dnl in the actual packet direction in reg0 (IN=1, OUT=2). REPLY packets dnl get the ACL lookup using the conntrack tuple and the inverted direction. dnl RELATED packets get ACL lookup using the conntrack tuple in the direction dnl of the master connection, as stored in ct_label[0]. dnl dnl Incoming non-related packet in the original direction (ACL IN) table=1 reg3=1, ip, ct_state=-rel-rpl+trk-inv action=set_field:1->reg0,resubmit(,3),goto_table:5 dnl Incoming non-related reply packet (CT ACL OUT) table=1 reg3=1, ip, ct_state=-rel+rpl+trk-inv action=set_field:2->reg0,resubmit(,3,ct),goto_table:4 dnl Outgoing non-related packet (ACL OUT) table=1 reg3=2, ip, ct_state=-rel-rpl+trk-inv action=set_field:2->reg0,resubmit(,3),goto_table:5 dnl Outgoing non-related reply packet (CT ACL IN) table=1 reg3=2, ip, ct_state=-rel+rpl+trk-inv action=set_field:1->reg0,resubmit(,3,ct),goto_table:4 dnl dnl Related packet (CT ACL in the direction of the master connection.) table=1 ip, ct_state=+rel+trk-inv, action=move:NXM_NX_CT_LABEL[[0]]->NXM_NX_REG0[[0]],resubmit(,3,ct),goto_table:4 dnl Drop everything else. table=1 priority=0, action=drop dnl dnl "ACL table" dnl dnl Stateful accept (1->reg2) all incoming (reg0=1) IP connections with dnl IP source address '10.1.1.1'. Store rule ID (1234) in reg1, verdict dnl in reg2. table=3 priority=10, reg0=1, ip, nw_src=10.1.1.1 action=set_field:1234->reg1,set_field:1->reg2 dnl Stateless drop (0->reg2) everything else in both directions. (Rule ID: 1235) table=3 priority=0, action=set_field:1235->reg1,set_field:0->reg2 dnl dnl Re-process stateful traffic that was not accepted by a stateful rule as dnl normal traffic in the current direction. This should also delete the dnl now stale conntrack state, so that new state can be created in it's place. dnl dnl Stateful accepts go to next table. table=4 priority=100 reg2=1, action=goto_table:5 dnl Everything else is reprocessed disregarding the CT state, using the actual dnl packet direction. table=4 priority=0 action=move:NXM_NX_REG3[[]]->NXM_NX_REG0[[]],resubmit(,3),goto_table:5 dnl dnl "ACL verdict processing table." dnl dnl Handle stateful (reg2=1) / stateless (reg2=2) accepts and drops (reg2=0) dnl dnl Drop all non-accepted packets. table=5 reg2=0 priority=1000 action=drop dnl dnl Commit new incoming FTP control connections with SNAT range. Must match on dnl 'tcp' when setting 'alg=ftp'. Store the directionality of non-related dnl connections to ct_label[0] Store the rule ID to ct_label[96..127]. table=5 priority=100 reg2=1 reg3=1 ct_state=+new-rel, tcp, tp_dst=21, action=ct(zone=NXM_NX_REG4[[0..15]],alg=ftp,commit,nat(src=$2),exec(move:NXM_NX_REG3[[0]]->NXM_NX_CT_LABEL[[0]],move:NXM_NX_REG1[[0..31]]->NXM_NX_CT_LABEL[[96..127]])),goto_table:6 dnl Commit other new incoming non-related IP connections with SNAT range. table=5 priority=10 reg2=1 reg3=1 ct_state=+new-rel, ip, action=ct(zone=NXM_NX_REG4[[0..15]],commit,nat(src=$2),exec(move:NXM_NX_REG3[[0]]->NXM_NX_CT_LABEL[[0]],move:NXM_NX_REG1[[0..31]]->NXM_NX_CT_LABEL[[96..127]])),goto_table:6 dnl Commit non-related outgoing new IP connections with DNAT range. dnl (This should not get any packets in this test.) table=5 priority=10 reg2=1 reg3=2 ct_state=+new-rel, ip, action=ct(zone=NXM_NX_REG4[[0..15]],commit,nat(dst=$2),exec(move:NXM_NX_REG3[[0]]->NXM_NX_CT_LABEL[[0]],move:NXM_NX_REG1[[0..31]]->NXM_NX_CT_LABEL[[96..127]])),goto_table:6 dnl Commit new related connections in either direction, which need 'nat' dnl and which inherit the label (the direction of the original direction dnl master tuple) from the master connection. table=5 priority=10 reg2=1 ct_state=+new+rel, ip, action=ct(zone=NXM_NX_REG4[[0..15]],commit,nat,exec(move:NXM_NX_REG1[[0..31]]->NXM_NX_CT_LABEL[[96..127]])),goto_table:6 dnl dnl NAT incoming non-NEW packets. Outgoing packets were NATted in table 0. dnl table=5 priority=10 ct_state=-new+trk-inv reg3=1 ip, action=ct(zone=NXM_NX_REG4[[0..15]],nat),goto_table:6 dnl Forward everything else, including stateless accepts. table=5 priority=0 action=goto_table:6 dnl dnl "Forwarding table" dnl table=6 in_port=1 action=2 table=6 in_port=2 action=1 dnl dnl MAC resolution table for IP in reg2, stores mac in OXM_OF_PKT_REG0 dnl table=8,reg2=$3,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 ], [dnl tcp,orig=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),reply=(src=10.1.1.2,dst=$2,sport=,dport=),zone=1,labels=0x4d2000000000000000000000001,protoinfo=(state=),helper=ftp tcp,orig=(src=10.1.1.2,dst=$2,sport=,dport=),reply=(src=10.1.1.1,dst=10.1.1.2,sport=,dport=),zone=1,labels=0x4d2000000000000000000000001,protoinfo=(state=) ]) ]) dnl Check that ct(nat,table=foo) works without TCP sequence adjustment with dnl an ACL table based on matching on conntrack original direction tuple only. CHECK_FTP_NAT_ORIG_TUPLE([], [10.1.1.9], [0x0a010109]) dnl Check that ct(nat,table=foo) works with TCP sequence adjustment with dnl an ACL table based on matching on conntrack original direction tuple only. CHECK_FTP_NAT_ORIG_TUPLE([seqadj], [10.1.1.240], [0x0a0101f0]) AT_SETUP([conntrack - IPv4 FTP Passive with NAT]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() 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 e6:66:c1:11:11:11]) NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22]) ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address e6:66:c1:22:22:22]) NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e6:66:c1:11:11:11]) NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.240 e6:66:c1:11:11:11]) dnl Allow any traffic from ns0->ns1. AT_DATA([flows.txt], [dnl dnl track all IPv4 traffic and NAT any established traffic. table=0 priority=10 ip, action=ct(nat,table=1) table=0 priority=0 action=drop dnl dnl Table 1 dnl dnl Allow new FTP control connections. table=1 in_port=1 ct_state=+new tcp nw_src=10.1.1.1 tp_dst=21 action=ct(alg=ftp,commit,nat(src=10.1.1.240)),2 dnl Allow related TCP connections from port 1. table=1 in_port=1 ct_state=+new+rel tcp nw_src=10.1.1.1 action=ct(commit,nat),2 dnl Allow established TCP connections both ways, post-NAT match. table=1 in_port=1 ct_state=+est tcp nw_src=10.1.1.240 action=2 table=1 in_port=2 ct_state=+est tcp nw_dst=10.1.1.1 action=1 dnl Allow ICMP both ways. table=1 priority=100 in_port=1 icmp, action=2 table=1 priority=100 in_port=2 icmp, action=1 table=1 priority=0, action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Check that the stacks working to avoid races. OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.1.1.2 >/dev/null]) OVS_START_L7([at_ns1], [ftp]) dnl 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]) dnl Discards CLOSE_WAIT and CLOSING 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.240,sport=,dport=),protoinfo=(state=) 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=),helper=ftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 HTTP with SNAT]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() 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]) NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::241 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-fc00::241)),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 priority=200,in_port=2,ct_state=+trk+new,icmp6,icmpv6_code=0,icmpv6_type=135,nd_target=fc00::241,action=ct(commit,nat(dst=fc00::1)),1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) dnl HTTP requests from ns0->ns1 should work fine. OVS_START_L7([at_ns1], [http6]) 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. OVS_START_L7([at_ns0], [http6]) 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 HTTP with DNAT]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() 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") NS_CHECK_EXEC([at_ns0], [ip -6 link set dev p0 address 80:88:88:88:88:77]) NS_CHECK_EXEC([at_ns1], [ip -6 link set dev p1 address 80:88:88:88:88:88]) NS_CHECK_EXEC([at_ns0], [ip -6 neigh add fc00::240 lladdr 80:88:88:88:88:88 dev p0]) NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::1 lladdr 80:88:88:88:88:77 dev p1]) 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,ip6,ipv6_dst=fc00::240,action=ct(zone=1,nat(dst=fc00::2),commit),2 priority=100 in_port=2,ct_state=-trk,ip6,action=ct(table=0,nat,zone=1) priority=100 in_port=2,ct_state=+trk+est,ct_zone=1,ip6,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::240]) NS_CHECK_EXEC([at_ns0], [ping6 -q -c 3 -i 0.3 -w 2 fc00::240 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl Should work with the virtual IP address through NAT OVS_START_L7([at_ns1], [http6]) NS_CHECK_EXEC([at_ns0], [wget http://[[fc00::240]] -t 5 -T 1 --retry-connrefused -v -o wget0.log]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::1)], [0], [dnl icmpv6,orig=(src=fc00::1,dst=fc00::240,id=,type=128,code=0),reply=(src=fc00::2,dst=fc00::1,id=,type=129,code=0),zone=1 tcp,orig=(src=fc00::1,dst=fc00::240,sport=,dport=),reply=(src=fc00::2,dst=fc00::1,sport=,dport=),zone=1,protoinfo=(state=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 ICMP6 Related with SNAT]) AT_SKIP_IF([test $HAVE_TCPDUMP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() 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") NS_CHECK_EXEC([at_ns0], [ip -6 link set dev p0 address 80:88:88:88:88:77]) NS_CHECK_EXEC([at_ns1], [ip -6 link set dev p1 address 80:88:88:88:88:88]) NS_CHECK_EXEC([at_ns0], [ip -6 neigh add fc00::2 lladdr 80:88:88:88:88:88 dev p0]) NS_CHECK_EXEC([at_ns0], [ip -6 neigh add fc00::3 lladdr 80:88:88:88:88:88 dev p0]) NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::240 lladdr 80:88:88:88:88:77 dev p1]) NS_CHECK_EXEC([at_ns1], [ip -6 neigh add fc00::1 lladdr 80:88:88:88:88:77 dev p1]) NS_CHECK_EXEC([at_ns0], [ip -6 route add default via fc00::2]) 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,ip6,action=ct(nat(src=fc00::240),commit),2 priority=100 in_port=2,ct_state=-trk,ip6,action=ct(table=0,nat) priority=100 in_port=2,ct_state=+trk+est,ip6,action=1 priority=100 in_port=2,ct_state=+trk+rel,ip6,action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2]) AT_CHECK([ovs-appctl dpctl/flush-conntrack]) rm p0.pcap tcpdump -U -i ovs-p0 -w p0.pcap & sleep 1 dnl UDP packets from ns0->ns1 should solicit "destination unreachable" response. NS_CHECK_EXEC([at_ns0], [bash -c "echo a | nc -6 $NC_EOF_OPT -u fc00::2 1"]) AT_CHECK([tcpdump -v "icmp6" -r p0.pcap 2>/dev/null | egrep 'wrong|bad'], [1], [ignore-nolog]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(fc00::2)], [0], [dnl udp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::240,sport=,dport=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 FTP with NAT]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() 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 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 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 Drop everything else. table=1 priority=0, action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2 >/dev/null]) OVS_START_L7([at_ns1], [ftp]) 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-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING 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::240,sport=,dport=),protoinfo=(state=),helper=ftp tcp,orig=(src=fc00::2,dst=fc00::240,sport=,dport=),reply=(src=fc00::1,dst=fc00::2,sport=,dport=),protoinfo=(state=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 FTP Passive with NAT]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() 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 link set dev p1 address 80:88:88:88:88:99]) NS_CHECK_EXEC([at_ns0], [ip -6 neigh add fc00::2 lladdr 80:88:88:88:88:99 dev p0]) 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 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 1. table=1 in_port=1 ct_state=+new+rel tcp6 ipv6_dst=fc00::2 action=ct(commit,nat),2 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 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 Drop everything else. table=1 priority=0, action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2 >/dev/null]) OVS_START_L7([at_ns1], [ftp]) dnl FTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [wget ftp://[[fc00::2]] -6 -t 3 -T 1 --retry-connrefused -v --server-response --no-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING 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::240,sport=,dport=),protoinfo=(state=) tcp,orig=(src=fc00::1,dst=fc00::2,sport=,dport=),reply=(src=fc00::2,dst=fc00::240,sport=,dport=),protoinfo=(state=),helper=ftp ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv6 FTP with NAT - orig tuple]) AT_SKIP_IF([test $HAVE_FTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() 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 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 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 Allow new TCPv6 FTP control connections. table=1 priority=10 in_port=1 ct_state=+new+trk-inv tcp6 ct_nw_proto=6 ct_ipv6_src=fc00::1 ct_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 priority=10 in_port=2 ct_state=+new+rel+trk-inv ipv6 ct_nw_proto=6 ct_ipv6_src=fc00::1 ct_tp_dst=21 action=ct(commit,nat),1 dnl Allow established TCPv6 connections both ways, enforce NATting table=1 priority=10 in_port=1 ct_state=+est+trk-inv ipv6 ct_nw_proto=6 ct_ipv6_src=fc00::1 ct_tp_dst=21 action=2 table=1 priority=10 in_port=2 ct_state=+est+trk-inv ipv6 ct_nw_proto=6 ct_ipv6_src=fc00::1 ct_tp_dst=21 action=1 dnl Drop everything else. table=1 priority=0, action=drop ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Linux seems to take a little time to get its IPv6 stack in order. Without dnl waiting, we get occasional failures due to the following error: dnl "connect: Cannot assign requested address" OVS_WAIT_UNTIL([ip netns exec at_ns0 ping6 -c 1 fc00::2 >/dev/null]) NETNS_DAEMONIZE([at_ns1], [[$PYTHON $srcdir/test-l7.py ftp]], [ftp0.pid]) OVS_WAIT_UNTIL([ip netns exec at_ns1 netstat -l | grep ftp]) 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-remove-listing -o wget0.log -d]) dnl Discards CLOSE_WAIT and CLOSING 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::240,sport=,dport=),protoinfo=(state=),helper=ftp tcp,orig=(src=fc00::2,dst=fc00::240,sport=,dport=),reply=(src=fc00::1,dst=fc00::2,sport=,dport=),protoinfo=(state=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - IPv4 TFTP with NAT]) AT_SKIP_IF([test $HAVE_TFTP = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() CHECK_CONNTRACK_ALG() 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 e6:66:c1:11:11:11]) NS_CHECK_EXEC([at_ns0], [arp -s 10.1.1.2 e6:66:c1:22:22:22]) ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address e6:66:c1:22:22:22]) NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.1 e6:66:c1:11:11:11]) NS_CHECK_EXEC([at_ns1], [arp -s 10.1.1.240 e6:66:c1:11:11:11]) dnl Allow any traffic from ns0->ns1. AT_DATA([flows.txt], [dnl dnl track all IPv4 traffic. table=0 priority=10 ip, action=ct(table=1) dnl drop everything else. table=0 priority=0 action=drop dnl dnl Table 1 dnl Allow ICMP both ways. table=1 priority=100 in_port=1 icmp, action=2 table=1 priority=100 in_port=2 icmp, action=1 dnl dnl Allow new TFTP control connections. table=1 in_port=1 ct_state=+new udp nw_src=10.1.1.1 tp_dst=69 action=ct(alg=tftp,commit,nat(src=10.1.1.240)),2 dnl Allow related UDP connections from port 1. table=1 in_port=2 ct_state=+new+rel udp nw_src=10.1.1.2 action=ct(commit,nat),1 dnl Allow established and NAT them. table=1 in_port=1 ct_state=+est udp nw_src=10.1.1.1 action=ct(nat,table=2) table=1 in_port=2 ct_state=+est udp nw_src=10.1.1.2 action=ct(nat,table=2) dnl table=1 priority=0, action=drop dnl table=2 in_port=1 ct_state=+est udp nw_src=10.1.1.240 action=2 table=2 in_port=2 ct_state=+est udp nw_dst=10.1.1.1 action=1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Check that the stacks working to avoid races. OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.1.1.2 >/dev/null]) OVS_START_L7([at_ns0], [tftp]) OVS_START_L7([at_ns1], [tftp]) dnl TFTP requests from p0->p1 should work fine. NS_CHECK_EXEC([at_ns0], [[curl $CURL_OPT tftp://10.1.1.2/flows.txt -o foo 2>curl0.log]]) AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(10.1.1.2)], [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.240,sport=,dport=),helper=tftp udp,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=) ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - DNAT load balancing]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns1, at_ns2, at_ns3, at_ns4) ADD_VETH(p1, at_ns1, br0, "10.1.1.1/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.2/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.3/24") ADD_VETH(p4, at_ns4, br0, "10.1.1.4/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address 80:88:88:88:88:11]) NS_CHECK_EXEC([at_ns2], [ip link set dev p2 address 80:88:88:88:88:22]) NS_CHECK_EXEC([at_ns3], [ip link set dev p3 address 80:88:88:88:88:33]) NS_CHECK_EXEC([at_ns4], [ip link set dev p4 address 80:88:88:88:88:44]) dnl Select group for load balancing. One bucket per server. Each bucket dnl tracks and NATs the connection and recirculates to table 4 for egress dnl routing. Packets of existing connections are always NATted based on dnl connection state, only new connections are NATted according to the dnl specific NAT parameters in each bucket. AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn add-group br0 "group_id=234,type=select,bucket=weight=100,ct(nat(dst=10.1.1.2),commit,table=4),bucket=weight=100,ct(nat(dst=10.1.1.3),commit,table=4),bucket=weight=100,ct(nat(dst=10.1.1.4),commit,table=4)"]) AT_DATA([flows.txt], [dnl dnl Track connections to the virtual IP address. table=0 priority=100 ip nw_dst=10.1.1.64 action=group:234 dnl All other IP traffic is allowed but the connection state is no commited. table=0 priority=90 ip action=ct(table=4,nat) dnl dnl Allow ARP, but generate responses for virtual 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 Routing table dnl table=4,ip,nw_dst=10.1.1.1 action=mod_dl_dst:80:88:88:88:88:11,output:1 table=4,ip,nw_dst=10.1.1.2 action=mod_dl_dst:80:88:88:88:88:22,output:2 table=4,ip,nw_dst=10.1.1.3 action=mod_dl_dst:80:88:88:88:88:33,output:3 table=4,ip,nw_dst=10.1.1.4 action=mod_dl_dst:80:88:88:88:88:44,output:4 table=4 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=controller ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Start web servers OVS_START_L7([at_ns2], [http]) OVS_START_L7([at_ns3], [http]) OVS_START_L7([at_ns4], [http]) on_exit 'ovs-ofctl -O OpenFlow15 dump-flows br0' on_exit 'ovs-appctl revalidator/purge' on_exit 'ovs-appctl dpif/dump-flows br0' dnl Should work with the virtual IP address through NAT for i in 1 2 3 4 5 6 7 8 9 10 11 12; do echo Request $i NS_CHECK_EXEC([at_ns1], [wget 10.1.1.64 -t 5 -T 1 --retry-connrefused -v -o wget$i.log]) done dnl Each server should have at least one connection. 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=),protoinfo=(state=) tcp,orig=(src=10.1.1.1,dst=10.1.1.64,sport=,dport=),reply=(src=10.1.1.3,dst=10.1.1.1,sport=,dport=),protoinfo=(state=) tcp,orig=(src=10.1.1.1,dst=10.1.1.64,sport=,dport=),reply=(src=10.1.1.4,dst=10.1.1.1,sport=,dport=),protoinfo=(state=) ]) ovs-appctl dpif/dump-flows br0 ovs-appctl revalidator/purge ovs-ofctl -O OpenFlow15 dump-flows br0 ovs-ofctl -O OpenFlow15 dump-group-stats br0 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - DNAT load balancing with NC]) AT_SKIP_IF([test $HAVE_NC = no]) CHECK_CONNTRACK() CHECK_CONNTRACK_NAT() OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns1, at_ns2, at_ns3, at_ns4, at_ns5) ADD_VETH(p1, at_ns1, br0, "10.1.1.1/24") ADD_VETH(p2, at_ns2, br0, "10.1.1.2/24") ADD_VETH(p3, at_ns3, br0, "10.1.1.3/24") ADD_VETH(p4, at_ns4, br0, "10.1.1.4/24") ADD_VETH(p5, at_ns5, br0, "10.1.1.5/24") NS_CHECK_EXEC([at_ns1], [ip link set dev p1 address 80:88:88:88:88:11]) NS_CHECK_EXEC([at_ns2], [ip link set dev p2 address 80:88:88:88:88:22]) NS_CHECK_EXEC([at_ns3], [ip link set dev p3 address 80:88:88:88:88:33]) NS_CHECK_EXEC([at_ns4], [ip link set dev p4 address 80:88:88:88:88:44]) NS_CHECK_EXEC([at_ns5], [ip link set dev p5 address 80:88:88:88:88:55]) dnl Select group for load balancing. One bucket per server. Each bucket dnl tracks and NATs the connection and recirculates to table 4 for egress dnl routing. Packets of existing connections are always NATted based on dnl connection state, only new connections are NATted according to the dnl specific NAT parameters in each bucket. AT_CHECK([ovs-ofctl -O OpenFlow15 -vwarn add-group br0 "group_id=234,type=select,bucket=weight=100,ct(nat(dst=10.1.1.2),commit,table=4),bucket=weight=100,ct(nat(dst=10.1.1.3),commit,table=4),bucket=weight=100,ct(nat(dst=10.1.1.4),commit,table=4)"]) AT_DATA([flows.txt], [dnl dnl Track connections to the virtual IP address. table=0 priority=100 ip nw_dst=10.1.1.64 action=group:234 dnl All other IP traffic is allowed but the connection state is no commited. table=0 priority=90 ip action=ct(table=4,nat) dnl dnl Allow ARP, but generate responses for virtual 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 Routing table dnl table=4,ip,nw_dst=10.1.1.1 action=mod_dl_dst:80:88:88:88:88:11,output:1 table=4,ip,nw_dst=10.1.1.2 action=mod_dl_dst:80:88:88:88:88:22,output:2 table=4,ip,nw_dst=10.1.1.3 action=mod_dl_dst:80:88:88:88:88:33,output:3 table=4,ip,nw_dst=10.1.1.4 action=mod_dl_dst:80:88:88:88:88:44,output:4 table=4,ip,nw_dst=10.1.1.5 action=mod_dl_dst:80:88:88:88:88:55,output:5 table=4 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=controller ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl Start web servers OVS_START_L7([at_ns2], [http]) OVS_START_L7([at_ns3], [http]) OVS_START_L7([at_ns4], [http]) on_exit 'ovs-ofctl -O OpenFlow15 dump-flows br0' on_exit 'ovs-appctl revalidator/purge' on_exit 'ovs-appctl dpif/dump-flows br0' sleep 5 dnl Should work with the virtual IP address through NAT for i in 1 2 3 4 5 6 7 8 9; do echo Request $i NS_CHECK_EXEC([at_ns1], [echo "TEST1" | nc -p 4100$i 10.1.1.64 80 > nc-1-$i.log]) NS_CHECK_EXEC([at_ns5], [echo "TEST5" | nc -p 4100$i 10.1.1.64 80 > nc-5-$i.log]) done conntrack -L 2>&1 ovs-appctl dpif/dump-flows br0 ovs-appctl revalidator/purge ovs-ofctl -O OpenFlow15 dump-flows br0 ovs-ofctl -O OpenFlow15 dump-group-stats br0 OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([conntrack - floating IP]) AT_SKIP_IF([test $HAVE_NC = no]) CHECK_CONNTRACK() OVS_TRAFFIC_VSWITCHD_START() OVS_CHECK_CT_CLEAR() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24", "f0:00:00:01:01:01") dnl FIP 10.254.254.1 ADD_VETH(p1, at_ns1, br0, "10.1.1.2/24", "f0:00:00:01:01:02") dnl FIP 10.254.254.2 dnl Static ARPs NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.2 lladdr f0:00:00:01:01:02 dev p0]) NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.1 lladdr f0:00:00:01:01:01 dev p1]) dnl Static ARP and route entries for the FIP "gateway" NS_CHECK_EXEC([at_ns0], [ip neigh add 10.1.1.254 lladdr f0:00:00:01:01:FE dev p0]) NS_CHECK_EXEC([at_ns1], [ip neigh add 10.1.1.254 lladdr f0:00:00:01:01:FE dev p1]) NS_CHECK_EXEC([at_ns0], [ip route add default nexthop via 10.1.1.254]) NS_CHECK_EXEC([at_ns1], [ip route add default nexthop via 10.1.1.254]) NETNS_DAEMONIZE([at_ns0], [nc -l -k 1234 > /dev/null], [nc0.pid]) AT_DATA([flows.txt], [dnl table=0,priority=10 ip action=ct(table=1) table=0,priority=1 action=drop dnl dst FIP table=1,priority=20 ip,ct_state=+trk+est,nw_dst=10.254.254.0/24 action=goto_table:10 table=1,priority=20 ip,ct_state=+trk+new,nw_dst=10.254.254.0/24 action=ct(commit,table=10) dnl dst local table=1,priority=10 ip,ct_state=+trk+est action=goto_table:20 table=1,priority=10 ip,ct_state=+trk+new action=ct(commit,table=20) table=1,priority=1 ip,ct_state=+trk+inv action=drop dnl dnl FIP translation (dst FIP, src local) --> (dst local, src FIP) table=10 ip,nw_dst=10.254.254.1 action=set_field:10.1.1.1->nw_dst,goto_table:11 table=10 ip,nw_dst=10.254.254.2 action=set_field:10.1.1.2->nw_dst,goto_table:11 table=11 ip,nw_src=10.1.1.1 action=set_field:10.254.254.1->nw_src,goto_table:12 table=11 ip,nw_src=10.1.1.2 action=set_field:10.254.254.2->nw_src,goto_table:12 dnl clear conntrack and do another lookup since we changed the tuple table=12,priority=10 ip action=ct_clear,ct(table=13) table=12,priority=1 action=drop table=13 ip,ct_state=+trk+est action=goto_table:20 table=13 ip,ct_state=+trk+new action=ct(commit,table=20) table=13 ip,ct_state=+trk+inv action=drop dnl dnl Output table=20 ip,nw_src=10.1.1.1 action=set_field:f0:00:00:01:01:01->eth_src,goto_table:21 table=20 ip,nw_src=10.1.1.2 action=set_field:f0:00:00:01:01:02->eth_src,goto_table:21 table=20 ip,nw_src=10.254.254.0/24 action=set_field:f0:00:00:01:01:FE->eth_src,goto_table:21 table=21 ip,nw_dst=10.1.1.1 action=set_field:f0:00:00:01:01:01->eth_dst,output:ovs-p0 table=21 ip,nw_dst=10.1.1.2 action=set_field:f0:00:00:01:01:02->eth_dst,output:ovs-p1 ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows.txt]) dnl non-FIP case NS_CHECK_EXEC([at_ns1], [echo "foobar" |nc $NC_EOF_OPT 10.1.1.1 1234]) OVS_WAIT_UNTIL([[ovs-appctl dpctl/dump-conntrack | sed -e 's/port=[0-9]*/port=/g' -e 's/id=[0-9]*/id=/g' | grep "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)" ]]) dnl Check that the full session ends as expected (i.e. TIME_WAIT). Otherwise it dnl means the datapath didn't process the ct_clear action. Ending in SYN_RECV dnl (OVS maps to ESTABLISHED) means the initial frame was committed, but not a dnl second time after the FIP translation (because ct_clear didn't occur). NS_CHECK_EXEC([at_ns1], [echo "foobar" |nc $NC_EOF_OPT 10.254.254.1 1234]) OVS_WAIT_UNTIL([[ovs-appctl dpctl/dump-conntrack | sed -e 's/port=[0-9]*/port=/g' -e 's/id=[0-9]*/id=/g' | grep "tcp,orig=(src=10.254.254.2,dst=10.1.1.1,sport=,dport=),reply=(src=10.1.1.1,dst=10.254.254.2,sport=,dport=),protoinfo=(state=TIME_WAIT)" ]]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_BANNER([802.1ad]) AT_SETUP([802.1ad - vlan_limit]) OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() 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_SVLAN(p0, at_ns0, 4094, "10.255.2.1/24") ADD_SVLAN(p1, at_ns1, 4094, "10.255.2.2/24") ADD_CVLAN(p0.4094, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p1.4094, at_ns1, 100, "10.2.2.2/24") AT_CHECK([ovs-ofctl add-flow br0 "priority=1 action=normal"]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) dnl CVLAN traffic should match the flow and drop AT_CHECK([ovs-appctl revalidator/purge]) AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:vlan-limit=1]) AT_CHECK([ovs-ofctl add-flow br0 "priority=100 dl_type=0x8100 action=drop"]) NS_CHECK_EXEC([at_ns0], [ping -q -c 1 -w 3 10.2.2.2], [1], [ignore]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([802.1ad - push/pop outer 802.1ad]) OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() ADD_BR([br1]) ADD_BR([br2]) ADD_NAMESPACES(at_ns0, at_ns1) AT_CHECK([ip link add ovs-p0 type veth peer name ovs-p1]) AT_CHECK([ip link set dev ovs-p0 up]) AT_CHECK([ip link set dev ovs-p1 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p0]) AT_CHECK([ovs-vsctl add-port br1 ovs-p1]) on_exit 'ip link del ovs-p0' AT_CHECK([ip link add ovs-p2 type veth peer name ovs-p3]) AT_CHECK([ip link set dev ovs-p2 up]) AT_CHECK([ip link set dev ovs-p3 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p2]) AT_CHECK([ovs-vsctl add-port br2 ovs-p3]) on_exit 'ip link del ovs-p2' ADD_VETH(p4, at_ns0, br1, "10.1.1.1/24") ADD_VETH(p5, at_ns1, br2, "10.1.1.2/24") ADD_CVLAN(p4, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p5, at_ns1, 100, "10.2.2.2/24") AT_DATA([flows-br0.txt], [dnl priority=1 action=drop priority=100 in_port=1 action=push_vlan:0x88a8,mod_vlan_vid=4094,output:2 priority=100 in_port=2 action=push_vlan:0x88a8,mod_vlan_vid=4094,output:1 ]) AT_DATA([flows-customer-br.txt], [dnl priority=1 action=normal priority=100 in_port=1 vlan_tci=0x1000/0x1000 action=pop_vlan,normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) AT_CHECK([ovs-ofctl --bundle add-flows br1 flows-customer-br.txt]) AT_CHECK([ovs-ofctl --bundle add-flows br2 flows-customer-br.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) 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 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([802.1ad - push/pop outer 802.1q]) OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() ADD_BR([br1]) ADD_BR([br2]) ADD_NAMESPACES(at_ns0, at_ns1) AT_CHECK([ip link add ovs-p0 type veth peer name ovs-p1]) AT_CHECK([ip link set dev ovs-p0 up]) AT_CHECK([ip link set dev ovs-p1 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p0]) AT_CHECK([ovs-vsctl add-port br1 ovs-p1]) on_exit 'ip link del ovs-p0' AT_CHECK([ip link add ovs-p2 type veth peer name ovs-p3]) AT_CHECK([ip link set dev ovs-p2 up]) AT_CHECK([ip link set dev ovs-p3 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p2]) AT_CHECK([ovs-vsctl add-port br2 ovs-p3]) on_exit 'ip link del ovs-p2' ADD_VETH(p4, at_ns0, br1, "10.1.1.1/24") ADD_VETH(p5, at_ns1, br2, "10.1.1.2/24") ADD_CVLAN(p4, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p5, at_ns1, 100, "10.2.2.2/24") AT_DATA([flows-br0.txt], [dnl priority=1 action=drop priority=100 in_port=1 action=push_vlan:0x8100,mod_vlan_vid=4094,output:2 priority=100 in_port=2 action=push_vlan:0x8100,mod_vlan_vid=4094,output:1 ]) AT_DATA([flows-customer-br.txt], [dnl priority=1 action=normal priority=100 in_port=1 vlan_tci=0x1000/0x1000 action=pop_vlan,normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) AT_CHECK([ovs-ofctl --bundle add-flows br1 flows-customer-br.txt]) AT_CHECK([ovs-ofctl --bundle add-flows br2 flows-customer-br.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) 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 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([802.1ad - 802.1q tunnel]) OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() ADD_BR([br1]) ADD_BR([br2]) ADD_NAMESPACES(at_ns0, at_ns1) AT_CHECK([ip link add ovs-p0 type veth peer name ovs-p1]) AT_CHECK([ip link set dev ovs-p0 up]) AT_CHECK([ip link set dev ovs-p1 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p0]) AT_CHECK([ovs-vsctl add-port br1 ovs-p1]) on_exit 'ip link del ovs-p0' AT_CHECK([ip link add ovs-p2 type veth peer name ovs-p3]) AT_CHECK([ip link set dev ovs-p2 up]) AT_CHECK([ip link set dev ovs-p3 up]) AT_CHECK([ovs-vsctl add-port br0 ovs-p2]) AT_CHECK([ovs-vsctl add-port br2 ovs-p3]) on_exit 'ip link del ovs-p2' ADD_VETH(p4, at_ns0, br1, "10.1.1.1/24") ADD_VETH(p5, at_ns1, br2, "10.1.1.2/24") ADD_CVLAN(p4, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p5, at_ns1, 100, "10.2.2.2/24") ADD_CVLAN(p4, at_ns0, 200, "10.3.2.1/24") ADD_CVLAN(p5, at_ns1, 200, "10.3.2.2/24") ADD_CVLAN(p4, at_ns0, 300, "10.4.2.1/24") ADD_CVLAN(p5, at_ns1, 300, "10.4.2.2/24") AT_CHECK([ovs-ofctl add-flow br0 action=normal]) AT_CHECK([ovs-ofctl add-flow br1 action=normal]) AT_CHECK([ovs-ofctl add-flow br2 action=normal]) AT_CHECK([ovs-vsctl set port ovs-p0 vlan_mode=dot1q-tunnel tag=4094 cvlans=100,200]) AT_CHECK([ovs-vsctl set port ovs-p2 vlan_mode=dot1q-tunnel tag=4094 cvlans=100,200]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.3.2.2]) 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 -q -c 3 -i 0.3 -w 2 10.3.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 1600 -q -c 3 -i 0.3 -w 2 10.3.2.2 | FORMAT_PING], [0], [dnl 3 packets transmitted, 3 received, 0% packet loss, time 0ms ]) dnl CVLAN 300 is not permitted by dot1q-tunnel NS_CHECK_EXEC([at_ns0], [ping -q -c 1 -w 3 10.4.2.2], [1], [ignore]) OVS_TRAFFIC_VSWITCHD_STOP(["/dropping VLAN \(0\|300\) packet received on dot1q-tunnel port/d"]) AT_CLEANUP AT_SETUP([802.1ad - double vlan match]) OVS_TRAFFIC_VSWITCHD_START([set Open_vSwitch . other_config:vlan-limit=0]) OVS_CHECK_8021AD() 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_SVLAN(p0, at_ns0, 4094, "10.255.2.1/24") ADD_SVLAN(p1, at_ns1, 4094, "10.255.2.2/24") ADD_CVLAN(p0.4094, at_ns0, 100, "10.2.2.1/24") ADD_CVLAN(p1.4094, at_ns1, 100, "10.2.2.2/24") AT_DATA([flows-br0.txt], [dnl table=0,priority=1 action=drop table=0,priority=100 dl_vlan=4094 action=pop_vlan,goto_table:1 table=1,priority=100 dl_vlan=100 action=push_vlan:0x88a8,mod_vlan_vid:4094,normal ]) AT_CHECK([ovs-ofctl --bundle add-flows br0 flows-br0.txt]) OVS_WAIT_UNTIL([ip netns exec at_ns0 ping -c 1 10.2.2.2]) 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 ]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_BANNER([nsh-datapath]) AT_SETUP([nsh - encap header]) OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "0.0.0.0") ADD_VETH(p1, at_ns1, br0, "0.0.0.0") dnl The flow will encap a nsh header to the TCP syn packet dnl eth/ip/tcp --> OVS --> eth/nsh/eth/ip/tcp AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,ip,actions=encap(nsh(md_type=1)),set_field:0x1234->nsh_spi,set_field:0x11223344->nsh_c1,encap(ethernet),set_field:f2:ff:00:00:00:02->dl_dst,set_field:f2:ff:00:00:00:01->dl_src,ovs-p1"]) rm ovs-p1.pcap tcpdump -U -i ovs-p1 -w ovs-p1.pcap & sleep 1 dnl The hex dump is a TCP syn packet. pkt=eth/ip/tcp dnl The packet is sent from p0(at_ns0) interface directed to dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON $srcdir/sendpkt.py p0 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) sleep 1 dnl Check the expected nsh encapsulated packet on the egress interface AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0fc6" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0010: *0103 *0012 *34ff *1122 *3344 *0000 *0000 *0000" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0020: *0000 *0000 *0000 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([nsh - decap header]) OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "0.0.0.0") ADD_VETH(p1, at_ns1, br0, "0.0.0.0") dnl The flow will decap a nsh header which in turn carries a TCP syn packet dnl eth/nsh/eth/ip/tcp --> OVS --> eth/ip/tcp AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,dl_type=0x894f, actions=decap(),decap(), ovs-p1"]) rm ovs-p1.pcap tcpdump -U -i ovs-p1 -w ovs-p1.pcap & sleep 1 dnl The hex dump is NSH packet with TCP syn payload. pkt=eth/nsh/eth/ip/tcp dnl The packet is sent from p0(at_ns0) interface directed to dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 00 64 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) sleep 1 dnl Check the expected de-capsulated TCP packet on the egress interface AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0000: *f200 *0000 *0002 *f200 *0000 *0001 *0800 *4500" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0010: *0028 *0001 *0000 *4006 *b013 *c0a8 *000a *0a00" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0020: *000a *0400 *0800 *0000 *00c8 *0000 *0000 *5002" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0030: *2000 *b85e *0000" 2>&1 1>/dev/null]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([nsh - replace header]) OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1) ADD_VETH(p0, at_ns0, br0, "0.0.0.0") ADD_VETH(p1, at_ns1, br0, "0.0.0.0") dnl The flow will decap a nsh header and encap a new nsh header dnl eth/nsh-X/eth/ip/tcp --> OVS --> eth/nsh-Y/eth/ip/tcp dnl The flow will add another NSH header with nsh_spi=0x101, nsh_si=4, dnl nsh_ttl=7 and change the md1 context AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,in_port=ovs-p0,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x03,actions=decap(),decap(),encap(nsh(md_type=1)),set_field:0x07->nsh_ttl,set_field:0x0101->nsh_spi,set_field:0x04->nsh_si,set_field:0x100f0e0d->nsh_c1,set_field:0x0c0b0a09->nsh_c2,set_field:0x08070605->nsh_c3,set_field:0x04030201->nsh_c4,encap(ethernet),set_field:f2:ff:00:00:00:02->dl_dst,set_field:f2:ff:00:00:00:01->dl_src,ovs-p1"]) rm ovs-p1.pcap tcpdump -U -i ovs-p1 -w ovs-p1.pcap & sleep 1 dnl The hex dump is NSH packet with TCP syn payload. pkt=eth/nsh/eth/ip/tcp dnl The nsh_ttl is 8, nsh_spi is 0x100 and nsh_si is 3 dnl The packet is sent from p0(at_ns0) interface directed to dnl p1(at_ns1) interface NS_CHECK_EXEC([at_ns0], [$PYTHON $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 03 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) sleep 1 dnl Check the expected NSH packet with new fields in the header AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000* 0001 *894f *01c6" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0010: *0103 *0001 *0104 *100f *0e0d *0c0b *0a09 *0807" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0020: *0605 *0403 *0201 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP AT_SETUP([nsh - forward]) OVS_TRAFFIC_VSWITCHD_START() ADD_NAMESPACES(at_ns0, at_ns1, at_ns2) ADD_VETH(p0, at_ns0, br0, "0.0.0.0") ADD_VETH(p1, at_ns1, br0, "0.0.0.0") ADD_VETH(p2, at_ns2, br0, "0.0.0.0") dnl Push two flows to OVS. #1 will check on SPI=0X100, SI=2 and send the dnl packet to at_ns1. #2 will check on SPI=0X100, SI=1 and send the dnl packet to to at_ns2. AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x02,actions=ovs-p1"]) AT_CHECK([ovs-ofctl -Oopenflow13 add-flow br0 "table=0,priority=100,dl_type=0x894f,nsh_spi=0x100,nsh_si=0x01,actions=ovs-p2"]) rm ovs-p1.pcap rm ovs-p2.pcap tcpdump -U -i ovs-p1 -w ovs-p1.pcap & tcpdump -U -i ovs-p2 -w ovs-p2.pcap & sleep 1 dnl First send packet from at_ns0 --> OVS with SPI=0x100 and SI=2 NS_CHECK_EXEC([at_ns0], [$PYTHON $srcdir/sendpkt.py p0 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 02 06 01 03 00 01 00 02 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) sleep 1 dnl Check for the above packet on ovs-p1 interface AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *0206" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0010: *0103 *0001 *0002 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p1.pcap 2>&1 | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) dnl Send the second packet from at_ns1 --> OVS with SPI=0x100 and SI=1 NS_CHECK_EXEC([at_ns1], [$PYTHON $srcdir/sendpkt.py p1 f2 ff 00 00 00 02 f2 ff 00 00 00 01 89 4f 01 c6 01 03 00 01 00 01 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 10 f2 00 00 00 00 02 f2 00 00 00 00 01 08 00 45 00 00 28 00 01 00 00 40 06 b0 13 c0 a8 00 0a 0a 00 00 0a 04 00 08 00 00 00 00 c8 00 00 00 00 50 02 20 00 b8 5e 00 00 > /dev/null]) sleep 1 dnl Check for the above packet on ovs-p2 interface AT_CHECK([tcpdump -xx -r ovs-p2.pcap 2>&1 | egrep "0x0000: *f2ff *0000 *0002 *f2ff *0000 *0001 *894f *01c6" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p2.pcap 2>&1 | egrep "0x0010: *0103 *0001 *0001 *0102 *0304 *0506 *0708 *090a" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p2.pcap 2>&1 | egrep "0x0020: *0b0c *0d0e *0f10 *f200 *0000 *0002 *f200 *0000" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p2.pcap 2>&1 | egrep "0x0030: *0001 *0800 *4500 *0028 *0001 *0000 *4006 *b013" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p2.pcap 2>&1 | egrep "0x0040: *c0a8 *000a *0a00 *000a *0400 *0800 *0000 *00c8" 2>&1 1>/dev/null]) AT_CHECK([tcpdump -xx -r ovs-p2.pcap 2>&1 | egrep "0x0050: *0000 *0000 *5002 *2000 *b85e *0000" 2>&1 1>/dev/null]) OVS_TRAFFIC_VSWITCHD_STOP AT_CLEANUP