From 6ce267af7124a93306d8b5bf4944379536ecd264 Mon Sep 17 00:00:00 2001 From: Dumitru Ceara Date: Thu, 11 Jan 2024 23:21:43 +0100 Subject: [PATCH] actions: Make sure affinity learnt flows are auto deleted. In order for that to happen the learnt flows' cookie must match with the cookie of the flow they were learnt on. Fixes: 216201a2b5d6 ("actions: introduce commit_lb_aff action") Reported-at: https://issues.redhat.com/browse/FDP-257 Signed-off-by: Dumitru Ceara Acked-by: Numan Siddique (cherry picked from commit 9283a5849a0b57f493a0a45940b59081d2aa585f) --- lib/actions.c | 1 + tests/ovn.at | 6 +-- tests/system-ovn-kmod.at | 4 +- tests/system-ovn.at | 89 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 5 deletions(-) diff --git a/lib/actions.c b/lib/actions.c index b880927b6d..4d408d82d7 100644 --- a/lib/actions.c +++ b/lib/actions.c @@ -5004,6 +5004,7 @@ encode_COMMIT_LB_AFF(const struct ovnact_commit_lb_aff *lb_aff, ol->hard_timeout = OFP_FLOW_PERMANENT; ol->priority = OFP_DEFAULT_PRIORITY; ol->table_id = OFTABLE_CHK_LB_AFFINITY; + ol->cookie = htonll(ep->lflow_uuid.parts[0]); /* Match on metadata of the packet that created the new table. */ ol_spec = ofpbuf_put_zeros(ofpacts, sizeof *ol_spec); diff --git a/tests/ovn.at b/tests/ovn.at index d03e2d8426..d29a4ee23d 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -2219,13 +2219,13 @@ reg9[5] = chk_ecmp_nh(); # commit_lb_aff commit_lb_aff(vip = "172.16.0.123:8080", backend = "10.0.0.3:8080", proto = tcp, timeout = 30); - encodes as learn(table=78,idle_timeout=30,delete_learned,OXM_OF_METADATA[],eth_type=0x800,NXM_OF_IP_SRC[],ip_dst=172.16.0.123,nw_proto=6,tcp_dst=8080,load:0x1->NXM_NX_REG10[14],load:0xa000003->NXM_NX_REG4[],load:0x1f90->NXM_NX_REG8[0..15]) + encodes as learn(table=78,idle_timeout=30,delete_learned,cookie=0xaaaaaaaa,OXM_OF_METADATA[],eth_type=0x800,NXM_OF_IP_SRC[],ip_dst=172.16.0.123,nw_proto=6,tcp_dst=8080,load:0x1->NXM_NX_REG10[14],load:0xa000003->NXM_NX_REG4[],load:0x1f90->NXM_NX_REG8[0..15]) commit_lb_aff(vip = "172.16.0.123", backend = "10.0.0.3", timeout = 30); - encodes as learn(table=78,idle_timeout=30,delete_learned,OXM_OF_METADATA[],eth_type=0x800,NXM_OF_IP_SRC[],ip_dst=172.16.0.123,load:0x1->NXM_NX_REG10[14],load:0xa000003->NXM_NX_REG4[]) + encodes as learn(table=78,idle_timeout=30,delete_learned,cookie=0xaaaaaaaa,OXM_OF_METADATA[],eth_type=0x800,NXM_OF_IP_SRC[],ip_dst=172.16.0.123,load:0x1->NXM_NX_REG10[14],load:0xa000003->NXM_NX_REG4[]) commit_lb_aff(vip = "[::1]:8080", backend = "[::2]:8080", proto = tcp, timeout = 30); - encodes as learn(table=78,idle_timeout=30,delete_learned,OXM_OF_METADATA[],eth_type=0x86dd,NXM_NX_IPV6_SRC[],ipv6_dst=::1,nw_proto=6,tcp_dst=8080,load:0x1->NXM_NX_REG10[14],load:0x2->NXM_NX_XXREG0[],load:0x1f90->NXM_NX_REG8[0..15]) + encodes as learn(table=78,idle_timeout=30,delete_learned,cookie=0xaaaaaaaa,OXM_OF_METADATA[],eth_type=0x86dd,NXM_NX_IPV6_SRC[],ipv6_dst=::1,nw_proto=6,tcp_dst=8080,load:0x1->NXM_NX_REG10[14],load:0x2->NXM_NX_XXREG0[],load:0x1f90->NXM_NX_REG8[0..15]) # chk_lb_aff() reg9[6] = chk_lb_aff(); diff --git a/tests/system-ovn-kmod.at b/tests/system-ovn-kmod.at index 71d906d8fa..039d711709 100644 --- a/tests/system-ovn-kmod.at +++ b/tests/system-ovn-kmod.at @@ -146,7 +146,7 @@ tcp,orig=(src=172.16.1.2,dst=172.16.1.100,sport=,dport=),reply ]) dp_key=$(printf "0x%x" $(fetch_column datapath tunnel_key external_ids:name=R2)) -AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=78 --no-stats | sed -e 's/load:0xc0a80[[0-9]]02/load:0xc0a8002/'], [0], [dnl +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=78 --no-stats | strip_cookie | sed -e 's/load:0xc0a80[[0-9]]02/load:0xc0a8002/'], [0], [dnl table=78, idle_timeout=60, tcp,metadata=$dp_key,nw_src=172.16.1.2,nw_dst=172.16.1.100,tp_dst=8080 actions=load:0x1->NXM_NX_REG10[[14]],load:0xc0a8002->NXM_NX_REG4[[]],load:0x50->NXM_NX_REG8[[0..15]] ]) @@ -443,7 +443,7 @@ tcp,orig=(src=fd72::2,dst=fd30::1,sport=,dport=),reply=(src=fd ]) dp_key=$(printf "0x%x" $(fetch_column datapath tunnel_key external_ids:name=R2)) -AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=78 --no-stats | sed -e 's/load:0xfd1[[0-9]]000000000000/load:0xfd1000000000000/'], [0], [dnl +AT_CHECK_UNQUOTED([ovs-ofctl dump-flows br-int table=78 --no-stats | strip_cookie | sed -e 's/load:0xfd1[[0-9]]000000000000/load:0xfd1000000000000/'], [0], [dnl table=78, idle_timeout=60, tcp6,metadata=$dp_key,ipv6_src=fd72::2,ipv6_dst=fd30::1,tp_dst=8080 actions=load:0x1->NXM_NX_REG10[[14]],load:0x2->NXM_NX_XXREG1[[0..63]],load:0xfd1000000000000->NXM_NX_XXREG1[[64..127]],load:0x50->NXM_NX_REG8[[0..15]] ]) diff --git a/tests/system-ovn.at b/tests/system-ovn.at index 6d4265ce09..3ecf1db42f 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -12030,3 +12030,92 @@ as OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d /connection dropped.*/d"]) AT_CLEANUP + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([load balancing affinity sessions - auto clear learnt flows]) +AT_SKIP_IF([test $HAVE_NC = no]) +AT_KEYWORDS([lb]) + +ovn_start +OVS_TRAFFIC_VSWITCHD_START() +ADD_BR([br-int]) + +check ovs-vsctl \ + -- set Open_vSwitch . external-ids:system-id=hv1 \ + -- set Open_vSwitch . external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ + -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ + -- set bridge br-int fail-mode=secure other-config:disable-in-band=true + +start_daemon ovn-controller + +check ovn-nbctl lr-add lr +check ovn-nbctl lrp-add lr lr-ls 00:00:00:00:01:00 42.42.42.3/24 +check ovn-nbctl ls-add ls + +check ovn-nbctl lsp-add ls ls-lr +check ovn-nbctl lsp-set-addresses ls-lr 00:00:00:00:01:00 +check ovn-nbctl lsp-set-type ls-lr router +check ovn-nbctl lsp-set-options ls-lr router-port=lr-ls +check ovn-nbctl lsp-add ls vm1 +check ovn-nbctl lsp-set-addresses vm1 00:00:00:00:00:01 +check ovn-nbctl lsp-add ls vm2 +check ovn-nbctl lsp-set-addresses vm2 00:00:00:00:00:02 +check ovn-nbctl lb-add lb-test 43.43.43.43:80 42.42.42.1:8080,42.42.42.2:8080 tcp \ + -- set load_balancer lb-test options:affinity_timeout=65535 \ + -- ls-lb-add ls lb-test + +dnl Start a server on vm1. +ADD_NAMESPACES(vm1) +ADD_VETH(vm1, vm1, br-int, "42.42.42.1/24", "00:00:00:00:00:01", "42.42.42.3") +NETNS_DAEMONIZE([vm1], [nc -l -k 42.42.42.1 8080], [vm1.pid]) + +dnl Start a server on vm2. +ADD_NAMESPACES(vm2) +ADD_VETH(vm2, vm2, br-int, "42.42.42.2/24", "00:00:00:00:00:02", "42.42.42.3") +NETNS_DAEMONIZE([vm2], [nc -l -k 42.42.42.2 8080], [vm2.pid]) + +dnl Wait for ovn-controller to catch up. +wait_for_ports_up +check ovn-nbctl --wait=hv sync + +dnl Test the connection. +OVS_WAIT_UNTIL([ + ip netns exec vm1 nc -z 43.43.43.43 80 &> /dev/null +]) + +OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int | grep 'table=78, n_packets' -c) -eq 1]) + +dnl Find the backend that was hit. +backend=$(ovs-ofctl dump-flows br-int table=78 | \ + grep -oE 'load:0x2a2a2a0[[12]]' | sed -n 's/load:0x2a2a2a0\(.*\)/\1/p') + +dnl Remove the backend that was hit. +if [[ "$backend" == "1" ]]; then + check ovn-nbctl set load_balancer lb-test vip:\"43.43.43.43:80\"=\"42.42.42.2:8080\" +else + check ovn-nbctl set load_balancer lb-test vip:\"43.43.43.43:80\"=\"42.42.42.1:8080\" +fi +check ovn-nbctl --wait=hv sync + +dnl The learnt flow should also be auto deleted. +AT_CHECK([ovs-ofctl dump-flows br-int | grep 'table=78, n_packets' -c], [1], [dnl +0 +]) + +OVS_APP_EXIT_AND_WAIT([ovn-controller]) + +as ovn-sb +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) + +as ovn-nb +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) + +as northd +OVS_APP_EXIT_AND_WAIT([ovn-northd]) + +as +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d +/connection dropped.*/d"]) +AT_CLEANUP +])