X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=53a24e36e1180c0e505342492bfa97e78e5cdfb0;hb=76ecc721793b29c8bae44b10a065ec9ac07a9e4b;hp=74ac87efa1d85c81b98778c4a1a3699c09719fab;hpb=26233bb4615608fd45d89a5abe2e62f4b3d776f7;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 74ac87ef..53a24e36 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -15,6 +15,7 @@ #include #include "bridge.h" +#include "byte-order.h" #include #include #include @@ -65,10 +66,9 @@ #include "vswitchd/vswitch-idl.h" #include "xenserver.h" #include "vlog.h" -#include "xtoxll.h" #include "sflow_api.h" -VLOG_DEFINE_THIS_MODULE(bridge) +VLOG_DEFINE_THIS_MODULE(bridge); struct dst { uint16_t vlan; @@ -255,6 +255,7 @@ static struct iface *iface_lookup(const struct bridge *, const char *name); static struct iface *iface_from_dp_ifidx(const struct bridge *, uint16_t dp_ifidx); static void iface_set_mac(struct iface *); +static void iface_set_ofport(const struct ovsrec_interface *, int64_t ofport); static void iface_update_qos(struct iface *, const struct ovsrec_qos *); static void shash_from_ovs_idl_map(char **keys, char **values, size_t n, @@ -419,7 +420,7 @@ create_iface_netdev(struct iface *iface) error = netdev_open(&netdev_options, &iface->netdev); if (iface->netdev) { - netdev_get_carrier(iface->netdev, &iface->enabled); + iface->enabled = netdev_get_carrier(iface->netdev); } shash_destroy(&options); @@ -509,6 +510,7 @@ iterate_and_prune_ifaces(struct bridge *br, if (cb(br, iface, aux)) { j++; } else { + iface_set_ofport(iface->cfg, -1); iface_destroy(iface); } } @@ -1702,12 +1704,25 @@ bridge_reconfigure_remotes(struct bridge *br, struct ovsrec_controller **controllers; size_t n_controllers; bool had_primary; + const char *disable_ib_str; + bool disable_in_band = false; struct ofproto_controller *ocs; size_t n_ocs; size_t i; - ofproto_set_extra_in_band_remotes(br->ofproto, managers, n_managers); + + /* Check if we should disable in-band control on this bridge. */ + disable_ib_str = bridge_get_other_config(br->cfg, "disable-in-band"); + if (disable_ib_str && !strcmp(disable_ib_str, "true")) { + disable_in_band = true; + } + + if (disable_in_band) { + ofproto_set_extra_in_band_remotes(br->ofproto, NULL, 0); + } else { + ofproto_set_extra_in_band_remotes(br->ofproto, managers, n_managers); + } had_primary = ofproto_has_primary_controller(br->ofproto); n_controllers = bridge_get_controllers(br, &controllers); @@ -1732,7 +1747,11 @@ bridge_reconfigure_remotes(struct bridge *br, } bridge_configure_local_iface_netdev(br, c); - bridge_ofproto_controller_from_ovsrec(c, &ocs[n_ocs++]); + bridge_ofproto_controller_from_ovsrec(c, &ocs[n_ocs]); + if (disable_in_band) { + ocs[n_ocs].band = OFPROTO_OUT_OF_BAND; + } + n_ocs++; } ofproto_set_controllers(br->ofproto, ocs, n_ocs); @@ -1822,12 +1841,10 @@ bridge_fetch_dp_ifaces(struct bridge *br) hash_int(iface->dp_ifidx, 0)); } - if (iface->cfg) { - int64_t ofport = (iface->dp_ifidx >= 0 - ? odp_port_to_ofp_port(iface->dp_ifidx) - : -1); - ovsrec_interface_set_ofport(iface->cfg, &ofport, 1); - } + iface_set_ofport(iface->cfg, + (iface->dp_ifidx >= 0 + ? odp_port_to_ofp_port(iface->dp_ifidx) + : -1)); } } free(dpif_ports); @@ -2060,10 +2077,11 @@ bond_run(struct bridge *br) /* Track carrier going up and down on interfaces. */ while (!netdev_monitor_poll(port->monitor, &devname)) { struct iface *iface; - bool carrier; iface = port_lookup_iface(port, devname); - if (iface && !netdev_get_carrier(iface->netdev, &carrier)) { + if (iface) { + bool carrier = netdev_get_carrier(iface->netdev); + bond_link_status_update(iface, carrier); port_update_bond_compat(port); } @@ -2203,6 +2221,20 @@ port_includes_vlan(const struct port *port, uint16_t vlan) return vlan == port->vlan || port_trunks_vlan(port, vlan); } +static bool +port_is_floodable(const struct port *port) +{ + int i; + + for (i = 0; i < port->n_ifaces; i++) { + if (!ofproto_port_is_floodable(port->bridge->ofproto, + port->ifaces[i]->dp_ifidx)) { + return false; + } + } + return true; +} + static size_t compose_dsts(const struct bridge *br, const struct flow *flow, uint16_t vlan, const struct port *in_port, const struct port *out_port, @@ -2217,7 +2249,9 @@ compose_dsts(const struct bridge *br, const struct flow *flow, uint16_t vlan, /* XXX even better, define each VLAN as a datapath port group */ for (i = 0; i < br->n_ports; i++) { struct port *port = br->ports[i]; - if (port != in_port && port_includes_vlan(port, vlan) + if (port != in_port + && port_is_floodable(port) + && port_includes_vlan(port, vlan) && !port->is_mirror_output_port && set_dst(dst, flow, in_port, port, tags)) { mirrors |= port->dst_mirrors; @@ -2314,7 +2348,7 @@ compose_actions(struct bridge *br, const struct flow *flow, uint16_t vlan, } else { a = odp_actions_add(actions, ODPAT_SET_DL_TCI); a->dl_tci.tci = htons(p->vlan & VLAN_VID_MASK); - a->dl_tci.mask = htons(VLAN_VID_MASK); + a->dl_tci.tci |= htons(flow->dl_vlan_pcp << VLAN_PCP_SHIFT); } cur_vlan = p->vlan; } @@ -3419,6 +3453,7 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg) if (!shash_add_once(&new_ifaces, if_cfg->name, NULL)) { VLOG_WARN("port %s: %s specified twice as port interface", port->name, if_cfg->name); + iface_set_ofport(if_cfg, -1); continue; } @@ -3531,6 +3566,8 @@ port_destroy(struct port *port) del = br->ports[port->port_idx] = br->ports[--br->n_ports]; del->port_idx = port->port_idx; + VLOG_INFO("destroyed port %s on bridge %s", port->name, br->name); + netdev_monitor_destroy(port->monitor); free(port->ifaces); bitmap_free(port->trunks); @@ -3828,6 +3865,15 @@ iface_set_mac(struct iface *iface) } } +/* Sets the ofport column of 'if_cfg' to 'ofport'. */ +static void +iface_set_ofport(const struct ovsrec_interface *if_cfg, int64_t ofport) +{ + if (if_cfg) { + ovsrec_interface_set_ofport(if_cfg, &ofport, 1); + } +} + /* Adds the 'n' key-value pairs in 'keys' in 'values' to 'shash'. * * The value strings in '*shash' are taken directly from values[], not copied,