The bonding code is supposed to tag flows two ways:
- According to the chosen bond slave, to make it easy to invalidate all
of the flows assigned to a given slave.
- According to the hash value for a flow, to make it easy to invalidate
all of the flows that hash into the same bucket.
However, the code wasn't actually applying the hash-based tags. This
meant that rebalancing didn't take effect immediately, and so after
rebalancing we could get log messages like this:
inconsistency in subfacet (actions were: 5) (correct actions: 4)
specifying some flow that was moved by the rebalance.
This commit fixes the problem by applying the hash-based tags.
Bug #12847.
Reported-by: Pratap Reddy <preddy@nicira.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Acked-by: Ethan Jackson <ethan@nicira.com>
Peter Balland peter@nicira.com
Peter Phaal peter.phaal@inmon.com
Prabina Pattnaik Prabina.Pattnaik@nechclst.in
Peter Balland peter@nicira.com
Peter Phaal peter.phaal@inmon.com
Prabina Pattnaik Prabina.Pattnaik@nechclst.in
+Pratap Reddy preddy@nicira.com
Ralf Heiringhoff ralf@frosty-geek.net
Ram Jothikumar rjothikumar@nicira.com
Ramana Reddy gtvrreddy@gmail.com
Ralf Heiringhoff ralf@frosty-geek.net
Ram Jothikumar rjothikumar@nicira.com
Ramana Reddy gtvrreddy@gmail.com
static tag_type bond_get_active_slave_tag(const struct bond *);
static struct bond_slave *choose_output_slave(const struct bond *,
const struct flow *,
static tag_type bond_get_active_slave_tag(const struct bond *);
static struct bond_slave *choose_output_slave(const struct bond *,
const struct flow *,
+ uint16_t vlan, tag_type *tags);
static void bond_update_fake_slave_stats(struct bond *);
/* Attempts to parse 's' as the name of a bond balancing mode. If successful,
static void bond_update_fake_slave_stats(struct bond *);
/* Attempts to parse 's' as the name of a bond balancing mode. If successful,
{
struct bond_slave *slave;
struct ofpbuf *packet;
{
struct bond_slave *slave;
struct ofpbuf *packet;
struct flow flow;
assert(may_send_learning_packets(bond));
memset(&flow, 0, sizeof flow);
memcpy(flow.dl_src, eth_src, ETH_ADDR_LEN);
struct flow flow;
assert(may_send_learning_packets(bond));
memset(&flow, 0, sizeof flow);
memcpy(flow.dl_src, eth_src, ETH_ADDR_LEN);
- slave = choose_output_slave(bond, &flow, vlan);
+ slave = choose_output_slave(bond, &flow, vlan, &tags);
packet = ofpbuf_new(0);
compose_rarp(packet, eth_src);
packet = ofpbuf_new(0);
compose_rarp(packet, eth_src);
bond_choose_output_slave(struct bond *bond, const struct flow *flow,
uint16_t vlan, tag_type *tags)
{
bond_choose_output_slave(struct bond *bond, const struct flow *flow,
uint16_t vlan, tag_type *tags)
{
- struct bond_slave *slave = choose_output_slave(bond, flow, vlan);
+ struct bond_slave *slave = choose_output_slave(bond, flow, vlan, tags);
if (slave) {
*tags |= bond->balance == BM_STABLE ? bond->stb_tag : slave->tag;
return slave->aux;
if (slave) {
*tags |= bond->balance == BM_STABLE ? bond->stb_tag : slave->tag;
return slave->aux;
static struct bond_slave *
choose_output_slave(const struct bond *bond, const struct flow *flow,
static struct bond_slave *
choose_output_slave(const struct bond *bond, const struct flow *flow,
+ uint16_t vlan, tag_type *tags)
}
e->tag = tag_create_random();
}
}
e->tag = tag_create_random();
}
return e->slave;
default:
return e->slave;
default: