From 59d7b2b65665d5d0db9a348789f7eba4b3f16d54 Mon Sep 17 00:00:00 2001 From: Ethan Jackson Date: Tue, 12 Apr 2011 17:53:24 -0700 Subject: [PATCH] bond: Reconfigure flows when bond mode changes. 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 | 18 +++++++++++++++--- lib/bond.h | 2 +- vswitchd/bridge.c | 4 +++- 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/bond.c b/lib/bond.c index ccd8a07e..b651d399 100644 --- a/lib/bond.c +++ b/lib/bond.c @@ -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 diff --git a/lib/bond.h b/lib/bond.h index 7e44deea..8d2f8c9e 100644 --- a/lib/bond.h +++ b/lib/bond.h @@ -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); diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 7997402e..26b4f707 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -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) { -- 2.30.2