-/* Copyright (c) 2008, 2009, 2010, 2011 Nicira Networks
+/* Copyright (c) 2008, 2009, 2010, 2011, 2012 Nicira Networks
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
static void bridge_reconfigure_remotes(struct bridge *,
const struct sockaddr_in *managers,
size_t n_managers);
+static void bridge_reconfigure_remotes_late(struct bridge *);
static void bridge_get_all_ifaces(const struct bridge *, struct shash *ifaces);
static void bridge_fetch_dp_ifaces(struct bridge *);
static void bridge_flush(struct bridge *);
HMAP_FOR_EACH (iface, dp_ifidx_node, &br->ifaces) {
iface_update_cfm(iface);
}
+ bridge_reconfigure_remotes_late(br);
}
free(managers);
}
ds_put_format(&ds, "%5d %4d "ETH_ADDR_FMT" %3d\n",
br->ports[e->port]->ifaces[0]->dp_ifidx,
- e->vlan, ETH_ADDR_ARGS(e->mac), mac_entry_age(e));
+ e->vlan, ETH_ADDR_ARGS(e->mac),
+ mac_entry_age(br->ml, e));
}
unixctl_command_reply(conn, 200, ds_cstr(&ds));
ds_destroy(&ds);
br->name = xstrdup(br_cfg->name);
br->cfg = br_cfg;
- br->ml = mac_learning_create();
+ br->ml = mac_learning_create(MAC_ENTRY_DEFAULT_IDLE_TIME);
eth_addr_nicira_random(br->default_ea);
hmap_init(&br->ifaces);
struct svec snoops, old_snoops;
struct shash_node *node;
enum ofproto_fail_mode fail_mode;
+ const char *idle_time_str;
+ int idle_time;
size_t i;
/* Collect old ports. */
}
ofproto_set_fail_mode(br->ofproto, fail_mode);
+ /* Set the MAC learning aging timeout. */
+ idle_time_str = bridge_get_other_config(br->cfg, "mac-aging-time");
+ idle_time = (idle_time_str && atoi(idle_time_str)
+ ? atoi(idle_time_str)
+ : MAC_ENTRY_DEFAULT_IDLE_TIME);
+ mac_learning_set_idle_time(br->ml, idle_time);
+
/* Delete all flows if we're switching from connected to standalone or vice
* versa. (XXX Should we delete all flows if we are switching from one
* controller to another?) */
if (had_primary != ofproto_has_primary_controller(br->ofproto)) {
ofproto_flush_flows(br->ofproto);
}
+}
+/* Does configuration of remotes that must happen after all of the ports and
+ * interfaces are fully configured, that is, when flow translation can be
+ * expected to succeed. (This is because ofproto_add_flow() immediately
+ * re-translates any existing facets for the rule that it replaces, if any.)
+ * In particular, it must be called after port_update_bonding(), to ensure that
+ * 'bond_hash' is non-NULL for bonded ports. */
+static void
+bridge_reconfigure_remotes_late(struct bridge *br)
+{
/* If there are no controllers and the bridge is in standalone
* mode, set up a flow that matches every packet and directs
* them to OFPP_NORMAL (which goes to us). Otherwise, the
* switch is in secure mode and we won't pass any traffic until
* a controller has been defined and it tells us to do so. */
- if (!n_controllers
+ if (!bridge_get_controllers(br, NULL)
&& ofproto_get_fail_mode(br->ofproto) == OFPROTO_FAIL_STANDALONE) {
union ofp_action action;
struct cls_rule rule;
* to the exception is if we locked the learning table to avoid
* reflections on bond slaves. If this is the case, just drop the
* packet now. */
- src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan,
- &is_grat_arp_locked);
- if (src_idx != -1 && src_idx != in_port->port_idx &&
- (!is_gratuitous_arp(flow) || is_grat_arp_locked)) {
+ if (in_port->bond_mode != BM_AB) {
+ src_idx = mac_learning_lookup(br->ml, flow->dl_src, vlan,
+ &is_grat_arp_locked);
+ if (src_idx != -1 && src_idx != in_port->port_idx &&
+ (!is_gratuitous_arp(flow) || is_grat_arp_locked)) {
return false;
+ }
}
}