summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Stringer <joestringer@nicira.com>2014-05-05 10:14:18 +1200
committerJoe Stringer <joestringer@nicira.com>2014-05-08 09:49:07 +1200
commit2e6b2d5a0d3aab1d4ae7484feabb4946468efb4d (patch)
tree4f1a8807ddf7158929f89c9fe863a90bbef200f5
parent5b6d8aeb2614c85beb49509714a063128bbbb2cc (diff)
downloadopenvswitch-2e6b2d5a0d3aab1d4ae7484feabb4946468efb4d.tar.gz
tunnel: Fix bug where misconfiguration persists.
Previously, misconfiguring a tunnel port to use the exact same settings would cause the corresponding netdev to never be destroyed. When attempting to re-use the port as a different type, this would fail and result in a discrepancy between reported port type and actual netdev in use. An example configuration that would previously give unexpected behaviour: ovs-vsctl add-port br0 p0 -- set int p0 type=gre options:remote_ip=1.2.3.4 ovs-vsctl add-port br0 p1 -- set int p1 type=internal ovs-vsctl set int p1 type=gre options:remote_ip=1.2.3.4 ovs-vsctl set int p1 type=internal The final command would report in the ovs-vswitchd logs that it is attempting to configure the port with the same gre settings as p0, despite the command specifying the type as internal. Even after deleting and re-adding the port, the message would reappear. This patch fixes the bug by dereferencing the netdev in the failure case of tnl_port_add__(), and ensures that the tnl_port structure is freed in that case as well. Bug #1198386. Signed-off-by: Joe Stringer <joestringer@nicira.com> Acked-by: Ryan Wilson <wryan@vmware.com> Acked-by: Alex Wang <alexw@nicira.com>
-rw-r--r--ofproto/tunnel.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index 202358b86..7f7693ebc 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -117,8 +117,9 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev,
"port '%s' (%s)", tnl_port_get_name(tnl_port),
tnl_port_get_name(existing_port), ds_cstr(&ds));
ds_destroy(&ds);
- free(tnl_port);
}
+ netdev_close(tnl_port->netdev);
+ free(tnl_port);
return false;
}