X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=d894233ab58126bcdc6e8f925aad580e2a858a29;hb=2c360fbb2777fba6d35599e4b53287e2ecb26fa9;hp=eb10cf0abb30607ad3b134a84f8ef9516e9fc5db;hpb=08fd19f01b22226e25a5112b13eb951190ea8d00;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index eb10cf0a..d894233a 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -73,6 +73,7 @@ #include "xenserver.h" #include "vlog.h" #include "sflow_api.h" +#include "vlan-bitmap.h" VLOG_DEFINE_THIS_MODULE(bridge); @@ -418,71 +419,6 @@ bridge_configure_once(const struct ovsrec_open_vswitch *cfg) sset_destroy(&dpif_types); } -/* Callback for iterate_and_prune_ifaces(). */ -static bool -check_iface(struct bridge *br, struct iface *iface, void *aux OVS_UNUSED) -{ - if (!iface->netdev) { - /* We already reported a related error, don't bother duplicating it. */ - return false; - } - - if (iface->dp_ifidx < 0) { - VLOG_ERR("%s interface not in %s, dropping", - iface->name, dpif_name(br->dpif)); - return false; - } - - VLOG_DBG("%s has interface %s on port %d", dpif_name(br->dpif), - iface->name, iface->dp_ifidx); - return true; -} - -/* Callback for iterate_and_prune_ifaces(). */ -static bool -set_iface_properties(struct bridge *br OVS_UNUSED, struct iface *iface, - void *aux OVS_UNUSED) -{ - /* Set policing attributes. */ - netdev_set_policing(iface->netdev, - iface->cfg->ingress_policing_rate, - iface->cfg->ingress_policing_burst); - - /* Set MAC address of internal interfaces other than the local - * interface. */ - iface_set_mac(iface); - - return true; -} - -/* Calls 'cb' for each interfaces in 'br', passing along the 'aux' argument. - * Deletes from 'br' all the interfaces for which 'cb' returns false, and then - * deletes from 'br' any ports that no longer have any interfaces. */ -static void -iterate_and_prune_ifaces(struct bridge *br, - bool (*cb)(struct bridge *, struct iface *, - void *aux), - void *aux) -{ - struct port *port, *next_port; - - HMAP_FOR_EACH_SAFE (port, next_port, hmap_node, &br->ports) { - struct iface *iface, *next_iface; - - LIST_FOR_EACH_SAFE (iface, next_iface, port_elem, &port->ifaces) { - if (!cb(br, iface, aux)) { - iface_set_ofport(iface->cfg, -1); - iface_destroy(iface); - } - } - - if (list_is_empty(&port->ifaces)) { - VLOG_WARN("%s port has no interfaces, dropping", port->name); - port_destroy(port); - } - } -} - /* Looks at the list of managers in 'ovs_cfg' and extracts their remote IP * addresses and ports into '*managersp' and '*n_managersp'. The caller is * responsible for freeing '*managersp' (with free()). @@ -615,9 +551,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) && strcmp(dpif_port.name, br->name)) { int retval = dpif_port_del(br->dpif, dpif_port.port_no); if (retval) { - VLOG_WARN("failed to remove %s interface from %s: %s", - dpif_port.name, dpif_name(br->dpif), - strerror(retval)); + VLOG_WARN("bridge %s: failed to remove %s interface (%s)", + br->name, dpif_port.name, strerror(retval)); } } } @@ -710,13 +645,13 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) if (error) { netdev_close(netdev); if (error == EFBIG) { - VLOG_ERR("ran out of valid port numbers on %s", - dpif_name(br->dpif)); + VLOG_ERR("bridge %s: out of valid port numbers", + br->name); break; } else { - VLOG_WARN("failed to add %s interface to %s: %s", - if_name, dpif_name(br->dpif), - strerror(error)); + VLOG_WARN("bridge %s: failed to add %s interface " + "(%s)", + br->name, if_name, strerror(error)); continue; } } @@ -751,6 +686,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) uint8_t ea[ETH_ADDR_LEN]; uint64_t dpid; struct iface *local_iface; + struct port *port, *next_port; struct iface *hw_addr_iface; char *dpid_string; @@ -758,9 +694,34 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) /* Delete interfaces that cannot be opened. * - * From this point forward we are guaranteed that every "struct iface" - * has nonnull 'netdev' and correct 'dp_ifidx'. */ - iterate_and_prune_ifaces(br, check_iface, NULL); + * Following this loop, every remaining "struct iface" has nonnull + * 'netdev' and correct 'dp_ifidx'. */ + HMAP_FOR_EACH_SAFE (port, next_port, hmap_node, &br->ports) { + struct iface *iface, *next_iface; + + LIST_FOR_EACH_SAFE (iface, next_iface, port_elem, &port->ifaces) { + if (iface->netdev && iface->dp_ifidx >= 0) { + VLOG_DBG("bridge %s: interface %s is on port %d", + br->name, iface->name, iface->dp_ifidx); + } else { + if (iface->netdev) { + VLOG_ERR("bridge %s: missing %s interface, dropping", + br->name, iface->name); + } else { + /* We already reported a related error, don't bother + * duplicating it. */ + } + + iface_set_ofport(iface->cfg, -1); + iface_destroy(iface); + } + } + + if (list_is_empty(&port->ifaces)) { + VLOG_WARN("%s port has no interfaces, dropping", port->name); + port_destroy(port); + } + } /* Pick local port hardware address, datapath ID. */ bridge_pick_local_hw_addr(br, ea, &hw_addr_iface); @@ -903,12 +864,13 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) LIST_FOR_EACH (iface, port_elem, &port->ifaces) { iface_update_qos(iface, port->cfg->qos); + netdev_set_policing(iface->netdev, + iface->cfg->ingress_policing_rate, + iface->cfg->ingress_policing_burst); + iface_set_mac(iface); } } } - LIST_FOR_EACH (br, node, &all_bridges) { - iterate_and_prune_ifaces(br, set_iface_properties, NULL); - } /* Some reconfiguration operations require the bridge to have been run at * least once. */ @@ -1706,7 +1668,7 @@ bridge_create(const struct ovsrec_bridge *br_cfg) list_push_back(&all_bridges, &br->node); - VLOG_INFO("created bridge %s on %s", br->name, dpif_name(br->dpif)); + VLOG_INFO("bridge %s: created", br->name); return br; } @@ -1729,8 +1691,8 @@ bridge_destroy(struct bridge *br) ofproto_destroy(br->ofproto); error = dpif_delete(br->dpif); if (error && error != ENOENT) { - VLOG_ERR("failed to delete %s: %s", - dpif_name(br->dpif), strerror(error)); + VLOG_ERR("bridge %s: failed to destroy (%s)", + br->name, strerror(error)); } dpif_close(br->dpif); mac_learning_destroy(br->ml); @@ -2062,9 +2024,9 @@ bridge_reconfigure_remotes(struct bridge *br, /* Prevent remote ovsdb-server users from accessing arbitrary Unix * domain sockets and overwriting arbitrary local files. */ - VLOG_ERR_RL(&rl, "%s: not adding Unix domain socket controller " - "\"%s\" due to possibility for remote exploit", - dpif_name(br->dpif), c->target); + VLOG_ERR_RL(&rl, "bridge %s: not adding Unix domain socket " + "controller \"%s\" due to possibility for remote " + "exploit", br->name, c->target); continue; } @@ -2128,11 +2090,11 @@ bridge_fetch_dp_ifaces(struct bridge *br) struct iface *iface = iface_lookup(br, dpif_port.name); if (iface) { if (iface->dp_ifidx >= 0) { - VLOG_WARN("%s reported interface %s twice", - dpif_name(br->dpif), dpif_port.name); + VLOG_WARN("bridge %s: interface %s reported twice", + br->name, dpif_port.name); } else if (iface_from_dp_ifidx(br, dpif_port.port_no)) { - VLOG_WARN("%s reported interface %"PRIu16" twice", - dpif_name(br->dpif), dpif_port.port_no); + VLOG_WARN("bridge %s: interface %"PRIu16" reported twice", + br->name, dpif_port.port_no); } else { iface->dp_ifidx = dpif_port.port_no; hmap_insert(&br->ifaces, &iface->dp_ifidx_node, @@ -2225,8 +2187,7 @@ dst_is_duplicate(const struct dst_set *set, const struct dst *test) static bool port_trunks_vlan(const struct port *port, uint16_t vlan) { - return (port->vlan < 0 - && (!port->trunks || bitmap_is_set(port->trunks, vlan))); + return (port->vlan < 0 || vlan_bitmap_contains(port->trunks, vlan)); } static bool @@ -2980,35 +2941,16 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg) /* Get trunked VLANs. */ trunks = NULL; if (vlan < 0 && cfg->n_trunks) { - size_t n_errors; - - trunks = bitmap_allocate(4096); - n_errors = 0; - for (i = 0; i < cfg->n_trunks; i++) { - int trunk = cfg->trunks[i]; - if (trunk >= 0) { - bitmap_set1(trunks, trunk); - } else { - n_errors++; - } - } - if (n_errors) { - VLOG_ERR("port %s: invalid values for %zu trunk VLANs", - port->name, cfg->n_trunks); - } - if (n_errors == cfg->n_trunks) { + trunks = vlan_bitmap_from_array(cfg->trunks, cfg->n_trunks); + if (!trunks) { VLOG_ERR("port %s: no valid trunks, trunking all VLANs", port->name); - bitmap_free(trunks); - trunks = NULL; } } else if (vlan >= 0 && cfg->n_trunks) { VLOG_ERR("port %s: ignoring trunks in favor of implicit vlan", port->name); } - if (trunks == NULL - ? port->trunks != NULL - : port->trunks == NULL || !bitmap_equal(trunks, port->trunks, 4096)) { + if (!vlan_bitmap_equal(trunks, port->trunks)) { need_flush = true; } bitmap_free(port->trunks); @@ -3633,24 +3575,14 @@ mirror_reconfigure(struct bridge *br) /* Update flooded vlans (for RSPAN). */ rspan_vlans = NULL; if (br->cfg->n_flood_vlans) { - rspan_vlans = bitmap_allocate(4096); - - for (i = 0; i < br->cfg->n_flood_vlans; i++) { - int64_t vlan = br->cfg->flood_vlans[i]; - if (vlan >= 0 && vlan < 4096) { - bitmap_set1(rspan_vlans, vlan); - VLOG_INFO("bridge %s: disabling learning on vlan %"PRId64, - br->name, vlan); - } else { - VLOG_ERR("bridge %s: invalid value %"PRId64 "for flood VLAN", - br->name, vlan); - } - } + rspan_vlans = vlan_bitmap_from_array(br->cfg->flood_vlans, + br->cfg->n_flood_vlans); } if (mac_learning_set_flood_vlans(br->ml, rspan_vlans)) { bridge_flush(br); mac_learning_flush(br->ml); } + free(rspan_vlans); } static void