Previously, we would prefer to get the type for an ofport from the corresponding dpif_port, rather than from the netdev. This would cause lookups for ports of "tap" type to report that they are of type "system".
Each time we see a port of the wrong type in bridge_reconfigure(), we remove it and add a port with the correct configuration. This would always occur for tap ports, causing deletion and re-creation of all tap ports each time the bridge was reconfigured. This patch fixes the behaviour. Bug #1196289. Reported-by: James Schmidt <jschm...@vmware.com> Signed-off-by: Joe Stringer <joestrin...@nicira.com> --- ofproto/ofproto-dpif.c | 37 +++++++++++++++++++++++-------------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index 328b215..c378c97 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -2672,34 +2672,43 @@ port_query_by_name(const struct ofproto *ofproto_, const char *devname, struct ofproto_port *ofproto_port) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_); + const char *netdev_type = netdev_get_type_from_name(devname); struct dpif_port dpif_port; - int error; + int error = 0; if (sset_contains(&ofproto->ghost_ports, devname)) { - const char *type = netdev_get_type_from_name(devname); - /* We may be called before ofproto->up.port_by_name is populated with * the appropriate ofport. For this reason, we must get the name and * type from the netdev layer directly. */ - if (type) { + if (netdev_type) { const struct ofport *ofport; ofport = shash_find_data(&ofproto->up.port_by_name, devname); ofproto_port->ofp_port = ofport ? ofport->ofp_port : OFPP_NONE; - ofproto_port->name = xstrdup(devname); - ofproto_port->type = xstrdup(type); - return 0; + } else { + error = ENODEV; } - return ENODEV; + goto exit; } - if (!sset_contains(&ofproto->ports, devname)) { - return ENODEV; + if (sset_contains(&ofproto->ports, devname)) { + error = dpif_port_query_by_name(ofproto->backer->dpif, + devname, &dpif_port); + if (!error) { + ofproto_port_from_dpif_port(ofproto, ofproto_port, &dpif_port); + if (netdev_type) { + /* Prefer the netdev type over the dpif type. */ + dpif_port_destroy(&dpif_port); + } + } + } else { + error = ENODEV; } - error = dpif_port_query_by_name(ofproto->backer->dpif, - devname, &dpif_port); - if (!error) { - ofproto_port_from_dpif_port(ofproto, ofproto_port, &dpif_port); + +exit: + if (!error && netdev_type) { + ofproto_port->name = xstrdup(devname); + ofproto_port->type = xstrdup(netdev_type); } return error; } -- 1.7.9.5 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev