X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;ds=inline;f=vswitchd%2Fbridge.c;h=d1e24d0eeaaeba8c376cf63be5bb99dd269e40c5;hb=7beaa082d7f422dda337780d6dd457b9a5ffe7d5;hp=9fcc97098129b026a7a9f240c3872c490b69127f;hpb=d02a5f8ea4e1da19ccc4f903026b77649472b236;p=openvswitch diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c index 9fcc9709..d1e24d0e 100644 --- a/vswitchd/bridge.c +++ b/vswitchd/bridge.c @@ -36,6 +36,7 @@ #include "meta-flow.h" #include "netdev.h" #include "ofp-print.h" +#include "ofp-util.h" #include "ofpbuf.h" #include "ofproto/ofproto.h" #include "poll-loop.h" @@ -227,6 +228,8 @@ static void mirror_refresh_stats(struct mirror *); static void iface_configure_lacp(struct iface *, struct lacp_slave_settings *); static bool iface_create(struct bridge *, struct if_cfg *, int ofp_port); +static bool iface_is_internal(const struct ovsrec_interface *iface, + const struct ovsrec_bridge *br); static const char *iface_get_type(const struct ovsrec_interface *, const struct ovsrec_bridge *); static void iface_destroy(struct iface *); @@ -276,25 +279,27 @@ bridge_init_ofproto(const struct ovsrec_open_vswitch *cfg) shash_init(&iface_hints); - for (i = 0; i < cfg->n_bridges; i++) { - const struct ovsrec_bridge *br_cfg = cfg->bridges[i]; - int j; + if (cfg) { + for (i = 0; i < cfg->n_bridges; i++) { + const struct ovsrec_bridge *br_cfg = cfg->bridges[i]; + int j; - for (j = 0; j < br_cfg->n_ports; j++) { - struct ovsrec_port *port_cfg = br_cfg->ports[j]; - int k; + for (j = 0; j < br_cfg->n_ports; j++) { + struct ovsrec_port *port_cfg = br_cfg->ports[j]; + int k; - for (k = 0; k < port_cfg->n_interfaces; k++) { - struct ovsrec_interface *if_cfg = port_cfg->interfaces[k]; - struct iface_hint *iface_hint; + for (k = 0; k < port_cfg->n_interfaces; k++) { + struct ovsrec_interface *if_cfg = port_cfg->interfaces[k]; + struct iface_hint *iface_hint; - iface_hint = xmalloc(sizeof *iface_hint); - iface_hint->br_name = br_cfg->name; - iface_hint->br_type = br_cfg->datapath_type; - iface_hint->ofp_port = if_cfg->n_ofport_request ? - *if_cfg->ofport_request : OFPP_NONE; + iface_hint = xmalloc(sizeof *iface_hint); + iface_hint->br_name = br_cfg->name; + iface_hint->br_type = br_cfg->datapath_type; + iface_hint->ofp_port = if_cfg->n_ofport_request ? + *if_cfg->ofport_request : OFPP_NONE; - shash_add(&iface_hints, if_cfg->name, iface_hint); + shash_add(&iface_hints, if_cfg->name, iface_hint); + } } } } @@ -810,6 +815,18 @@ bridge_configure_datapath_id(struct bridge *br) free(dpid_string); } +/* Returns a bitmap of "enum ofputil_protocol"s that are allowed for use with + * 'br'. */ +static uint32_t +bridge_get_allowed_versions(struct bridge *br) +{ + if (!br->cfg->n_protocols) + return 0; + + return ofputil_versions_from_strings(br->cfg->protocols, + br->cfg->n_protocols); +} + /* Set NetFlow configuration on 'br'. */ static void bridge_configure_netflow(struct bridge *br) @@ -1345,7 +1362,8 @@ iface_do_create(const struct bridge *br, br->name, iface_cfg->name, *ofp_portp); } - if (port_cfg->vlan_mode && !strcmp(port_cfg->vlan_mode, "splinter")) { + if ((port_cfg->vlan_mode && !strcmp(port_cfg->vlan_mode, "splinter")) + || iface_is_internal(iface_cfg, br->cfg)) { netdev_turn_flags_on(netdev, NETDEV_UP, true); } @@ -2795,7 +2813,8 @@ bridge_configure_remotes(struct bridge *br, n_ocs++; } - ofproto_set_controllers(br->ofproto, ocs, n_ocs); + ofproto_set_controllers(br->ofproto, ocs, n_ocs, + bridge_get_allowed_versions(br)); free(ocs[0].target); /* From bridge_ofproto_controller_for_mgmt(). */ free(ocs); @@ -3133,20 +3152,32 @@ port_is_synthetic(const struct port *port) /* Interface functions. */ +static bool +iface_is_internal(const struct ovsrec_interface *iface, + const struct ovsrec_bridge *br) +{ + /* The local port and "internal" ports are always "internal". */ + return !strcmp(iface->type, "internal") || !strcmp(iface->name, br->name); +} + /* Returns the correct network device type for interface 'iface' in bridge * 'br'. */ static const char * iface_get_type(const struct ovsrec_interface *iface, const struct ovsrec_bridge *br) { - /* The local port always has type "internal" unless the bridge is of - * type "dummy". Other ports take their type from the database and - * default to "system" if none is specified. */ - if (!strcmp(iface->name, br->name)) { - return !strcmp(br->datapath_type, "dummy") ? "dummy" : "internal"; + const char *type; + + /* The local port always has type "internal". Other ports take + * their type from the database and default to "system" if none is + * specified. */ + if (iface_is_internal(iface, br)) { + type = "internal"; } else { - return iface->type[0] ? iface->type : "system"; + type = iface->type[0] ? iface->type : "system"; } + + return ofproto_port_open_type(br->datapath_type, type); } static void