X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=vswitchd%2Fbridge.c;h=63b0c9b21fe8c1d378bb2f19bff5bb66496721cf;hb=867cc7bd395b32a3516112127a04d41d9f1b15fc;hp=d7f1979a4dddde08542ac4cc93c298b92be7c72e;hpb=37e7f42772ae4f7866b060a29efa05b42419b143;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index d7f1979a..63b0c9b2 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" @@ -162,6 +163,13 @@ struct bridge { /* OpenFlow switch processing. */ struct ofproto *ofproto; /* OpenFlow switch. */ + /* Description strings. */ + char *mfr_desc; /* Manufacturer. */ + char *hw_desc; /* Hardware. */ + char *sw_desc; /* Software version. */ + char *serial_desc; /* Serial number. */ + char *dp_desc; /* Datapath description. */ + /* Kernel datapath information. */ struct dpif *dpif; /* Datapath. */ struct port_array ifaces; /* Indexed by kernel datapath port number. */ @@ -193,11 +201,14 @@ 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; static int bridge_run_one(struct bridge *); +static const struct ovsrec_controller *bridge_get_controller( + const struct ovsrec_open_vswitch *ovs_cfg, + const struct bridge *br); static void bridge_reconfigure_one(const struct ovsrec_open_vswitch *, struct bridge *); static void bridge_reconfigure_controller(const struct ovsrec_open_vswitch *, @@ -285,7 +296,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 +308,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); @@ -442,8 +459,8 @@ reconfigure_iface(const struct ovsrec_interface *iface_cfg, struct iface *iface) } static bool -check_iface_netdev(struct bridge *br UNUSED, struct iface *iface, - void *aux UNUSED) +check_iface_netdev(struct bridge *br OVS_UNUSED, struct iface *iface, + void *aux OVS_UNUSED) { if (!iface->netdev) { int error = set_up_iface(iface->cfg, iface, true); @@ -458,7 +475,8 @@ check_iface_netdev(struct bridge *br UNUSED, struct iface *iface, } static bool -check_iface_dp_ifidx(struct bridge *br, struct iface *iface, void *aux UNUSED) +check_iface_dp_ifidx(struct bridge *br, struct iface *iface, + void *aux OVS_UNUSED) { if (iface->dp_ifidx >= 0) { VLOG_DBG("%s has interface %s on port %d", @@ -473,8 +491,8 @@ check_iface_dp_ifidx(struct bridge *br, struct iface *iface, void *aux UNUSED) } static bool -set_iface_properties(struct bridge *br UNUSED, struct iface *iface, - void *aux UNUSED) +set_iface_properties(struct bridge *br OVS_UNUSED, struct iface *iface, + void *aux OVS_UNUSED) { /* Set policing attributes. */ netdev_set_policing(iface->netdev, @@ -530,6 +548,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 +579,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 +682,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 +724,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 +764,44 @@ 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) { + const struct ovsrec_sflow *sflow_cfg = br->cfg->sflow; + const struct ovsrec_controller *ctrl; + 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; + + ctrl = bridge_get_controller(ovs_cfg, br); + oso.control_ip = ctrl ? ctrl->local_ip : NULL; + 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 @@ -1044,7 +1107,7 @@ bridge_get_local_iface(struct bridge *br) /* Bridge unixctl user interface functions. */ static void bridge_unixctl_fdb_show(struct unixctl_conn *conn, - const char *args, void *aux UNUSED) + const char *args, void *aux OVS_UNUSED) { struct ds ds = DS_EMPTY_INITIALIZER; const struct bridge *br; @@ -1071,34 +1134,38 @@ 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); + eth_addr_nicira_random(br->default_ea); port_array_init(&br->ifaces); @@ -1168,7 +1235,7 @@ bridge_get_datapathid(const char *name) * stack, including those normally hidden. */ static void bridge_unixctl_dump_flows(struct unixctl_conn *conn, - const char *args, void *aux UNUSED) + const char *args, void *aux OVS_UNUSED) { struct bridge *br; struct ds results; @@ -1238,6 +1305,75 @@ check_duplicate_ifaces(struct bridge *br, struct iface *iface, void *ifaces_) } } +static void +bridge_update_desc(struct bridge *br) +{ +#if 0 + bool changed = false; + const char *desc; + + desc = cfg_get_string(0, "bridge.%s.mfr-desc", br->name); + if (desc != br->mfr_desc) { + free(br->mfr_desc); + if (desc) { + br->mfr_desc = xstrdup(desc); + } else { + br->mfr_desc = xstrdup(DEFAULT_MFR_DESC); + } + changed = true; + } + + desc = cfg_get_string(0, "bridge.%s.hw-desc", br->name); + if (desc != br->hw_desc) { + free(br->hw_desc); + if (desc) { + br->hw_desc = xstrdup(desc); + } else { + br->hw_desc = xstrdup(DEFAULT_HW_DESC); + } + changed = true; + } + + desc = cfg_get_string(0, "bridge.%s.sw-desc", br->name); + if (desc != br->sw_desc) { + free(br->sw_desc); + if (desc) { + br->sw_desc = xstrdup(desc); + } else { + br->sw_desc = xstrdup(DEFAULT_SW_DESC); + } + changed = true; + } + + desc = cfg_get_string(0, "bridge.%s.serial-desc", br->name); + if (desc != br->serial_desc) { + free(br->serial_desc); + if (desc) { + br->serial_desc = xstrdup(desc); + } else { + br->serial_desc = xstrdup(DEFAULT_SERIAL_DESC); + } + changed = true; + } + + desc = cfg_get_string(0, "bridge.%s.dp-desc", br->name); + if (desc != br->dp_desc) { + free(br->dp_desc); + if (desc) { + br->dp_desc = xstrdup(desc); + } else { + br->dp_desc = xstrdup(DEFAULT_DP_DESC); + } + changed = true; + } + + if (changed) { + ofproto_set_desc(br->ofproto, br->mfr_desc, br->hw_desc, + br->sw_desc, br->serial_desc, br->dp_desc); + } +#endif +} + static void bridge_reconfigure_one(const struct ovsrec_open_vswitch *ovs_cfg, struct bridge *br) @@ -1247,7 +1383,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 +1418,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)) { @@ -1380,6 +1512,8 @@ bridge_reconfigure_one(const struct ovsrec_open_vswitch *ovs_cfg, #endif mirror_reconfigure(br); + + bridge_update_desc(br); } static void @@ -1417,7 +1551,7 @@ bridge_reconfigure_controller(const struct ovsrec_open_vswitch *ovs_cfg, local_iface = bridge_get_local_iface(br); if (local_iface && c->local_ip && inet_aton(c->local_ip, &ip)) { struct netdev *netdev = local_iface->netdev; - struct in_addr ip, mask, gateway; + struct in_addr mask, gateway; if (!c->local_netmask || !inet_aton(c->local_netmask, &mask)) { mask.s_addr = 0; @@ -1939,7 +2073,7 @@ compose_dsts(const struct bridge *br, const flow_t *flow, uint16_t vlan, return dst - dsts; } -static void UNUSED +static void OVS_UNUSED print_dsts(const struct dst *dsts, size_t n) { for (; n--; dsts++) { @@ -2654,7 +2788,7 @@ bond_send_learning_packets(struct port *port) static void bond_unixctl_list(struct unixctl_conn *conn, - const char *args UNUSED, void *aux UNUSED) + const char *args OVS_UNUSED, void *aux OVS_UNUSED) { struct ds ds = DS_EMPTY_INITIALIZER; const struct bridge *br; @@ -2705,7 +2839,7 @@ bond_find(const char *name) static void bond_unixctl_show(struct unixctl_conn *conn, - const char *args, void *aux UNUSED) + const char *args, void *aux OVS_UNUSED) { struct ds ds = DS_EMPTY_INITIALIZER; const struct port *port; @@ -2771,7 +2905,7 @@ bond_unixctl_show(struct unixctl_conn *conn, static void bond_unixctl_migrate(struct unixctl_conn *conn, const char *args_, - void *aux UNUSED) + void *aux OVS_UNUSED) { char *args = (char *) args_; char *save_ptr = NULL; @@ -2828,7 +2962,7 @@ bond_unixctl_migrate(struct unixctl_conn *conn, const char *args_, static void bond_unixctl_set_active_slave(struct unixctl_conn *conn, const char *args_, - void *aux UNUSED) + void *aux OVS_UNUSED) { char *args = (char *) args_; char *save_ptr = NULL; @@ -2909,21 +3043,21 @@ enable_slave(struct unixctl_conn *conn, const char *args_, bool enable) static void bond_unixctl_enable_slave(struct unixctl_conn *conn, const char *args, - void *aux UNUSED) + void *aux OVS_UNUSED) { enable_slave(conn, args, true); } static void bond_unixctl_disable_slave(struct unixctl_conn *conn, const char *args, - void *aux UNUSED) + void *aux OVS_UNUSED) { enable_slave(conn, args, false); } static void bond_unixctl_hash(struct unixctl_conn *conn, const char *args, - void *aux UNUSED) + void *aux OVS_UNUSED) { uint8_t mac[ETH_ADDR_LEN]; uint8_t hash; @@ -3028,7 +3162,7 @@ port_reconfigure(struct port *port, const struct ovsrec_port *cfg) iface = shash_find_data(&old_ifaces, if_cfg->name); if (!iface) { - iface = iface_create(port, if_cfg); + iface_create(port, if_cfg); } else { iface->cfg = if_cfg; } @@ -3522,7 +3656,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 +3673,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); } } @@ -3625,7 +3759,7 @@ mirror_collect_vlans(struct mirror *m, const struct ovsrec_mirror *cfg, size_t n_vlans; size_t i; - *vlans = xmalloc(sizeof *vlans * cfg->n_select_vlan); + *vlans = xmalloc(sizeof **vlans * cfg->n_select_vlan); n_vlans = 0; for (i = 0; i < cfg->n_select_vlan; i++) { int64_t vlan = cfg->select_vlan[i];