static void bridge_del_ofproto_ports(struct bridge *);
static void bridge_refresh_ofp_port(struct bridge *);
static void bridge_configure_datapath_id(struct bridge *);
+static void bridge_configure_flow_eviction_threshold(struct bridge *);
static void bridge_configure_netflow(struct bridge *);
static void bridge_configure_sflow(struct bridge *, int *sflow_bridge_number);
static void bridge_configure_remotes(struct bridge *,
{
/* Create connection to database. */
idl = ovsdb_idl_create(remote, &ovsrec_idl_class, true);
+ ovsdb_idl_set_lock(idl, "ovs_vswitchd");
ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_cur_cfg);
ovsdb_idl_omit_alert(idl, &ovsrec_open_vswitch_col_statistics);
}
bridge_configure_mirrors(br);
bridge_configure_datapath_id(br);
+ bridge_configure_flow_eviction_threshold(br);
bridge_configure_remotes(br, managers, n_managers);
bridge_configure_netflow(br);
bridge_configure_sflow(br, &sflow_bridge_number);
struct ofproto_port ofproto_port;
LIST_FOR_EACH_SAFE (iface, next_iface, port_elem, &port->ifaces) {
- struct shash args;
int error;
- /* Open the netdev or reconfigure it. */
- shash_init(&args);
- shash_from_ovs_idl_map(iface->cfg->key_options,
- iface->cfg->value_options,
- iface->cfg->n_options, &args);
+ /* Open the netdev. */
if (!iface->netdev) {
- struct netdev_options options;
- options.name = iface->name;
- options.type = iface->type;
- options.args = &args;
- options.ethertype = NETDEV_ETH_TYPE_NONE;
- error = netdev_open(&options, &iface->netdev);
+ error = netdev_open(iface->name, iface->type, &iface->netdev);
+ if (error) {
+ VLOG_WARN("could not open network device %s (%s)",
+ iface->name, strerror(error));
+ }
} else {
- error = netdev_set_config(iface->netdev, &args);
- }
- shash_destroy(&args);
- if (error) {
- VLOG_WARN("could not %s network device %s (%s)",
- iface->netdev ? "reconfigure" : "open",
- iface->name, strerror(error));
+ error = 0;
}
- /* Populate stats columns in new Interface rows. */
- if (iface->netdev && !iface->cfg->mtu) {
- iface_refresh_stats(iface);
- iface_refresh_status(iface);
+ /* Configure the netdev. */
+ if (iface->netdev) {
+ struct shash args;
+
+ shash_init(&args);
+ shash_from_ovs_idl_map(iface->cfg->key_options,
+ iface->cfg->value_options,
+ iface->cfg->n_options, &args);
+ error = netdev_set_config(iface->netdev, &args);
+ shash_destroy(&args);
+
+ if (error) {
+ VLOG_WARN("could not configure network device %s (%s)",
+ iface->name, strerror(error));
+ netdev_close(iface->netdev);
+ iface->netdev = NULL;
+ }
}
/* Add the port, if necessary. */
}
}
- /* Delete the iface if */
+ /* Populate stats columns in new Interface rows. */
+ if (iface->netdev && !iface->cfg->mtu) {
+ iface_refresh_stats(iface);
+ iface_refresh_status(iface);
+ }
+
+ /* Delete the iface if we failed. */
if (iface->netdev && iface->ofp_port >= 0) {
VLOG_DBG("bridge %s: interface %s is on port %d",
br->name, iface->name, iface->ofp_port);
if (port_is_bond_fake_iface(port)) {
if (ofproto_port_query_by_name(br->ofproto, port->name,
&ofproto_port)) {
- struct netdev_options options;
struct netdev *netdev;
int error;
- options.name = port->name;
- options.type = "internal";
- options.args = NULL;
- options.ethertype = NETDEV_ETH_TYPE_NONE;
- error = netdev_open(&options, &netdev);
+ error = netdev_open(port->name, "internal", &netdev);
if (!error) {
ofproto_port_add(br->ofproto, netdev, NULL);
netdev_close(netdev);
&ovsrec_bridge_col_other_config, key);
}
+/* Set Flow eviction threshold */
+static void
+bridge_configure_flow_eviction_threshold(struct bridge *br)
+{
+ const char *threshold_str;
+ unsigned threshold;
+
+ threshold_str = bridge_get_other_config(br->cfg, "flow-eviction-threshold");
+ if (threshold_str) {
+ threshold = strtoul(threshold_str, NULL, 10);
+ } else {
+ threshold = OFPROTO_FLOW_EVICTON_THRESHOLD_DEFAULT;
+ }
+ ofproto_set_flow_eviction_threshold(br->ofproto, threshold);
+}
+
static void
bridge_pick_local_hw_addr(struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
struct iface **hw_addr_iface)
bool database_changed;
struct bridge *br;
+ /* (Re)configure if necessary. */
+ database_changed = ovsdb_idl_run(idl);
+ if (ovsdb_idl_is_lock_contended(idl)) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
+ struct bridge *br, *next_br;
+
+ VLOG_ERR_RL(&rl, "another ovs-vswitchd process is running, "
+ "disabling this process until it goes away");
+
+ HMAP_FOR_EACH_SAFE (br, next_br, node, &all_bridges) {
+ bridge_destroy(br);
+ }
+ return;
+ } else if (!ovsdb_idl_has_lock(idl)) {
+ return;
+ }
+ cfg = ovsrec_open_vswitch_first(idl);
+
/* Let each bridge do the work that it needs to do. */
datapath_destroyed = false;
HMAP_FOR_EACH (br, node, &all_bridges) {
}
}
- /* (Re)configure if necessary. */
- database_changed = ovsdb_idl_run(idl);
- cfg = ovsrec_open_vswitch_first(idl);
-
/* Re-configure SSL. We do this on every trip through the main loop,
* instead of just when the database changes, because the contents of the
* key and certificate files can change without the database changing.
void
bridge_wait(void)
{
- struct bridge *br;
-
- HMAP_FOR_EACH (br, node, &all_bridges) {
- ofproto_wait(br->ofproto);
- }
ovsdb_idl_wait(idl);
- poll_timer_wait_until(stats_timer);
+ if (!hmap_is_empty(&all_bridges)) {
+ struct bridge *br;
- if (db_limiter > time_msec()) {
- poll_timer_wait_until(db_limiter);
+ HMAP_FOR_EACH (br, node, &all_bridges) {
+ ofproto_wait(br->ofproto);
+ }
+ poll_timer_wait_until(stats_timer);
+
+ if (db_limiter > time_msec()) {
+ poll_timer_wait_until(db_limiter);
+ }
}
}
\f
port->name, port->cfg->bond_mode,
bond_mode_to_string(s->balance));
}
+ if (s->balance == BM_SLB && port->bridge->cfg->n_flood_vlans) {
+ VLOG_WARN("port %s: SLB bonds are incompatible with flood_vlans, "
+ "please use another bond type or disable flood_vlans",
+ port->name);
+ }
miimon_interval = atoi(get_port_other_config(port->cfg,
"bond-miimon-interval", "0"));
&s.srcs, &s.n_srcs);
mirror_collect_ports(m, cfg->select_dst_port, cfg->n_select_dst_port,
&s.dsts, &s.n_dsts);
-
}
/* Get VLAN selection. */