Introduce a test case to show that we can exclude flows based on specific configurations. Signed-off-by: Aaron Conole <aconole@xxxxxxxxxx> --- .../selftests/net/openvswitch/openvswitch.sh | 53 +++++++++++++++++-- .../selftests/net/openvswitch/ovs-dpctl.py | 34 +++++++++++- 2 files changed, 81 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh index ce14913150fe..f04f2f748332 100755 --- a/tools/testing/selftests/net/openvswitch/openvswitch.sh +++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh @@ -11,7 +11,8 @@ VERBOSE=0 TRACING=0 tests=" - netlink_checks ovsnl: validate netlink attrs and settings" + netlink_checks ovsnl: validate netlink attrs and settings + upcall_interfaces ovs: test the upcall interfaces" info() { [ $VERBOSE = 0 ] || echo $* @@ -72,7 +73,15 @@ ovs_add_dp () { ovs_add_if () { info "Adding IF to DP: br:$2 if:$3" - ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-if "$2" "$3" || return 1 + if [ "$4" != "-u" ]; then + ovs_sbx "$1" python3 $ovs_base/ovs-dpctl.py add-if "$2" "$3" \ + || return 1 + else + python3 $ovs_base/ovs-dpctl.py add-if \ + -u "$2" "$3" >$ovs_dir/$3.out 2>$ovs_dir/$3.err & + pid=$! + on_exit "ovs_sbx $1 kill -TERM $pid 2>/dev/null" + fi } ovs_del_if () { @@ -103,10 +112,16 @@ ovs_add_netns_and_veths () { ovs_sbx "$1" ip netns exec "$3" ip link set "$5" up || return 1 if [ "$6" != "" ]; then - ovs_sbx "$1" ip netns exec "$4" ip addr add "$6" dev "$5" \ + ovs_sbx "$1" ip netns exec "$3" ip addr add "$6" dev "$5" \ || return 1 fi - ovs_add_if "$1" "$2" "$4" || return 1 + + if [ "$7" != "-u" ]; then + ovs_add_if "$1" "$2" "$4" || return 1 + else + ovs_add_if "$1" "$2" "$4" -u || return 1 + fi + [ $TRACING -eq 1 ] && ovs_netns_spawn_daemon "$1" "$3" \ tcpdump -i any -s 65535 >> ${ovs_dir}/tcpdump_"$3".log @@ -158,6 +173,36 @@ test_netlink_checks () { return 0 } +test_upcall_interfaces() { + sbx_add "test_upcall_interfaces" || return 1 + + info "setting up new DP" + ovs_add_dp "test_upcall_interfaces" ui0 || return 1 + + ovs_add_netns_and_veths "test_upcall_interfaces" ui0 upc left0 l0 \ + 172.31.110.1/24 -u || return 1 + + sleep 1 + info "sending arping" + ip netns exec upc arping -I l0 172.31.110.20 -c 1 \ + >$ovs_dir/arping.stdout 2>$ovs_dir/arping.stderr + + grep -E "MISS upcall\[0/yes\]: .*arp\(sip=172.31.110.1,tip=172.31.110.20,op=1,sha=" $ovs_dir/left0.out >/dev/null 2>&1 || return 1 + # now tear down the DP and set it up with the new options + ovs_sbx "test_upcall_interfaces" python3 $ovs_base/ovs-dpctl.py \ + del-dp ui0 || return 1 + ovs_sbx "test_upcall_interfaces" python3 $ovs_base/ovs-dpctl.py \ + add-dp -e miss -- ui0 || return 1 + ovs_add_if "test_upcall_interfaces" ui0 left0 -u || return 1 + + sleep 1 + info "sending second arping" + ip netns exec upc arping -I l0 172.31.110.20 -c 1 \ + >$ovs_dir/arping.stdout 2>$ovs_dir/arping.stderr + grep -E "MISS upcall\[0/yes\]: \(none\)" $ovs_dir/left0.out >/dev/null 2>&1 || return 1 + return 0 +} + run_test() { ( tname="$1" diff --git a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py index 94204af48d28..ba115fb51773 100644 --- a/tools/testing/selftests/net/openvswitch/ovs-dpctl.py +++ b/tools/testing/selftests/net/openvswitch/ovs-dpctl.py @@ -111,6 +111,7 @@ class OvsDatapath(GenericNetlinkSocket): OVS_DP_F_VPORT_PIDS = 1 << 1 OVS_DP_F_DISPATCH_UPCALL_PER_CPU = 1 << 3 + OVS_DP_F_EXCLUDE_UPCALL_FLOW_KEY = 1 << 4 class dp_cmd_msg(ovs_dp_msg): """ @@ -127,6 +128,8 @@ class OvsDatapath(GenericNetlinkSocket): ("OVS_DP_ATTR_PAD", "none"), ("OVS_DP_ATTR_MASKS_CACHE_SIZE", "uint32"), ("OVS_DP_ATTR_PER_CPU_PIDS", "array(uint32)"), + ("OVS_DP_ATTR_IFINDEX", "uint32"), + ("OVS_DP_ATTR_EXCLUDE_CMDS", "uint32"), ) class dpstats(nla): @@ -171,7 +174,8 @@ class OvsDatapath(GenericNetlinkSocket): return reply - def create(self, dpname, shouldUpcall=False, versionStr=None, p=OvsPacket()): + def create(self, dpname, shouldUpcall=False, versionStr=None, p=OvsPacket(), + exclude=[]): msg = OvsDatapath.dp_cmd_msg() msg["cmd"] = OVS_DP_CMD_NEW if versionStr is None: @@ -200,6 +204,23 @@ class OvsDatapath(GenericNetlinkSocket): for i in range(1, nproc): procarray += [int(p.epid)] msg["attrs"].append(["OVS_DP_ATTR_UPCALL_PID", procarray]) + + excluded = 0 + print("exclude", exclude) + if len(exclude) > 0: + for ex in exclude: + if ex == "miss": + excluded |= 1 << OvsPacket.OVS_PACKET_CMD_MISS + elif ex == "action": + excluded |= 1 << OvsPacket.OVS_PACKET_CMD_ACTION + elif ex == "execute": + excluded |= 1 << OvsPacket.OVS_PACKET_CMD_EXECUTE + else: + print("DP CREATE: Unknown type: '%s'" % ex) + msg["attrs"].append(["OVS_DP_ATTR_EXCLUDE_CMDS", excluded]) + if versionStr is None or versionStr.find(":") == -1: + dpfeatures |= OvsDatapath.OVS_DP_F_EXCLUDE_UPCALL_FLOW_KEY + msg["attrs"].append(["OVS_DP_ATTR_USER_FEATURES", dpfeatures]) try: @@ -1240,6 +1261,14 @@ def main(argv): action="store_true", help="Leave open a reader for upcalls", ) + adddpcmd.add_argument( + "-e", + "--exclude", + type=str, + default=[], + nargs="+", + help="Exclude flow key from upcall packet commands" + ) adddpcmd.add_argument( "-V", "--versioning", @@ -1305,7 +1334,8 @@ def main(argv): msg += ":'%s'" % args.showdp print(msg) elif hasattr(args, "adddp"): - rep = ovsdp.create(args.adddp, args.upcall, args.versioning, ovspk) + rep = ovsdp.create(args.adddp, args.upcall, args.versioning, ovspk, + args.exclude) if rep is None: print("DP '%s' already exists" % args.adddp) else: -- 2.34.3