Modifies the rule responsible for dropping the MLF_LOCAL_ONLY packets
to only drop them if the MLF_OVERRIDE_LOCAL_ONLY bit flag is not there.

This does also include the addition of MLF_OVERRIDE_LOCAL_ONLY bitflag applied
if a router announcement is being sent from either a gateway
or distributed router.

This is part of an ongoing unnumbered BGP effort.
Backport specific patch for v24.03

Signed-off-by: MJ Ponsonby <[email protected]>
---
 controller/physical.c        |   3 +-
 controller/pinctrl.c         |  11 +++-
 include/ovn/logical-fields.h |   3 +
 ovn-architecture.7.xml       |   6 +-
 tests/ovn.at                 | 104 +++++++++++++++++++++++++++++++++++
 5 files changed, 122 insertions(+), 5 deletions(-)

diff --git a/controller/physical.c b/controller/physical.c
index 6d1f48040..21dc0de85 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -1844,7 +1844,8 @@ consider_port_binding(struct ovsdb_idl_index 
*sbrec_port_binding_by_name,
             put_drop(debug, OFTABLE_CHECK_LOOPBACK, ofpacts_p);
             match_outport_dp_and_port_keys(&match, dp_key, port_key);
             match_set_reg_masked(&match, MFF_LOG_FLAGS - MFF_REG0,
-                                 MLF_LOCAL_ONLY, MLF_LOCAL_ONLY);
+                                 MLF_LOCAL_ONLY,
+                                 MLF_LOCAL_ONLY | MLF_OVERRIDE_LOCAL_ONLY);
             ofctrl_add_flow(flow_table, OFTABLE_CHECK_LOOPBACK, 160,
                             binding->header_.uuid.parts[0], &match,
                             ofpacts_p, &binding->header_.uuid);
diff --git a/controller/pinctrl.c b/controller/pinctrl.c
index 5f66be537..c222d02b7 100644
--- a/controller/pinctrl.c
+++ b/controller/pinctrl.c
@@ -3684,6 +3684,7 @@ struct ipv6_ra_state {
     struct ipv6_ra_config *config;
     int64_t port_key;
     int64_t metadata;
+    bool preserved;
     bool delete_me;
 };
 
@@ -4015,6 +4016,9 @@ ipv6_ra_send(struct rconn *swconn, struct ipv6_ra_state 
*ra)
     put_load(dp_key, MFF_LOG_DATAPATH, 0, 64, &ofpacts);
     put_load(port_key, MFF_LOG_INPORT, 0, 32, &ofpacts);
     put_load(1, MFF_LOG_FLAGS, MLF_LOCAL_ONLY_BIT, 1, &ofpacts);
+    if (ra->preserved) {
+        put_load(1, MFF_LOG_FLAGS, MLF_OVERRIDE_LOCAL_ONLY_BIT, 1, &ofpacts);
+    }
     struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts);
     resubmit->in_port = OFPP_CONTROLLER;
     resubmit->table_id = OFTABLE_LOG_INGRESS_PIPELINE;
@@ -4125,8 +4129,11 @@ prepare_ipv6_ras(const struct shash 
*local_active_ports_ras,
          * router port is connected to. The RA is injected
          * into that logical switch port.
          */
-        ra->port_key = peer->tunnel_key;
-        ra->metadata = peer->datapath->tunnel_key;
+        ra->port_key  = peer->tunnel_key;
+        ra->metadata  = peer->datapath->tunnel_key;
+        ra->preserved = (!strcmp(pb->type,"l2gateway") ||
+                        !strcmp(pb->type,"l3gateway") ||
+                        !strcmp(pb->type,"chassisredirect"));
         ra->delete_me = false;
 
         /* pinctrl_handler thread will send the IPv6 RAs. */
diff --git a/include/ovn/logical-fields.h b/include/ovn/logical-fields.h
index bcd3fd1f9..f8c184081 100644
--- a/include/ovn/logical-fields.h
+++ b/include/ovn/logical-fields.h
@@ -87,6 +87,7 @@ enum mff_log_flags_bits {
     MLF_LOCALNET_BIT = 15,
     MLF_RX_FROM_TUNNEL_BIT = 16,
     MLF_ICMP_SNAT_BIT = 17,
+    MLF_OVERRIDE_LOCAL_ONLY_BIT = 18,
 };
 
 /* MFF_LOG_FLAGS_REG flag assignments */
@@ -142,6 +143,8 @@ enum mff_log_flags {
     MLF_RX_FROM_TUNNEL = (1 << MLF_RX_FROM_TUNNEL_BIT),
 
     MLF_ICMP_SNAT = (1 << MLF_ICMP_SNAT_BIT),
+
+    MLF_OVERRIDE_LOCAL_ONLY = (1 << MLF_OVERRIDE_LOCAL_ONLY_BIT),
 };
 
 /* OVN logical fields
diff --git a/ovn-architecture.7.xml b/ovn-architecture.7.xml
index bfd8680ce..243c5b21b 100644
--- a/ovn-architecture.7.xml
+++ b/ovn-architecture.7.xml
@@ -1546,8 +1546,10 @@
       <p>
         Table 41 matches and drops packets for which the logical input and
         output ports are the same and the MLF_ALLOW_LOOPBACK flag is not
-        set. It also drops MLF_LOCAL_ONLY packets directed to a localnet port.
-        It resubmits other packets to table 42.
+        set. It also drops MLF_LOCAL_ONLY packets directed to a localnet port,
+        provided they aren't RAs sent from a gateway or distributed router
+        which is checked via the presence of the bitflag
+        MLF_OVERRIDE_LOCAL_ONLY. It resubmits other packets to table 42.
       </p>
     </li>
 
diff --git a/tests/ovn.at b/tests/ovn.at
index 1c68a315e..6320abe47 100644
--- a/tests/ovn.at
+++ b/tests/ovn.at
@@ -17024,6 +17024,110 @@ OVN_CLEANUP([hv1],[hv2])
 AT_CLEANUP
 ])
 
+
+OVN_FOR_EACH_NORTHD([
+AT_SETUP([IPv6 periodic gateway RA enabled 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 -- set Logical_Router ro options:chassis="hv1"
+check ovn-nbctl lrp-add ro ro-sw 00:00:00:00:00:01 20.0.0.1/24
+
+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"
+
+AT_CHECK([ovn-sbctl get Port_Binding ro-sw type | tr -d '\n'],[0],[l3gateway])
+
+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=1
+check ovn-nbctl set Logical_Router_Port ro-sw ipv6_ra_configs:min_interval=1
+
+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
+
+wait_for_ports_up
+
+ra_received() {
+    $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $1 | sed '/^ffffffffffff/d' | 
wc -l
+}
+
+ra_test() {
+    interface=$1
+    shift 1
+    local ra_packet=$(fmt_pkt "
+        Ether(src='00:00:00:00:00:01', dst='33:33:00:00:00:01') /
+        IPv6(dst='ff02::1', src='fe80::200:ff:fe00:1') /
+        ICMPv6ND_RA(chlim=255, prf=0, routerlifetime=65535) /
+        ICMPv6NDOptSrcLLAddr(lladdr='00:00:00:00:00:01')
+    ")
+    intname="$interface"
+
+    for i in hv1 hv2 ; do
+        if echo "$interface" | grep -q -v "br"; then
+            intname="$i-$interface"
+        fi
+        echo $intname
+        as $i reset_pcap_file $intname $i/$interface
+
+        OVS_WAIT_WHILE([test 0 = $(ra_received $i/$interface-tx.pcap)])
+
+        $PYTHON "$ovs_srcdir/utilities/ovs-pcap.in" $i/$interface-tx.pcap > 
packets
+        sed -i '/^ffffffffffff/d' packets
+
+        echo ${ra_packet} | cut -c -112 > expout
+        AT_CHECK([head -1 packets | cut -c -112], [0], [expout])
+
+        # Skip ICMPv6 checksum.
+        echo ${ra_packet} | cut -c 117- > expout
+        AT_CHECK([head -1 packets | cut -c 117-], [0], [expout])
+
+        rm -f packets
+        as $i reset_pcap_file $intname $i/$interface
+    done
+
+    rm -f expected
+}
+
+# check that RAs are sent
+ra_test vif1
+
+# check that RAs are recived on br-phys
+ra_test br-phys
+
+OVN_CLEANUP([hv1],[hv2])
+AT_CLEANUP
+])
+
 OVN_FOR_EACH_NORTHD([
 AT_SETUP([ACL reject rule test])
 AT_KEYWORDS([acl-reject])
-- 
2.43.0

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

Reply via email to