X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=sidebyside;f=vswitchd%2Fbridge.c;h=130e09493b21d60236f13232641cadd13b381154;hb=c874f17fc743b38295f6059ab6554561b7555724;hp=88f8db112365cd5704aa264a5bedc7d3160ed436;hpb=a4af00400a835eb87569ba40e21874c05e872c0f;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 88f8db11..130e0949 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -163,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. */ @@ -199,6 +206,9 @@ 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 *, @@ -338,49 +348,14 @@ bridge_init(const struct ovsrec_open_vswitch *cfg) } #ifdef HAVE_OPENSSL -static bool -config_string_change(const char *value, char **valuep) -{ - if (value && (!*valuep || strcmp(value, *valuep))) { - free(*valuep); - *valuep = xstrdup(value); - return true; - } else { - return false; - } -} - static void bridge_configure_ssl(const struct ovsrec_ssl *ssl) { - /* XXX SSL should be configurable on a per-bridge basis. - * XXX should be possible to de-configure SSL. */ - static char *private_key_file; - static char *certificate_file; - static char *cacert_file; - struct stat s; - - if (!ssl) { - /* XXX We can't un-set SSL settings. */ - return; - } - - if (config_string_change(ssl->private_key, &private_key_file)) { - stream_ssl_set_private_key_file(private_key_file); - } - - if (config_string_change(ssl->certificate, &certificate_file)) { - stream_ssl_set_certificate_file(certificate_file); - } - - /* We assume that even if the filename hasn't changed, if the CA cert - * file has been removed, that we want to move back into - * boot-strapping mode. This opens a small security hole, because - * the old certificate will still be trusted until vSwitch is - * restarted. We may want to address this in vconn's SSL library. */ - if (config_string_change(ssl->ca_cert, &cacert_file) - || (cacert_file && stat(cacert_file, &s) && errno == ENOENT)) { - stream_ssl_set_ca_cert_file(cacert_file, ssl->bootstrap_ca_cert); + /* XXX SSL should be configurable on a per-bridge basis. */ + if (ssl) { + stream_ssl_set_private_key_file(ssl->private_key); + stream_ssl_set_certificate_file(ssl->certificate); + stream_ssl_set_ca_cert_file(ssl->ca_cert, ssl->bootstrap_ca_cert); } } #endif @@ -407,7 +382,12 @@ set_up_iface(const struct ovsrec_interface *iface_cfg, struct iface *iface, memset(&netdev_options, 0, sizeof netdev_options); netdev_options.name = iface_cfg->name; - netdev_options.type = iface_cfg->type; + if (!strcmp(iface_cfg->type, "internal")) { + /* An "internal" config type maps to a netdev "system" type. */ + netdev_options.type = "system"; + } else { + netdev_options.type = iface_cfg->type; + } netdev_options.args = &options; netdev_options.ethertype = NETDEV_ETH_TYPE_NONE; netdev_options.may_create = true; @@ -425,6 +405,11 @@ set_up_iface(const struct ovsrec_interface *iface_cfg, struct iface *iface, const char *iface_type = iface_cfg->type && strlen(iface_cfg->type) ? iface_cfg->type : NULL; + /* An "internal" config type maps to a netdev "system" type. */ + if (iface_type && !strcmp(iface_type, "internal")) { + iface_type = "system"; + } + if (!iface_type || !strcmp(netdev_type, iface_type)) { error = netdev_reconfigure(iface->netdev, &options); } else { @@ -449,8 +434,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); @@ -465,7 +450,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", @@ -480,8 +466,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, @@ -755,7 +741,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) /* Set sFlow configuration on this bridge. */ if (br->cfg->sflow) { - struct ovsrec_sflow *sflow_cfg = 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); @@ -781,10 +768,8 @@ bridge_reconfigure(const struct ovsrec_open_vswitch *ovs_cfg) 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); @@ -1097,7 +1082,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; @@ -1155,7 +1140,7 @@ bridge_create(const struct ovsrec_bridge *br_cfg) 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); @@ -1225,7 +1210,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; @@ -1295,6 +1280,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) @@ -1433,13 +1487,14 @@ bridge_reconfigure_one(const struct ovsrec_open_vswitch *ovs_cfg, #endif mirror_reconfigure(br); + + bridge_update_desc(br); } static void bridge_reconfigure_controller(const struct ovsrec_open_vswitch *ovs_cfg, struct bridge *br) { - char *pfx = xasprintf("bridge.%s.controller", br->name); const struct ovsrec_controller *c; c = bridge_get_controller(ovs_cfg, br); @@ -1470,7 +1525,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; @@ -1533,7 +1588,6 @@ bridge_reconfigure_controller(const struct ovsrec_open_vswitch *ovs_cfg, ofproto_set_probe_interval(br->ofproto, 5); ofproto_set_failure(br->ofproto, false); } - free(pfx); ofproto_set_controller(br->ofproto, br->controller); } @@ -1992,7 +2046,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++) { @@ -2707,7 +2761,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; @@ -2758,7 +2812,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; @@ -2824,7 +2878,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; @@ -2881,7 +2935,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; @@ -2962,21 +3016,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; @@ -3081,7 +3135,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; } @@ -3678,7 +3732,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]; @@ -3728,9 +3782,6 @@ mirror_reconfigure_one(struct mirror *m, struct ovsrec_mirror *cfg) size_t n_vlans; int *vlans; size_t i; - bool mirror_all_ports; - bool any_ports_specified; - bool any_vlans_specified; /* Get output port. */ if (cfg->output_port) { @@ -3758,30 +3809,25 @@ mirror_reconfigure_one(struct mirror *m, struct ovsrec_mirror *cfg) return; } - /* Get all the ports, and drop duplicates and ports that don't exist. */ shash_init(&src_ports); shash_init(&dst_ports); - mirror_collect_ports(m, cfg->select_src_port, cfg->n_select_src_port, - &src_ports); - mirror_collect_ports(m, cfg->select_dst_port, cfg->n_select_dst_port, - &dst_ports); - any_ports_specified = cfg->n_select_dst_port || cfg->n_select_dst_port; - if (any_ports_specified - && shash_is_empty(&src_ports) && shash_is_empty(&dst_ports)) { - VLOG_ERR("bridge %s: disabling mirror %s since none of the specified " - "selection ports exists", m->bridge->name, m->name); - mirror_destroy(m); - goto exit; - } + if (cfg->select_all) { + for (i = 0; i < m->bridge->n_ports; i++) { + const char *name = m->bridge->ports[i]->name; + shash_add_once(&src_ports, name, NULL); + shash_add_once(&dst_ports, name, NULL); + } + vlans = NULL; + n_vlans = 0; + } else { + /* Get ports, and drop duplicates and ports that don't exist. */ + mirror_collect_ports(m, cfg->select_src_port, cfg->n_select_src_port, + &src_ports); + mirror_collect_ports(m, cfg->select_dst_port, cfg->n_select_dst_port, + &dst_ports); - /* Get all the vlans, and drop duplicate and invalid vlans. */ - n_vlans = mirror_collect_vlans(m, cfg, &vlans); - any_vlans_specified = cfg->n_select_vlan > 0; - if (any_vlans_specified && !n_vlans) { - VLOG_ERR("bridge %s: disabling mirror %s since none of the specified " - "VLANs exists", m->bridge->name, m->name); - mirror_destroy(m); - goto exit; + /* Get all the vlans, and drop duplicate and invalid vlans. */ + n_vlans = mirror_collect_vlans(m, cfg, &vlans); } /* Update mirror data. */ @@ -3801,16 +3847,12 @@ mirror_reconfigure_one(struct mirror *m, struct ovsrec_mirror *cfg) m->out_port = out_port; m->out_vlan = out_vlan; - /* If no selection criteria have been given, mirror for all ports. */ - mirror_all_ports = !any_ports_specified && !any_vlans_specified; - /* Update ports. */ mirror_bit = MIRROR_MASK_C(1) << m->idx; for (i = 0; i < m->bridge->n_ports; i++) { struct port *port = m->bridge->ports[i]; - if (mirror_all_ports - || shash_find(&m->src_ports, port->name) + if (shash_find(&m->src_ports, port->name) || (m->n_vlans && (!port->vlan ? port_trunks_any_mirrored_vlan(m, port) @@ -3820,7 +3862,7 @@ mirror_reconfigure_one(struct mirror *m, struct ovsrec_mirror *cfg) port->src_mirrors &= ~mirror_bit; } - if (mirror_all_ports || shash_find(&m->dst_ports, port->name)) { + if (shash_find(&m->dst_ports, port->name)) { port->dst_mirrors |= mirror_bit; } else { port->dst_mirrors &= ~mirror_bit; @@ -3828,7 +3870,6 @@ mirror_reconfigure_one(struct mirror *m, struct ovsrec_mirror *cfg) } /* Clean up. */ -exit: shash_destroy(&src_ports); shash_destroy(&dst_ports); }