Skip GARP packet with link-local (ip6.dst == ff00::/8) address being advertised when "always_learn_from_arp_request=false", this should prevent huge grow of MAC Binding table. To keep the option consistent overwrite the previous MAC with LLA if it was already stored in DB.
Reported-at: https://bugzilla.redhat.com/2211240 Signed-off-by: Ales Musil <[email protected]> --- v2: Remove leftover from previous tests. v3: Address comments from Ihar: - Move the condition next to the other "nd_na" flow. - Update the comment for the flow. v4: Address comments from Dumitru: - Make sure we skip only unsolicited NAs. - Add relevant system test. --- northd/northd.c | 12 +++++++ tests/ovn.at | 78 ++++++++++++++++++++++++++++++--------------- tests/system-ovn.at | 73 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 137 insertions(+), 26 deletions(-) diff --git a/northd/northd.c b/northd/northd.c index 2aad2e425..cb39de4f6 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -12448,6 +12448,18 @@ build_neigh_learning_flows_for_lrouter( ovn_lflow_add(lflows, od, S_ROUTER_IN_LOOKUP_NEIGHBOR, 100, "nd_na", ds_cstr(actions)); + if (!learn_from_arp_request) { + /* Add flow to skip GARP LLA if we don't know it already. */ + ds_clear(actions); + ds_put_format(actions, REGBIT_LOOKUP_NEIGHBOR_RESULT + " = lookup_nd(inport, ip6.src, nd.tll); " + REGBIT_LOOKUP_NEIGHBOR_IP_RESULT + " = lookup_nd_ip(inport, ip6.src); next;"); + ovn_lflow_add(lflows, od, S_ROUTER_IN_LOOKUP_NEIGHBOR, 110, + "nd_na && ip6.src == fe80::/10 && ip6.dst == ff00::/8", + ds_cstr(actions)); + } + ds_clear(actions); ds_put_format(actions, REGBIT_LOOKUP_NEIGHBOR_RESULT " = lookup_nd(inport, ip6.src, nd.sll); %snext;", diff --git a/tests/ovn.at b/tests/ovn.at index 5e6a8fefa..df4ca75de 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -5062,6 +5062,7 @@ AT_CLEANUP OVN_FOR_EACH_NORTHD([ AT_SETUP([IP relocation using GARP request]) +AT_SKIP_IF([test $HAVE_SCAPY = no]) ovn_start # Logical network: @@ -5161,7 +5162,9 @@ done test_ip() { # This packet has bad checksums but logical L3 routing doesn't check. local inport=$1 src_mac=$2 dst_mac=$3 src_ip=$4 dst_ip=$5 - local packet=${dst_mac}${src_mac}08004500001c0000000040110000${src_ip}${dst_ip}0035111100080000 + local packet=$(fmt_pkt "Ether(dst='${dst_mac}', src='${src_mac}')/ \ + IP(dst='${dst_ip}', src='${src_ip}')/ \ + UDP(sport=53, dport=4369)") shift; shift; shift; shift; shift hv=hv`vif_to_hv $inport` as $hv ovs-appctl netdev-dummy/receive vif$inport $packet @@ -5176,7 +5179,9 @@ test_ip() { # Routing decrements TTL and updates source and dest MAC # (and checksum). out_lrp=`vif_to_lrp $outport` - echo f000000000${outport}00000000ff0${out_lrp}08004500001c00000000"3f1101"00${src_ip}${dst_ip}0035111100080000 + echo $(fmt_pkt "Ether(dst='f0:00:00:00:00:${outport}', src='00:00:00:00:ff:${out_lrp}')/ \ + IP(src='${src_ip}', dst='${dst_ip}', ttl=63)/ \ + UDP(sport=53, dport=4369)") fi >> $outport.expected done } @@ -5192,8 +5197,10 @@ test_ip() { # SHA and REPLY_HA are each 12 hex digits. # SPA and TPA are each 8 hex digits. test_arp() { - local inport=$1 sha=$2 spa=$3 tpa=$4 reply_ha=$5 - local request=ffffffffffff${sha}08060001080006040001${sha}${spa}ffffffffffff${tpa} + local inport=$1 sha=$2 spa=$3 tpa=$3 + local request=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \ + ARP(hwsrc='${sha}', hwdst='ff:ff:ff:ff:ff:ff', psrc='${spa}', pdst='${tpa}')") + hv=hv`vif_to_hv $inport` as $hv ovs-appctl netdev-dummy/receive vif$inport $request @@ -5206,53 +5213,72 @@ test_arp() { echo $request >> $i$j$k.expected fi done +} - # Expect to receive the reply, if any. - if test X$reply_ha != X; then - lrp=`vif_to_lrp $inport` - local reply=${sha}00000000ff0${lrp}08060001080006040002${reply_ha}${tpa}${sha}${spa} - echo $reply >> $inport.expected - fi +test_na() { + local inport=$1 sha=$2 spa=$3 + local request=$(fmt_pkt "Ether(dst='ff:ff:ff:ff:ff:ff', src='${sha}')/ \ + IPv6(dst='ff01::1', src='${spa}')/ \ + ICMPv6ND_NA(tgt='${spa}')") + + hv=hv`vif_to_hv $inport` + as $hv ovs-appctl netdev-dummy/receive vif$inport $request + + # Expect to receive the broadcast ARP on the other logical switch ports if + # IP address is not configured to the switch patch port. + local i=`vif_to_ls $inport` + local j + for j in 1 2; do + if test $i$j != $inport; then + echo $request >> $i$j$k.expected + fi + done } -# lp11 send GARP request to announce ownership of 192.168.1.100. +# lp11 send GARP request to announce ownership of 192.168.1.100 and fe80::abcd:1. -sha=f00000000011 -spa=`ip_to_hex 192 168 1 100` -tpa=$spa +sha="f0:00:00:00:00:11" +spa="192.168.1.100" +spa6="fe80::abcd:1" # When always_learn_from_arp_request=false, the new mac-binding will not be learned # through GARP request. ovn-nbctl --wait=hv set logical_router lr0 options:always_learn_from_arp_request=false -test_arp 11 $sha $spa $tpa +test_arp 11 $sha $spa +test_na 11 $sha $spa6 sleep 1 -check_row_count MAC_Binding 0 ip="192.168.1.100" +check_row_count MAC_Binding 0 ip="$spa" +check_row_count MAC_Binding 0 ip=\"$spa6\" # When always_learn_from_arp_request=true, the new mac-binding will be learned. ovn-nbctl --wait=hv set logical_router lr0 options:always_learn_from_arp_request=true -test_arp 11 $sha $spa $tpa -OVS_WAIT_UNTIL([test `ovn-sbctl find mac_binding ip="192.168.1.100" | wc -l` -gt 0]) +test_arp 11 $sha $spa +test_na 11 $sha $spa6 +wait_row_count MAC_Binding 1 ip="$spa" mac=\"$sha\" +wait_row_count MAC_Binding 1 ip=\"$spa6\" mac=\"$sha\" ovn-nbctl --wait=hv sync # Send an IP packet from lp21 to 192.168.1.100, which should go to lp11. -smac=f00000000021 -dmac=00000000ff02 -sip=`ip_to_hex 192 168 2 11` -dip=`ip_to_hex 192 168 1 100` +smac="f0:00:00:00:00:21" +dmac="00:00:00:00:ff:02" +sip="192.168.2.11" +dip="192.168.1.100" test_ip 21 $smac $dmac $sip $dip 11 -# lp12 send GARP request to announce ownership of 192.168.1.100. +# lp12 send GARP request to announce ownership of 192.168.1.100 and fe80::abcd:1. # Even when always_learn_from_arp_request=false, the existing mac-binding should be # updated through GARP request. ovn-nbctl --wait=hv set logical_router lr0 options:always_learn_from_arp_request=false -sha=f00000000012 -test_arp 12 $sha $spa $tpa -wait_row_count MAC_Binding 1 ip="192.168.1.100" mac='"f0:00:00:00:00:12"' +sha="f0:00:00:00:00:12" +test_arp 12 $sha $spa +test_na 11 $sha $spa6 +wait_row_count MAC_Binding 1 ip="$spa" mac=\"$sha\" +wait_row_count MAC_Binding 1 ip=\"$spa6\" mac=\"$sha\" ovn-nbctl --wait=hv sync # give to the hv the time to send queued ip packets sleep 1 diff --git a/tests/system-ovn.at b/tests/system-ovn.at index 6669c18e7..14cfbef11 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -11546,3 +11546,76 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([Traffic to router port via LLA]) +ovn_start +OVS_TRAFFIC_VSWITCHD_START() +ADD_BR([br-int]) +ADD_BR([br-phys], [set Bridge br-phys fail-mode=standalone]) + +# Set external-ids in br-int needed for ovn-controller +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 lr0 +check ovn-nbctl lrp-add lr0 lr0-ls0 00:00:00:00:00:01 fd00::1/64 + +check ovn-nbctl ls-add ls0 +check ovn-nbctl lsp-add ls0 vif0 \ + -- lsp-set-addresses vif0 "00:00:00:00:00:02 fd00::2" +check ovn-nbctl lsp-add ls0 ls0-lr0 \ + -- lsp-set-type ls0-lr0 router \ + -- lsp-set-addresses ls0-lr0 router \ + -- lsp-set-options ls0-lr0 router-port=lr0-ls0 + +ADD_NAMESPACES(vif0) +ADD_VETH(vif0, vif0, br-int, "fd00::2/64", "00:00:00:00:00:02", "fd00::1") +OVS_WAIT_UNTIL([test "$(ip netns exec vif0 ip a | grep fe80:: | grep tentative)" = ""]) + +check ovn-nbctl set logical_router lr0 options:always_learn_from_arp_request=false + +OVN_POPULATE_ARP +wait_for_ports_up +check ovn-nbctl --wait=sb sync + +NS_CHECK_EXEC([vif0], [ping -q -c 3 -i 0.3 -w 2 fe80::200:ff:fe00:1 | FORMAT_PING], \ +[0], [dnl +3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) + +check_row_count mac_binding 1 mac=\"00:00:00:00:00:02\" +ovn-sbctl --all destroy mac_binding + +ovn-nbctl --wait=hv set logical_router lr0 options:always_learn_from_arp_request=true + +NS_CHECK_EXEC([vif0], [ping -q -c 3 -i 0.3 -w 2 fe80::200:ff:fe00:1 | FORMAT_PING], \ +[0], [dnl +3 packets transmitted, 3 received, 0% packet loss, time 0ms +]) + +check_row_count mac_binding 1 mac=\"00:00:00:00:00:02\" + +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([NORTHD_TYPE]) + +as +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d +/connection dropped.*/d"]) + +AT_CLEANUP +]) -- 2.40.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
