When a router port is attached to a localnet switch, sending periodic RAs through localnet port will confuse upstream router by leaking conflicting router advertisements into datacenter network.
Signed-off-by: Ihar Hrachyshka <[email protected]> --- northd/ovn-northd.c | 5 +- tests/ovn.at | 156 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 160 insertions(+), 1 deletion(-) diff --git a/northd/ovn-northd.c b/northd/ovn-northd.c index a0eaa1247..6cd686d12 100644 --- a/northd/ovn-northd.c +++ b/northd/ovn-northd.c @@ -10207,7 +10207,10 @@ build_ND_RA_flows_for_lrouter_port( if (smap_get_bool(&op->nbrp->ipv6_ra_configs, "send_periodic", false)) { - copy_ra_to_sb(op, address_mode); + /* Don't leak RAs into datacenter networks. */ + if (!op->peer->od->n_localnet_ports) { + copy_ra_to_sb(op, address_mode); + } } ds_clear(match); diff --git a/tests/ovn.at b/tests/ovn.at index 7ae136ad9..22c5ed07c 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -13674,6 +13674,162 @@ OVN_CLEANUP([hv1],[hv2]) AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD([ +AT_SETUP([IPv6 periodic RA disabled for localnet adjacent switch ports]) +ovn_start + +net_add n1 +sim_add hv1 +sim_add hv2 +as hv1 +check ovs-vsctl add-br br-phys +check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys +ovn_attach n1 br-phys 192.168.0.2 +as hv2 +check ovs-vsctl add-br br-phys +check ovs-vsctl set open . external-ids:ovn-bridge-mappings=phys:br-phys +ovn_attach n1 br-phys 192.168.0.3 + +check ovn-nbctl lr-add ro +check ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 aef0:0:0:0:0:0:0:1/64 + +check ovn-nbctl ls-add sw +check ovn-nbctl lsp-add sw ln +check ovn-nbctl lsp-set-addresses ln unknown +check ovn-nbctl lsp-set-type ln localnet +check ovn-nbctl lsp-set-options ln network_name=phys + +check ovn-nbctl lsp-add sw sw-ro +check ovn-nbctl lsp-set-type sw-ro router +check ovn-nbctl lsp-set-options sw-ro router-port=ro-sw +check ovn-nbctl lsp-set-addresses sw-ro 00:00:00:00:00:01 +check ovn-nbctl lsp-add sw sw-p1 +check ovn-nbctl lsp-set-addresses sw-p1 "00:00:00:00:00:02 aef0::200:ff:fe00:2" +check ovn-nbctl lsp-add sw sw-p2 +check ovn-nbctl lsp-set-addresses sw-p2 "00:00:00:00:00:03 aef0::200:ff:fe00:3" + +check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:send_periodic=true +check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:address_mode=slaac +check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:max_interval=4 +check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=3 + +for i in 1 2 ; do + as hv$i + check ovs-vsctl -- add-port br-int hv$i-vif1 -- \ + set interface hv$i-vif1 external-ids:iface-id=sw-p$i \ + options:tx_pcap=hv$i/vif1-tx.pcap \ + options:rxq_pcap=hv$i/vif1-rx.pcap \ + ofport-request=1 +done + +OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p1` = xup]) +OVS_WAIT_UNTIL([test x`ovn-nbctl lsp-get-up sw-p2` = xup]) + +reset_pcap_file() { + local iface=$1 + local pcap_file=$2 + ovs-vsctl -- set Interface $iface options:tx_pcap=dummy-tx.pcap \ +options:rxq_pcap=dummy-rx.pcap + rm -f ${pcap_file}*.pcap + ovs-vsctl -- set Interface $iface options:tx_pcap=${pcap_file}-tx.pcap \ +options:rxq_pcap=${pcap_file}-rx.pcap + +} + +construct_expected_ra() { + local src_mac=000000000001 + local dst_mac=333300000001 + local src_addr=fe80000000000000020000fffe000001 + local dst_addr=ff020000000000000000000000000001 + + local mtu=$1 + local ra_mo=$2 + local rdnss=$3 + local dnssl=$4 + local route_info=$5 + local ra_prefix_la=$6 + + local slla=0101${src_mac} + local mtu_opt="" + if test $mtu != 0; then + mtu_opt=05010000${mtu} + fi + shift 6 + + local prefix="" + while [[ $# -gt 0 ]] ; do + local size=$1 + local net=$2 + prefix=${prefix}0304${size}${ra_prefix_la}ffffffffffffffff00000000${net} + shift 2 + done + + local rdnss_opt="" + if test $rdnss != 0; then + rdnss_opt=19030000ffffffff${rdnss} + fi + local dnssl_opt="" + if test $dnssl != 0; then + dnssl_opt=1f030000ffffffff${dnssl} + fi + local route_info_opt="" + if test $route_info != 0; then + route_info_opt=${route_info} + fi + + local ra=ff${ra_mo}ffff0000000000000000${slla}${mtu_opt}${prefix}${rdnss_opt}${dnssl_opt}${route_info_opt} + local icmp=8600XXXX${ra} + + local ip_len=$(expr ${#icmp} / 2) + ip_len=$(echo "$ip_len" | awk '{printf "%0.4x\n", $0}') + + local ip=60000000${ip_len}3aff${src_addr}${dst_addr}${icmp} + local eth=${dst_mac}${src_mac}86dd${ip} + local packet=${eth} + echo $packet >> expected +} + +ra_test() { + if [[ $1 = 1 ]]; then + shift; construct_expected_ra $@ + else + shift; > expected + fi + + for i in hv1 hv2 ; do + as $i reset_pcap_file $i-vif1 $i/vif1 + + OVS_WAIT_WHILE([test 24 = $(wc -c $i/vif1-tx.pcap | cut -d " " -f1)]) + + $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $i/vif1-tx.pcap > packets + sed -i '/^ffffffffffff/d' packets + + cat expected | cut -c -112 > expout + AT_CHECK([cat packets | cut -c -112], [0], [expout]) + + # Skip ICMPv6 checksum. + cat expected | cut -c 117- > expout + AT_CHECK([cat packets | cut -c 117-], [0], [expout]) + + rm -f packets + as $i reset_pcap_file $i-vif1 $i/vif1 + done + + rm -f expected +} + +# first check that localnet port blocks RAs +ra_test 0 0 00 0 0 0 c0 40 aef00000000000000000000000000000 + +# now remove localnet port and check periodic RAs +check ovn-nbctl lsp-del ln +check ovn-nbctl --wait=hv sync +ra_test 1 0 00 0 0 0 c0 40 aef00000000000000000000000000000 + +OVN_CLEANUP([hv1],[hv2]) +AT_CLEANUP +]) + OVN_FOR_EACH_NORTHD([ AT_SETUP([ACL reject rule test]) AT_KEYWORDS([acl-reject]) -- 2.31.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
