bond: Reconfigure flows when bond mode changes.
authorEthan Jackson <ethan@nicira.com>
Wed, 13 Apr 2011 00:53:24 +0000 (17:53 -0700)
committerEthan Jackson <ethan@nicira.com>
Wed, 13 Apr 2011 00:53:24 +0000 (17:53 -0700)
Changes in the bonding mode can cause drastic changes in flow
assignments to slaves.  This commit causes all flows in a bridge
to be revalidated when bond_reconfigure() changes its bonding mode.
This approach is a bit aggressive, but bond reconfiguration
shouldn't happen often.

lib/bond.c
lib/bond.h
vswitchd/bridge.c

index ccd8a07e96d8178b89b2cdae94bb65cd823661e5..b651d39917bc1f92ff927c7d684637aab84e802b 100644 (file)
@@ -256,10 +256,16 @@ bond_destroy(struct bond *bond)
  * bond_slave_register().  This is optional if none of the slaves'
  * configuration has changed, except that it is mandatory if 's' enables LACP
  * and 'bond' previously didn't have LACP enabled.  In any case it can't
- * hurt. */
-void
+ * hurt.
+ *
+ * Returns true if the configuration has changed in such a way that requires
+ * flow revalidation.
+ * */
+bool
 bond_reconfigure(struct bond *bond, const struct bond_settings *s)
 {
+    bool revalidate = false;
+
     if (!bond->name || strcmp(bond->name, s->name)) {
         if (bond->name) {
             hmap_remove(&all_bonds, &bond->hmap_node);
@@ -269,13 +275,17 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s)
         hmap_insert(&all_bonds, &bond->hmap_node, hash_string(bond->name, 0));
     }
 
-    bond->balance = s->balance;
     bond->detect = s->detect;
     bond->miimon_interval = s->miimon_interval;
     bond->updelay = s->up_delay;
     bond->downdelay = s->down_delay;
     bond->rebalance_interval = s->rebalance_interval;
 
+    if (bond->balance != s->balance) {
+        bond->balance = s->balance;
+        revalidate = true;
+    }
+
     if (bond->balance != BM_AB) {
         if (!bond->hash) {
             bond->hash = xcalloc(BOND_MASK + 1, sizeof *bond->hash);
@@ -324,6 +334,8 @@ bond_reconfigure(struct bond *bond, const struct bond_settings *s)
     } else {
         bond->next_fake_iface_update = LLONG_MAX;
     }
+
+    return revalidate;
 }
 
 /* Registers 'slave_' as a slave of 'bond'.  The 'slave_' pointer is an
index 7e44deeac65f8e46d574c79095fb48e153f9485c..8d2f8c9ee5226ede08f02023cb07b9a9d16eaeef 100644 (file)
@@ -75,7 +75,7 @@ void bond_init(void);
 struct bond *bond_create(const struct bond_settings *);
 void bond_destroy(struct bond *);
 
-void bond_reconfigure(struct bond *, const struct bond_settings *);
+bool bond_reconfigure(struct bond *, const struct bond_settings *);
 void bond_slave_register(struct bond *, void *slave_, struct netdev *,
                          const struct lacp_slave_settings *);
 void bond_slave_unregister(struct bond *, const void *slave);
index 7997402e1c6e6a934ef00ad9d6891382d4097ee3..26b4f707524a5505f65544603a829c9de0272166 100644 (file)
@@ -3107,7 +3107,9 @@ port_reconfigure_bond(struct port *port)
     if (!port->bond) {
         port->bond = bond_create(&s);
     } else {
-        bond_reconfigure(port->bond, &s);
+        if (bond_reconfigure(port->bond, &s)) {
+            bridge_flush(port->bridge);
+        }
     }
 
     LIST_FOR_EACH (iface, port_elem, &port->ifaces) {