Fix the active mac-binding refresh support for IPv6. In particular, remove
wrong flows for IPv6 NA in OFTABLE_MAC_CACHE_USE table (79) since they are
already managed by the more general IPv6 open-flow rules reported below.

table=79, n_packets=2, n_bytes=172, idle_age=4, 
priority=100,ipv6,reg14=0x2,metadata=0x1,dl_src=f0:00:00:01:02:04,ipv6_src=fd12::2
 actions=drop

Add IPv6 unit/system-tests.

Fixes: 1e4d4409f391 ("controller: Send ARP/ND for stale mac_bindings entries.")
Fixes: 9fc291c889bb ("controller: Update OFTABLE_MAC_CACHE_USE for ARP reply 
generated by the tracked device.")
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
 controller/lflow.c     |  13 +++--
 controller/mac-cache.c |   2 +-
 tests/ovn.at           | 105 ++++++++++++++++++++++++++++++++++++++---
 tests/system-ovn.at    |  37 +++++++++++++--
 4 files changed, 139 insertions(+), 18 deletions(-)

diff --git a/controller/lflow.c b/controller/lflow.c
index 860869f55..cb44f0b7a 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -1398,15 +1398,11 @@ consider_neighbor_flow(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
         match_set_dl_type(&lookup_arp_match, htons(ETH_TYPE_IPV6));
         match_set_nw_proto(&lookup_arp_match, 58);
         match_set_icmp_code(&lookup_arp_match, 0);
-        lookup_arp_for_stats_match = lookup_arp_match;
 
         match_set_xxreg(&lookup_arp_match, 0, ntoh128(value));
 
         match_set_dl_type(&mb_cache_use_match, htons(ETH_TYPE_IPV6));
         match_set_ipv6_src(&mb_cache_use_match, &ip6);
-
-        match_set_icmp_type(&lookup_arp_for_stats_match, 136);
-        match_set_nd_target(&lookup_arp_for_stats_match, &ip6);
     }
 
     match_set_metadata(&get_arp_match, htonll(pb->datapath->tunnel_key));
@@ -1438,9 +1434,12 @@ consider_neighbor_flow(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
 
     if (b) {
         ofpbuf_clear(&ofpacts);
-        ofctrl_add_flow(flow_table, OFTABLE_MAC_CACHE_USE, priority,
-                        b->header_.uuid.parts[0], &lookup_arp_for_stats_match,
-                        &ofpacts, &b->header_.uuid);
+        if (strchr(ip, '.')) {
+            ofctrl_add_flow(flow_table, OFTABLE_MAC_CACHE_USE, priority,
+                            b->header_.uuid.parts[0],
+                            &lookup_arp_for_stats_match,
+                            &ofpacts, &b->header_.uuid);
+        }
         ofctrl_add_flow(flow_table, OFTABLE_MAC_CACHE_USE, priority,
                         b->header_.uuid.parts[0], &mb_cache_use_match,
                         &ofpacts, &b->header_.uuid);
diff --git a/controller/mac-cache.c b/controller/mac-cache.c
index 0aebb09a4..a67578c48 100644
--- a/controller/mac-cache.c
+++ b/controller/mac-cache.c
@@ -943,7 +943,7 @@ mac_binding_probe_stats_run(
         }
 
         if (laddr.n_ipv4_addrs || laddr.n_ipv6_addrs) {
-            struct in6_addr local = laddr.n_ipv4_addrs
+            struct in6_addr local = IN6_IS_ADDR_V4MAPPED(&mb->data.ip)
                 ? in6_addr_mapped_ipv4(laddr.ipv4_addrs[0].addr)
                 : laddr.ipv6_addrs[0].addr;
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 714286596..afde2576f 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -36240,6 +36240,22 @@ send_udp() {
     as $hv ovs-appctl netdev-dummy/receive $dev $packet
 }
 
+send_udp6() {
+    local hv=$1 dev=$2 hdst=$3 hsrc=$4 idst=$5 isrc=$6
+    local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
+                            IPv6(dst='${idst}', src='${isrc}')/UDP()")
+    as $hv ovs-appctl netdev-dummy/receive $dev $packet
+}
+
+send_na() {
+    local hv=$1 dev=$2 hdst=$3 hsrc=$4 idst=$5 isrc=$6
+    local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
+                            IPv6(dst='${idst}', src='${isrc}')/ \
+                            ICMPv6ND_NA(tgt='${isrc}')/ \
+                            ICMPv6NDOptDstLLAddr(lladdr='${hsrc}')")
+    as $hv ovs-appctl netdev-dummy/receive $dev $packet
+}
+
 dump_arp() {
     local op=$1 eth_src=$2 eth_dst=$3 spa=$4 tpa=$5 hwdst=$6
 
@@ -36249,6 +36265,15 @@ dump_arp() {
     echo $packet
 }
 
+dump_ns() {
+    local hdst=$1 hsrc=$2 idst=$3 isrc=$4 tgt=$5
+    local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
+                            IPv6(dst='${idst}', src='${isrc}')/ \
+                            ICMPv6ND_NS(tgt='${tgt}')/
+                            ICMPv6NDOptSrcLLAddr(lladdr='${hsrc}')")
+    echo $packet
+}
+
 aging_th=10
 net_add n1
 sim_add hv1
@@ -36262,8 +36287,8 @@ check ovn-nbctl                                         
                    \
     -- ls-add ls2                                                           \
     -- lr-add lr                                                            \
     -- set logical_router lr options:mac_binding_age_threshold=$aging_th    \
-    -- lrp-add lr lr-ls1 00:00:00:00:10:00 192.168.10.1/24                  \
-    -- lrp-add lr lr-ls2 00:00:00:00:20:00 192.168.20.1/24                  \
+    -- lrp-add lr lr-ls1 00:00:00:00:10:00 192.168.10.1/24 fd11::1/64       \
+    -- lrp-add lr lr-ls2 00:00:00:00:20:00 192.168.20.1/24 fd12::1/64       \
     -- lsp-add ls1 ls1-lr                                                   \
     -- lsp-set-type ls1-lr router                                           \
     -- lsp-set-addresses ls1-lr router                                      \
@@ -36342,6 +36367,32 @@ send_udp hv1 vif2 00:00:00:00:20:00 00:00:00:00:10:2b 
192.168.10.100 192.168.20.
 OVN_CHECK_PACKETS_CONTAIN([hv1/vif2-tx.pcap], [expected1])
 OVN_CHECK_PACKETS_CONTAIN([hv1/vif1-tx.pcap], [expected2])
 
+wait_row_count mac_binding 0
+# Send UDP6 traffic.
+send_udp6 hv1 vif1 00:00:00:00:10:00 00:00:00:00:10:2a fd12::64 fd11::64
+send_udp6 hv1 vif2 00:00:00:00:20:00 00:00:00:00:10:2b fd11::64 fd12::64
+# Send NA to resolve L2 addresses.
+send_na hv1 vif1 00:00:00:00:10:00 00:00:00:00:10:1a fd11::1 fd11::64
+send_na hv1 vif2 00:00:00:00:20:00 00:00:00:00:10:1b fd12::1 fd12::64
+
+check_row_count mac_binding 1 mac=\"00:00:00:00:10:1a\" ip=\"fd11::64\"
+check_row_count mac_binding 1 mac=\"00:00:00:00:10:1b\" ip=\"fd12::64\"
+
+ts0=$(fetch_column Mac_Binding timestamp mac=\"00:00:00:00:10:1a\" 
ip=\"fd11::64\")
+uuid=$(fetch_column Mac_Binding _uuid mac=\"00:00:00:00:10:1a\" 
ip=\"fd11::64\")
+OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
| \
+                       awk '/ipv6_src=fd11::64/{print substr($6,10,1)}') -ge 
$((aging_th/2))])
+send_udp6 hv1 vif1 00:00:00:00:10:00 00:00:00:00:10:2a fd12::64 fd11::64
+send_udp6 hv1 vif2 00:00:00:00:20:00 00:00:00:00:10:2b fd11::64 fd12::64
+
+dump_ns 33:33:ff:00:00:64 00:00:00:00:10:00 ff02::1:ff00:64 fd11::1 fd11::64 > 
expected2
+dump_ns 33:33:ff:00:00:64 00:00:00:00:10:00 ff02::1:ff00:64 fd11::1 fd11::64 
>> expected2
+OVN_CHECK_PACKETS_CONTAIN([hv1/vif1-tx.pcap], [expected2])
+
+send_na hv1 vif1 00:00:00:00:10:00 00:00:00:00:10:1a fd11::1 fd11::64
+OVS_WAIT_UNTIL([test $(fetch_column Mac_Binding timestamp 
mac=\"00:00:00:00:10:1a\" ip=\"fd11::64\") -gt $ts0])
+AT_CHECK([test "$(fetch_column Mac_Binding _uuid mac=\"00:00:00:00:10:1a\" 
ip=\"fd11::64\")" = "$uuid"])
+
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
@@ -36358,6 +36409,22 @@ send_imcp_echo_req() {
     as $hv ovs-appctl netdev-dummy/receive $dev $packet
 }
 
+send_icmp6_echo_req() {
+    local hv=$1 dev=$2 hdst=$3 hsrc=$4 idst=$5 isrc=$6
+    local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
+                            IPv6(dst='${idst}', 
src='${isrc}')/ICMPv6EchoRequest()")
+    as $hv ovs-appctl netdev-dummy/receive $dev $packet
+}
+
+send_na() {
+    local hv=$1 dev=$2 hdst=$3 hsrc=$4 idst=$5 isrc=$6
+    local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
+                            IPv6(dst='${idst}', src='${isrc}')/ \
+                            ICMPv6ND_NA(tgt='${isrc}')/ \
+                            ICMPv6NDOptDstLLAddr(lladdr='${hsrc}')")
+    as $hv ovs-appctl netdev-dummy/receive $dev $packet
+}
+
 dump_icmp() {
     local hdst=$1 hsrc=$2 idst=$3 isrc=$4 ttl=$5 type=$6 chksum=$7
     local packet=$(fmt_pkt "Ether(dst='${hdst}', src='${hsrc}')/ \
@@ -36383,8 +36450,8 @@ check ovn-nbctl                                         
                    \
     -- set Logical_Router gw options:chassis="hv1"                          \
     -- set logical_router gw options:mac_binding_age_threshold=$aging_th    \
     -- set logical_router gw options:dynamic_neigh_routers=true             \
-    -- lrp-add gw gw-public 00:00:00:00:10:00 192.168.10.1/24               \
-    -- lrp-add gw gw-join 00:00:00:00:20:00 192.168.20.1/24                 \
+    -- lrp-add gw gw-public 00:00:00:00:10:00 192.168.10.1/24 fd11::1/64    \
+    -- lrp-add gw gw-join 00:00:00:00:20:00 192.168.20.1/24 fd12::1/64      \
     -- lsp-add public public-gw                                             \
     -- lsp-set-type public-gw router                                        \
     -- lsp-set-addresses public-gw router                                   \
@@ -36395,12 +36462,13 @@ check ovn-nbctl                                       
                      \
     -- lsp-set-type join-gw router                                          \
     -- lsp-set-addresses join-gw router                                     \
     -- lsp-set-options join-gw router-port=gw-join                          \
-    -- lrp-add lr lr-join 00:00:00:00:30:00 192.168.20.2/24                 \
+    -- lrp-add lr lr-join 00:00:00:00:30:00 192.168.20.2/24 fd12::2/64      \
     -- lsp-add join join-lr                                                 \
     -- lsp-set-type join-lr router                                          \
     -- lsp-set-addresses join-lr router                                     \
     -- lsp-set-options join-lr router-port=lr-join                          \
-    -- lr-route-add lr 0.0.0.0/0 192.168.20.1
+    -- lr-route-add lr 0.0.0.0/0 192.168.20.1                               \
+    -- lr-route-add lr ::/0 fd12::1
 
 check ovs-vsctl                                                             \
     -- add-port br-int public                                               \
@@ -36433,10 +36501,10 @@ OVS_WAIT_UNTIL([$(ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_BINDING | \
                   sed 
's/reg15=0x.,metadata=0x./reg15=<cleared>,metadata=<cleared>/g' | \
                   grep -q "reg0=0xc0a81402,reg15=<cleared>,metadata=<cleared> 
actions=mod_dl_dst:00:00:00:00:30:00")])
 
+n_arp=$(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE |awk 
'/arp_spa=192.168.20.2/{print substr($4,11,1)}')
 # Check GW router does not send any ARP requests in this case.
 OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
| \
                        awk '/nw_src=192.168.10.100/{print substr($6,10,1)}') 
-ge $((aging_th/2))])
-n_arp=$(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE |awk 
'/arp_spa=192.168.20.2/{print substr($4,11,1)}')
 AT_CHECK([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE |awk 
'/arp_spa=192.168.20.2/{print substr($4,11,1)}') -eq $n_arp])
 
 send_imcp_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.2 
192.168.10.100
@@ -36449,6 +36517,29 @@ OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int 
table=OFTABLE_MAC_CACHE_USE |
 send_imcp_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:10:1a 192.168.20.2 
192.168.10.100
 OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
|awk '/arp_spa=192.168.20.2/{print substr($4,11,1)}') -ge $((n_arp+1))])
 
+check ovn-nbctl --wait=hv acl-del join
+wait_row_count mac_binding 0
+
+send_icmp6_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:50:01 fd12::2 
fd11::64
+send_na hv1 vif1 00:00:00:00:10:00 00:00:00:00:50:01 fd11::1 fd11::64
+check_row_count mac_binding 1 mac=\"00:00:00:00:30:00\" ip=\"fd12::2\"
+
+n_ipv6=$(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE |awk 
'/ipv6_src=fd12::2/{print substr($4,11,1)}')
+OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
| \
+                       awk '/ipv6_src=fd12::2/{print substr($6,10,1)}') -ge 
$((aging_th/2))])
+# Check GW router does not send any NS requests in this case.
+AT_CHECK([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE |awk 
'/ipv6_src=fd12::2/{print substr($4,11,1)}') -eq $n_ipv6])
+send_icmp6_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:50:01 fd12::2 
fd11::64
+
+# Now drop ICMPv6 echo reply in order to force OVN to send NS for the lr mac 
binding entry.
+check ovn-nbctl --wait=hv acl-add join from-lport 1010 'inport == "join-lr" && 
ip6 && icmp6.type == 0x87' allow
+check ovn-nbctl --wait=hv acl-add join from-lport 1000 'inport == "join-lr" && 
icmp' drop
+n_ipv6=$(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE |awk 
'/ipv6_src=fd12::2/{print substr($4,11,1)}')
+OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
| \
+                       awk '/ipv6_src=fd12::2/{print substr($6,10,1)}') -ge 
$((aging_th/2))])
+send_icmp6_echo_req hv1 public 00:00:00:00:10:00 00:00:00:00:50:01 fd12::2 
fd11::64
+OVS_WAIT_UNTIL([test $(ovs-ofctl dump-flows br-int table=OFTABLE_MAC_CACHE_USE 
|awk '/ipv6_src=fd12::2/{print substr($4,11,1)}') -ge $((n_ipv6+1))])
+
 OVN_CLEANUP([hv1])
 AT_CLEANUP
 ])
diff --git a/tests/system-ovn.at b/tests/system-ovn.at
index 55d71248b..8d140954a 100644
--- a/tests/system-ovn.at
+++ b/tests/system-ovn.at
@@ -17277,8 +17277,8 @@ check ovn-nbctl set logical_router lr 
options:mac_binding_age_threshold=5
 check ovn-nbctl ls-add sw
 check ovn-nbctl ls-add public
 
-check ovn-nbctl lrp-add lr rp-sw 00:00:01:01:02:03 192.168.1.1/24
-check ovn-nbctl lrp-add lr rp-public 00:00:02:01:02:03 172.16.1.1/24
+check ovn-nbctl lrp-add lr rp-sw 00:00:01:01:02:03 192.168.1.1/24 fd11::1/64
+check ovn-nbctl lrp-add lr rp-public 00:00:02:01:02:03 172.16.1.1/24 fd12::1/64
 
 check ovn-nbctl lsp-add sw sw-rp -- set Logical_Switch_Port sw-rp \
     type=router options:router-port=rp-sw \
@@ -17290,7 +17290,9 @@ check ovn-nbctl lsp-add public public-rp -- set 
Logical_Switch_Port public-rp \
 
 ADD_NAMESPACES(alice)
 ADD_VETH(alice, alice, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", 
"192.168.1.1")
-check ovn-nbctl lsp-add sw alice -- lsp-set-addresses alice "f0:00:00:01:02:03 
192.168.1.2"
+NS_CHECK_EXEC([alice], [ip a a fd11::2/64 dev alice nodad])
+NS_CHECK_EXEC([alice], [ip -6 route add default via fd11::1])
+check ovn-nbctl lsp-add sw alice -- lsp-set-addresses alice "f0:00:00:01:02:03 
192.168.1.2 fd11::2"
 
 check ovs-vsctl set Open_vSwitch . 
external-ids:ovn-bridge-mappings=phynet:br-ext
 check ovn-nbctl lsp-add public public \
@@ -17300,16 +17302,25 @@ check ovn-nbctl lsp-add public public \
 
 ADD_NAMESPACES(gw)
 ADD_VETH(gw0, gw, br-ext, "172.16.1.2/24", "f0:00:00:01:02:04", "172.16.1.1")
+NS_CHECK_EXEC([gw], [ip a a fd12::2/64 dev gw0 nodad])
+NS_CHECK_EXEC([gw], [ip -6 route add default via fd12::1])
 ADD_VETH(gw1, gw, br-gw, "172.16.2.2/24", "f0:00:00:01:03:04")
+NS_CHECK_EXEC([gw], [ip a a fd13::2/64 dev gw1 nodad])
 
 NS_CHECK_EXEC([gw], [sysctl -w net.ipv4.conf.all.forwarding=1],[0], [dnl
 net.ipv4.conf.all.forwarding = 1
 ])
+NS_CHECK_EXEC([gw], [sysctl -w net.ipv6.conf.all.forwarding=1],[0], [dnl
+net.ipv6.conf.all.forwarding = 1
+])
 
 ADD_NAMESPACES(bob)
 ADD_VETH(bob, bob, br-gw, "172.16.2.10/24", "f0:00:00:01:02:06", "172.16.2.2")
+NS_CHECK_EXEC([bob], [ip a a fd13::a/64 dev bob nodad])
+NS_CHECK_EXEC([bob], [ip -6 route add default via fd13::2])
 
 check ovn-nbctl lr-route-add lr 0.0.0.0/0 172.16.1.2
+check ovn-nbctl lr-route-add lr ::/0 fd12::2
 check ovn-nbctl --wait=hv sync
 
 NS_CHECK_EXEC([alice], [ping -q -c 3 -i 0.3 -w 2 172.16.2.10 | FORMAT_PING], \
@@ -17337,6 +17348,26 @@ OVS_WAIT_UNTIL([
 # Wait for the mac binding entry to expire.
 wait_row_count MAC_Binding 0
 
+NS_CHECK_EXEC([alice], [ping -6 -q -c 3 -i 0.3 -w 2 fd13::a | FORMAT_PING], \
+[0], [dnl
+3 packets transmitted, 3 received, 0% packet loss, time 0ms
+])
+
+check_row_count mac_binding 1 mac=\"f0:00:00:01:02:04\" ip=\"fd12::2\"
+mac_binding_uuid=$(fetch_column mac_binding _uuid mac=\"f0:00:00:01:02:04\" 
ip=\"fd12::2\")
+NETNS_START_TCPDUMP([gw], [-n -c 2 -i gw0 icmp6 and ip6[[40]] == 0x87], [gw6])
+
+NS_CHECK_EXEC([alice], [ping -6 -q -c 30 -i 0.5 fd13::a | FORMAT_PING], \
+[0], [dnl
+30 packets transmitted, 30 received, 0% packet loss, time 0ms
+])
+
+AT_CHECK([test "$(fetch_column mac_binding _uuid mac=\"f0:00:00:01:02:04\" 
ip=\"fd12::2\")" = "$mac_binding_uuid"])
+OVS_WAIT_UNTIL([
+    n_ns=$(cat gw6.tcpdump | wc -l)
+    test ${n_ns} -ge 2
+])
+
 OVN_CLEANUP_CONTROLLER([hv1])
 
 as ovn-sb
-- 
2.48.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to