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