diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index f59d69c4d1e..fe034f9717b 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -3904,15 +3904,21 @@ port_query_by_name(const struct ofproto *ofproto_, const char *devname, int error; 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) { - const struct ofport *ofport; + * type from the netdev layer directly. + * However, when a port deleted, the corresponding netdev is also + * removed from netdev_shash. netdev_get_type_from_name returns NULL + * in such case and we should try to get type from ofport->netdev. */ + const char *type = netdev_get_type_from_name(devname); + const struct ofport *ofport = + shash_find_data(&ofproto->up.port_by_name, devname); - ofport = shash_find_data(&ofproto->up.port_by_name, devname); + if (!type && ofport && ofport->netdev) { + type = netdev_get_type(ofport->netdev); + } + + if (type) { ofproto_port->ofp_port = ofport ? ofport->ofp_port : OFPP_NONE; ofproto_port->name = xstrdup(devname); ofproto_port->type = xstrdup(type); diff --git a/tests/tunnel.at b/tests/tunnel.at index 71e7c2df4ea..9d539ee6f67 100644 --- a/tests/tunnel.at +++ b/tests/tunnel.at @@ -1269,6 +1269,18 @@ OVS_APP_EXIT_AND_WAIT([ovs-vswitchd]) OVS_APP_EXIT_AND_WAIT([ovsdb-server])] AT_CLEANUP +AT_SETUP([tunnel - re-create port with different name]) +OVS_VSWITCHD_START( + [add-port br0 p0 -- set int p0 type=vxlan options:remote_ip=10.10.10.1]) + +AT_CHECK([ovs-vsctl --if-exists del-port p0 -- \ + add-port br0 p1 -- \ + set int p1 type=vxlan options:remote_ip=10.10.10.1]) + +OVS_APP_EXIT_AND_WAIT([ovs-vswitchd]) +OVS_APP_EXIT_AND_WAIT([ovsdb-server])] +AT_CLEANUP + AT_SETUP([tunnel - SRV6 basic]) OVS_VSWITCHD_START([add-port br0 p1 -- set Interface p1 type=dummy \ ofport_request=1 \