This config param allows the delivery of broadcast and multicast packets
to the secondary interface of non-lacp bonds, equivalent to the option
"all_slaves_active" for Linux kernel bonds.

Reported-at: https://bugzilla.redhat.com/show_bug.cgi?id=1720935
Signed-off-by: Christophe Fontaine <[email protected]>
---
 NEWS                  |   2 +
 ofproto/bond.c        |  10 +++-
 ofproto/bond.h        |   3 +
 tests/ofproto-dpif.at | 132 ++++++++++++++++++++++++++++++++++++++++++
 vswitchd/bridge.c     |   3 +
 vswitchd/vswitch.xml  |  20 +++++++
 6 files changed, 169 insertions(+), 1 deletion(-)

diff --git a/NEWS b/NEWS
index 994fdf6a9..165ad4b8b 100644
--- a/NEWS
+++ b/NEWS
@@ -43,6 +43,8 @@ Post-v2.17.0
      * 'dpif-netdev/subtable-lookup-prio-get' appctl command renamed to
        'dpif-netdev/subtable-lookup-info-get' to better reflect its purpose.
        The old variant is kept for backward compatibility.
+   - bond:
+     * Added new configuration knob 'all_members_active' for non lacp bonds.
 
 
 v2.17.0 - 17 Feb 2022
diff --git a/ofproto/bond.c b/ofproto/bond.c
index 845f69e21..0603844f3 100644
--- a/ofproto/bond.c
+++ b/ofproto/bond.c
@@ -125,6 +125,8 @@ struct bond {
     uint32_t basis;             /* Basis for flow hash function. */
     bool use_lb_output_action;  /* Use lb_output action to avoid recirculation.
                                    Applicable only for Balance TCP mode. */
+    bool all_members_active;    /* Accept multicast packets on secondary
+                                   members of a non-LACP Balance SLB bond. */
     char *primary;              /* Name of the primary member. */
 
     /* SLB specific bonding info. */
@@ -448,6 +450,7 @@ bond_reconfigure(struct bond *bond, const struct 
bond_settings *s)
 
     bond->updelay = s->up_delay;
     bond->downdelay = s->down_delay;
+    bond->all_members_active = s->all_members_active;
 
     if (bond->lacp_fallback_ab != s->lacp_fallback_ab_cfg) {
         bond->lacp_fallback_ab = s->lacp_fallback_ab_cfg;
@@ -893,7 +896,7 @@ bond_check_admissibility(struct bond *bond, const void 
*member_,
 
     /* Drop all multicast packets on inactive members. */
     if (eth_addr_is_multicast(eth_dst)) {
-        if (bond->active_member != member) {
+        if (bond->active_member != member && !bond->all_members_active) {
             goto out;
         }
     }
@@ -1495,6 +1498,11 @@ bond_print_details(struct ds *ds, const struct bond 
*bond)
                   use_lb_output_action ? "enabled" : "disabled",
                   use_lb_output_action ? recirc_id : -1);
 
+    if(bond->balance == BM_SLB ) {
+        ds_put_format(ds, "all members active: %s\n",
+                      bond->all_members_active ? "true" : "false");
+    }
+
     ds_put_format(ds, "updelay: %d ms\n", bond->updelay);
     ds_put_format(ds, "downdelay: %d ms\n", bond->downdelay);
 
diff --git a/ofproto/bond.h b/ofproto/bond.h
index 1683ec878..2eb0c95a7 100644
--- a/ofproto/bond.h
+++ b/ofproto/bond.h
@@ -62,6 +62,9 @@ struct bond_settings {
                                    ovs run. */
     bool use_lb_output_action;  /* Use lb_output action. Only applicable for
                                    bond mode BALANCE TCP. */
+    bool all_members_active;    /* Accept multicast packets on secondary
+                                   interface. Only applicable for non-LACP
+                                   BALANCE SLB bond mode. */
 };
 
 /* Program startup. */
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
index 2c18e094d..0ea549b43 100644
--- a/tests/ofproto-dpif.at
+++ b/tests/ofproto-dpif.at
@@ -591,6 +591,138 @@ NXST_FLOW reply:
 OVS_VSWITCHD_STOP()
 AT_CLEANUP
 
+
+AT_SETUP([bond - discard duplicated frames])
+dnl With an active/active non-lacp bond, the default behaviour
+dnl is to discard multicast frames on the secondary interface.
+OVS_VSWITCHD_START([dnl
+        add-bond br0 bond0 p1 p2 -- dnl
+        set Port bond0 bond-mode=balance-slb 
other-config:bond-rebalance-interval=0 -- dnl
+        set Interface p1 type=dummy ofport_request=1 -- dnl
+        set Interface p2 type=dummy ofport_request=2 ])
+
+AT_CHECK([ovs-appctl bond/set-active-member bond0 p1], [0], [ignore])
+AT_CHECK([ovs-ofctl add-flow br0 actions=NORMAL])
+
+AT_CHECK([ovs-appctl bond/show bond0 | STRIP_ACTIVE_MEMBER_MAC], [0], [dnl
+---- bond0 ----
+bond_mode: balance-slb
+bond may use recirculation: no, Recirc-ID : -1
+bond-hash-basis: 0
+lb_output action: disabled, bond-id: -1
+all members active: false
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: off
+lacp_fallback_ab: false
+active-backup primary: <none>
+<active member mac del>
+
+member p1: enabled
+  active member
+  may_enable: true
+
+member p2: enabled
+  may_enable: true
+
+])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff], 
[0], [dnl
+Flow: 
in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+
+bridge("br0")
+-------------
+ 0. priority 32768
+    NORMAL
+     -> no learned MAC for destination, flooding
+
+Final flow: unchanged
+Megaflow: 
recirc_id=0,eth,in_port=1,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+Datapath actions: 100
+])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=2,dl_dst=ff:ff:ff:ff:ff:ff], 
[0], [dnl
+Flow: 
in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+
+bridge("br0")
+-------------
+ 0. priority 32768
+    NORMAL
+     -> bonding refused admissibility, dropping
+
+Final flow: unchanged
+Megaflow: 
recirc_id=0,eth,in_port=2,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+Datapath actions: drop
+])
+OVS_VSWITCHD_STOP()
+AT_CLEANUP
+
+AT_SETUP([bond - allow duplicated frames])
+dnl Receiving of duplicated multicast frames should be allowed with 
'all_members_active'.
+OVS_VSWITCHD_START([dnl
+        add-bond br0 bond0 p1 p2 -- dnl
+        set Port bond0 bond-mode=balance-slb 
other-config:bond-rebalance-interval=0 dnl
+                        other_config:all_members_active=true -- dnl
+        set Interface p1 type=dummy ofport_request=1 -- dnl
+        set Interface p2 type=dummy ofport_request=2])
+
+AT_CHECK([ovs-appctl bond/set-active-member bond0 p1], [0], [ignore])
+AT_CHECK([ovs-ofctl add-flow br0 actions=NORMAL])
+
+OVS_WAIT_UNTIL_EQUAL([ovs-appctl bond/show bond0 | STRIP_ACTIVE_MEMBER_MAC], 
[dnl
+---- bond0 ----
+bond_mode: balance-slb
+bond may use recirculation: no, Recirc-ID : -1
+bond-hash-basis: 0
+lb_output action: disabled, bond-id: -1
+all members active: true
+updelay: 0 ms
+downdelay: 0 ms
+lacp_status: off
+lacp_fallback_ab: false
+active-backup primary: <none>
+<active member mac del>
+
+member p1: enabled
+  active member
+  may_enable: true
+
+member p2: enabled
+  may_enable: true
+])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=1,dl_dst=ff:ff:ff:ff:ff:ff], 
[0], [dnl
+Flow: 
in_port=1,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+
+bridge("br0")
+-------------
+ 0. priority 32768
+    NORMAL
+     -> no learned MAC for destination, flooding
+
+Final flow: unchanged
+Megaflow: 
recirc_id=0,eth,in_port=1,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+Datapath actions: 100
+])
+
+AT_CHECK([ovs-appctl ofproto/trace br0 in_port=2,dl_dst=ff:ff:ff:ff:ff:ff], 
[0], [dnl
+Flow: 
in_port=2,vlan_tci=0x0000,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+
+bridge("br0")
+-------------
+ 0. priority 32768
+    NORMAL
+     -> no learned MAC for destination, flooding
+
+Final flow: unchanged
+Megaflow: 
recirc_id=0,eth,in_port=2,dl_src=00:00:00:00:00:00,dl_dst=ff:ff:ff:ff:ff:ff,dl_type=0x0000
+Datapath actions: 100
+])
+
+OVS_VSWITCHD_STOP()
+AT_CLEANUP
+
+
 AT_SETUP([ofproto-dpif - resubmit])
 OVS_VSWITCHD_START
 add_of_ports br0 1 10 11 12 13 14 15 16 17 18 19 20 21
diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
index e328d8ead..b0c01bd71 100644
--- a/vswitchd/bridge.c
+++ b/vswitchd/bridge.c
@@ -4615,6 +4615,9 @@ port_configure_bond(struct port *port, struct 
bond_settings *s)
     s->use_lb_output_action = (s->balance == BM_TCP)
                               && smap_get_bool(&port->cfg->other_config,
                                                "lb-output-action", false);
+    /* all_members_active is disabled by default. */
+    s->all_members_active = smap_get_bool(&port->cfg->other_config,
+                                          "all_members_active", false);
 }
 
 /* Returns true if 'port' is synthetic, that is, if we constructed it locally
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
index cc1dd77ec..a83066229 100644
--- a/vswitchd/vswitch.xml
+++ b/vswitchd/vswitch.xml
@@ -2085,6 +2085,26 @@
         <code>true</code>).
       </column>
 
+      <column name="other_config" key="all_members_active"
+              type='{"type": "boolean"}'>
+        <p>
+          Enable/Disable delivery of broadcast/multicast packets on secondary
+          interface of a balance-slb bond.  Relevant only when
+          <ref column="lacp"/> is <code>off</code>.
+        </p>
+
+        <p>
+          This parameter is identical to <code>all_slaves_active</code> for
+          Linux kernel bonds.  This is useful when we need to share 2 physical
+          functions between an OVS bond and a Linux bond, as 2 LACP sessions
+          can't be negotiated over the same physical link.  LACP session will
+          be managed by the kernel bond, while an active-active bond is used
+          for OVS.  In that particular configuration, the physical switch will
+          send a unique copy of broadcast packets over the 2 physical links,
+          eventually to the secondary link of the bond.
+        </p>
+      </column>
+
       <group title="Link Failure Detection">
         <p>
           An important part of link bonding is detecting that links are down so
-- 
2.36.1

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

Reply via email to