X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=88f8db112365cd5704aa264a5bedc7d3160ed436;hb=2ad2eb042517b975d761d456cceb5c9325c4aaa7;hp=d7f1979a4dddde08542ac4cc93c298b92be7c72e;hpb=37e7f42772ae4f7866b060a29efa05b42419b143;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index d7f1979a..88f8db11 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -61,6 +61,7 @@ #include "vswitchd/vswitch-idl.h" #include "xenserver.h" #include "xtoxll.h" +#include "sflow_api.h" #define THIS_MODULE VLM_bridge #include "vlog.h" @@ -193,7 +194,7 @@ static struct list all_bridges = LIST_INITIALIZER(&all_bridges); /* Maximum number of datapaths. */ enum { DP_MAX = 256 }; -static struct bridge *bridge_create(const char *name); +static struct bridge *bridge_create(const struct ovsrec_bridge *br_cfg); static void bridge_destroy(struct bridge *); static struct bridge *bridge_lookup(const char *name); static unixctl_cb_func bridge_unixctl_dump_flows; @@ -285,7 +286,7 @@ void bridge_init(const struct ovsrec_open_vswitch *cfg) { struct svec bridge_names; - struct svec dpif_names; + struct svec dpif_names, dpif_types; size_t i; unixctl_command_register("fdb/show", bridge_unixctl_fdb_show, NULL); @@ -297,31 +298,37 @@ bridge_init(const struct ovsrec_open_vswitch *cfg) svec_sort(&bridge_names); svec_init(&dpif_names); - dp_enumerate(&dpif_names); - for (i = 0; i < dpif_names.n; i++) { - const char *dpif_name = dpif_names.names[i]; + svec_init(&dpif_types); + dp_enumerate_types(&dpif_types); + for (i = 0; i < dpif_types.n; i++) { struct dpif *dpif; int retval; + size_t j; - retval = dpif_open(dpif_name, &dpif); - if (!retval) { - struct svec all_names; - size_t j; + dp_enumerate_names(dpif_types.names[i], &dpif_names); - svec_init(&all_names); - dpif_get_all_names(dpif, &all_names); - for (j = 0; j < all_names.n; j++) { - if (svec_contains(&bridge_names, all_names.names[j])) { - goto found; + for (j = 0; j < dpif_names.n; j++) { + retval = dpif_open(dpif_names.names[j], dpif_types.names[i], &dpif); + if (!retval) { + struct svec all_names; + size_t k; + + svec_init(&all_names); + dpif_get_all_names(dpif, &all_names); + for (k = 0; k < all_names.n; k++) { + if (svec_contains(&bridge_names, all_names.names[k])) { + goto found; + } } + dpif_delete(dpif); + found: + svec_destroy(&all_names); + dpif_close(dpif); } - dpif_delete(dpif); - found: - svec_destroy(&all_names); - dpif_close(dpif); } } svec_destroy(&dpif_names); + svec_destroy(&dpif_types); unixctl_command_register("bridge/dump-flows", bridge_unixctl_dump_flows, NULL); @@ -530,6 +537,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) struct shash_node *node; struct bridge *br, *next; size_t i; + int sflow_bridge_number; COVERAGE_INC(bridge_reconfigure); @@ -560,11 +568,16 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) SHASH_FOR_EACH (node, &new_br) { const char *br_name = node->name; const struct ovsrec_bridge *br_cfg = node->data; - if (!shash_find_data(&old_br, br_name)) { - br = bridge_create(br_name); - if (br) { - br->cfg = br_cfg; + br = shash_find_data(&old_br, br_name); + if (br) { + /* If the bridge datapath type has changed, we need to tear it + * down and recreate. */ + if (strcmp(br->cfg->datapath_type, br_cfg->datapath_type)) { + bridge_destroy(br); + bridge_create(br_cfg); } + } else { + bridge_create(br_cfg); } } shash_destroy(&old_br); @@ -658,6 +671,7 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) shash_destroy(&cur_ifaces); shash_destroy(&want_ifaces); } + sflow_bridge_number = 0; LIST_FOR_EACH (br, struct bridge, node, &all_bridges) { uint8_t ea[8]; uint64_t dpid; @@ -699,10 +713,10 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) dpif_get_netflow_ids(br->dpif, &opts.engine_type, &opts.engine_id); if (nf_cfg->engine_type) { - opts.engine_type = nf_cfg->engine_type; + opts.engine_type = *nf_cfg->engine_type; } if (nf_cfg->engine_id) { - opts.engine_id = nf_cfg->engine_id; + opts.engine_id = *nf_cfg->engine_id; } opts.active_timeout = nf_cfg->active_timeout; @@ -739,6 +753,45 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) ofproto_set_netflow(br->ofproto, NULL); } + /* Set sFlow configuration on this bridge. */ + if (br->cfg->sflow) { + struct ovsrec_sflow *sflow_cfg = br->cfg->sflow; + struct ofproto_sflow_options oso; + + memset(&oso, 0, sizeof oso); + + oso.targets.n = sflow_cfg->n_targets; + oso.targets.names = sflow_cfg->targets; + + oso.sampling_rate = SFL_DEFAULT_SAMPLING_RATE; + if (sflow_cfg->sampling) { + oso.sampling_rate = *sflow_cfg->sampling; + } + + oso.polling_interval = SFL_DEFAULT_POLLING_INTERVAL; + if (sflow_cfg->polling) { + oso.polling_interval = *sflow_cfg->polling; + } + + oso.header_len = SFL_DEFAULT_HEADER_SIZE; + if (sflow_cfg->header) { + oso.header_len = *sflow_cfg->header; + } + + oso.sub_id = sflow_bridge_number++; + oso.agent_device = sflow_cfg->agent; + +#if 0 /* xxx foo */ + ctrl = bridge_get_controller(ovs_cfg, br); + oso.control_ip = ctrl ? ctrl->local_ip : NULL; +#endif + ofproto_set_sflow(br->ofproto, &oso); + + svec_destroy(&oso.targets); + } else { + ofproto_set_sflow(br->ofproto, NULL); + } + /* Update the controller and related settings. It would be more * straightforward to call this from bridge_reconfigure_one(), but we * can't do it there for two reasons. First, and most importantly, at @@ -1071,31 +1124,35 @@ bridge_unixctl_fdb_show(struct unixctl_conn *conn, /* Bridge reconfiguration functions. */ static struct bridge * -bridge_create(const char *name) +bridge_create(const struct ovsrec_bridge *br_cfg) { struct bridge *br; int error; - assert(!bridge_lookup(name)); + assert(!bridge_lookup(br_cfg->name)); br = xzalloc(sizeof *br); - error = dpif_create_and_open(name, &br->dpif); + error = dpif_create_and_open(br_cfg->name, br_cfg->datapath_type, + &br->dpif); if (error) { free(br); return NULL; } dpif_flow_flush(br->dpif); - error = ofproto_create(name, &bridge_ofhooks, br, &br->ofproto); + error = ofproto_create(br_cfg->name, br_cfg->datapath_type, &bridge_ofhooks, + br, &br->ofproto); if (error) { - VLOG_ERR("failed to create switch %s: %s", name, strerror(error)); + VLOG_ERR("failed to create switch %s: %s", br_cfg->name, + strerror(error)); dpif_delete(br->dpif); dpif_close(br->dpif); free(br); return NULL; } - br->name = xstrdup(name); + br->name = xstrdup(br_cfg->name); + br->cfg = br_cfg; br->ml = mac_learning_create(); br->sent_config_request = false; eth_addr_random(br->default_ea); @@ -1247,7 +1304,6 @@ bridge_reconfigure_one(const struct ovsrec_open_vswitch *ovs_cfg, struct svec listeners, old_listeners; struct svec snoops, old_snoops; struct shash_node *node; - uint64_t mgmt_id; size_t i; /* Collect old ports. */ @@ -1283,9 +1339,6 @@ bridge_reconfigure_one(const struct ovsrec_open_vswitch *ovs_cfg, } } - dpid_from_string(ovs_cfg->management_id, &mgmt_id); - ofproto_set_mgmt_id(br->ofproto, mgmt_id); - /* Get rid of deleted ports and add new ports. */ SHASH_FOR_EACH (node, &old_ports) { if (!shash_find(&new_ports, node->name)) { @@ -3522,7 +3575,7 @@ mirror_reconfigure(struct bridge *br) } } - /* Update learning disabled vlans (for RSPAN). */ + /* Update flooded vlans (for RSPAN). */ rspan_vlans = NULL; if (br->cfg->n_flood_vlans) { rspan_vlans = bitmap_allocate(4096); @@ -3539,7 +3592,7 @@ mirror_reconfigure(struct bridge *br) } } } - if (mac_learning_set_disabled_vlans(br->ml, rspan_vlans)) { + if (mac_learning_set_flood_vlans(br->ml, rspan_vlans)) { bridge_flush(br); } }