* where we can't otherwise provide revalidation feedback to the client.
* That's only unixctl commands now; I hope no other cases will arise. */
struct tag_set unixctl_tags;
+
+ int ref_cnt;
};
static struct hmap all_bonds = HMAP_INITIALIZER(&all_bonds);
static tag_type bond_get_active_slave_tag(const struct bond *);
static struct bond_slave *choose_output_slave(const struct bond *,
const struct flow *,
+ struct flow_wildcards *,
uint16_t vlan, tag_type *tags);
static void bond_update_fake_slave_stats(struct bond *);
hmap_init(&bond->slaves);
bond->no_slaves_tag = tag_create_random();
bond->next_fake_iface_update = LLONG_MAX;
+ bond->ref_cnt = 1;
bond_reconfigure(bond, s);
return bond;
}
+struct bond *
+bond_ref(const struct bond *bond_)
+{
+ struct bond *bond = CONST_CAST(struct bond *, bond_);
+
+ ovs_assert(bond->ref_cnt > 0);
+ bond->ref_cnt++;
+ return bond;
+}
+
/* Frees 'bond'. */
void
-bond_destroy(struct bond *bond)
+bond_unref(struct bond *bond)
{
struct bond_slave *slave, *next_slave;
return;
}
+ ovs_assert(bond->ref_cnt > 0);
+ if (--bond->ref_cnt) {
+ return;
+ }
+
hmap_remove(&all_bonds, &bond->hmap_node);
HMAP_FOR_EACH_SAFE (slave, next_slave, hmap_node, &bond->slaves) {
memset(&flow, 0, sizeof flow);
memcpy(flow.dl_src, eth_src, ETH_ADDR_LEN);
- slave = choose_output_slave(bond, &flow, vlan, &tags);
+ slave = choose_output_slave(bond, &flow, NULL, vlan, &tags);
packet = ofpbuf_new(0);
compose_rarp(packet, eth_src);
* packet belongs to (so for an access port it will be the access port's VLAN).
*
* Adds a tag to '*tags' that associates the flow with the returned slave.
+ *
+ * If 'wc' is non-NULL, bitwise-OR's 'wc' with the set of bits that were
+ * significant in the selection. At some point earlier, 'wc' should
+ * have been initialized (e.g., by flow_wildcards_init_catchall()).
*/
void *
bond_choose_output_slave(struct bond *bond, const struct flow *flow,
- uint16_t vlan, tag_type *tags)
+ struct flow_wildcards *wc, uint16_t vlan,
+ tag_type *tags)
{
- struct bond_slave *slave = choose_output_slave(bond, flow, vlan, tags);
+ struct bond_slave *slave = choose_output_slave(bond, flow, wc, vlan, tags);
if (slave) {
*tags |= slave->tag;
return slave->aux;
if (enable != slave->enabled) {
slave->enabled = enable;
if (!slave->enabled) {
- VLOG_WARN("interface %s: disabled", slave->name);
+ VLOG_INFO("interface %s: disabled", slave->name);
if (tags) {
tag_set_add(tags, slave->tag);
}
} else {
- VLOG_WARN("interface %s: enabled", slave->name);
+ VLOG_INFO("interface %s: enabled", slave->name);
slave->tag = tag_create_random();
}
}
static struct bond_slave *
choose_output_slave(const struct bond *bond, const struct flow *flow,
- uint16_t vlan, tag_type *tags)
+ struct flow_wildcards *wc, uint16_t vlan, tag_type *tags)
{
struct bond_entry *e;
/* Must have LACP negotiations for TCP balanced bonds. */
return NULL;
}
+ if (wc) {
+ flow_mask_hash_fields(wc, NX_HASH_FIELDS_SYMMETRIC_L4);
+ }
/* Fall Through. */
case BM_SLB:
+ if (wc) {
+ flow_mask_hash_fields(wc, NX_HASH_FIELDS_ETH_SRC);
+ }
e = lookup_bond_entry(bond, flow, vlan);
if (!e->slave || !e->slave->enabled) {
e->slave = CONTAINER_OF(hmap_random_node(&bond->slaves),
bond->send_learning_packets = true;
} else if (old_active_slave) {
- VLOG_WARN_RL(&rl, "bond %s: all interfaces disabled", bond->name);
+ VLOG_INFO_RL(&rl, "bond %s: all interfaces disabled", bond->name);
}
}