X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=9b70e63cb1346e690753bf19936cacdace4c7f1e;hb=7b6b0ef47e398a2fbda48fd385f9781b2df8bebb;hp=449957a9f5372242a40fc1822e1cb5356f22b36c;hpb=5d27908667cfa34f7786fdc88e9e09078453637a;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 449957a9..9b70e63c 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -148,6 +148,7 @@ static void bridge_add_ofproto_ports(struct bridge *); 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 *, @@ -216,6 +217,7 @@ bridge_init(const char *remote) { /* 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); @@ -411,6 +413,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) } 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); @@ -856,7 +859,6 @@ bridge_add_ofproto_ports(struct bridge *br) options.name = iface->name; options.type = iface->type; options.args = &args; - options.ethertype = NETDEV_ETH_TYPE_NONE; error = netdev_open(&options, &iface->netdev); } else { error = netdev_set_config(iface->netdev, &args); @@ -868,12 +870,6 @@ bridge_add_ofproto_ports(struct bridge *br) iface->name, strerror(error)); } - /* Populate stats columns in new Interface rows. */ - if (iface->netdev && !iface->cfg->mtu) { - iface_refresh_stats(iface); - iface_refresh_status(iface); - } - /* Add the port, if necessary. */ if (iface->netdev && iface->ofp_port < 0) { uint16_t ofp_port; @@ -889,6 +885,12 @@ bridge_add_ofproto_ports(struct bridge *br) } } + /* 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 */ if (iface->netdev && iface->ofp_port >= 0) { VLOG_DBG("bridge %s: interface %s is on port %d", @@ -922,7 +924,6 @@ bridge_add_ofproto_ports(struct bridge *br) options.name = port->name; options.type = "internal"; options.args = NULL; - options.ethertype = NETDEV_ETH_TYPE_NONE; error = netdev_open(&options, &netdev); if (!error) { ofproto_port_add(br->ofproto, netdev, NULL); @@ -961,6 +962,22 @@ bridge_get_other_config(const struct ovsrec_bridge *br_cfg, const char *key) &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) @@ -1391,6 +1408,24 @@ bridge_run(void) 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) { @@ -1403,10 +1438,6 @@ bridge_run(void) } } - /* (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. @@ -1495,16 +1526,18 @@ bridge_run(void) 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; + + 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); + if (db_limiter > time_msec()) { + poll_timer_wait_until(db_limiter); + } } } @@ -2221,6 +2254,11 @@ port_configure_bond(struct port *port, struct bond_settings *s, 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")); @@ -2474,6 +2512,7 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos) } else { struct iface_delete_queues_cbdata cbdata; struct shash details; + bool queue_zero; size_t i; /* Configure top-level Qos for 'iface'. */ @@ -2489,16 +2528,28 @@ iface_configure_qos(struct iface *iface, const struct ovsrec_qos *qos) netdev_dump_queues(iface->netdev, iface_delete_queues, &cbdata); /* Configure queues for 'iface'. */ + queue_zero = false; for (i = 0; i < qos->n_queues; i++) { const struct ovsrec_queue *queue = qos->value_queues[i]; unsigned int queue_id = qos->key_queues[i]; + if (queue_id == 0) { + queue_zero = true; + } + shash_from_ovs_idl_map(queue->key_other_config, queue->value_other_config, queue->n_other_config, &details); netdev_set_queue(iface->netdev, queue_id, &details); shash_destroy(&details); } + if (!queue_zero) { + static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1); + VLOG_WARN_RL(&rl, "interface %s: QoS configured without a default " + "queue (queue 0). Packets not directed to a " + "correctly configured queue may be dropped.", + iface->name); + } } netdev_set_policing(iface->netdev, @@ -2718,7 +2769,6 @@ mirror_configure(struct mirror *m, const struct ovsrec_mirror *cfg) &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. */