From ea0797c929dc663ed443f07cd0bfc9d788d11367 Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Fri, 5 Jun 2015 08:13:28 -0700 Subject: [PATCH] ofproto-dpif: Avoid creating OpenFlow ports for duplicate tunnels. Until now, when two tunnels had an identical configuration, both of them were assigned OpenFlow ports, but only one of those OpenFlow ports was functional. With this commit, only one of the two (or more) identically configured tunnels will be assigned an OpenFlow port number. Reported-by: Keith Holleman Signed-off-by: Ben Pfaff Co-authored-by: Andy Zhou Signed-off-by: Andy Zhou --- AUTHORS | 1 + ofproto/ofproto-dpif.c | 10 ++++++++-- ofproto/tunnel.c | 14 ++++++++++---- ofproto/tunnel.h | 6 +++--- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/AUTHORS b/AUTHORS index f15510571e8..28899a885d1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -277,6 +277,7 @@ Joan Cirer joan@ev0.net John Darrington john@darrington.wattle.id.au John Galgay john@galgay.net John Hurley john.hurley@netronome.com +Keith Holleman hollemanietf@gmail.com K 華 k940545@hotmail.com Kevin Mancuso kevin.mancuso@rackspace.com Kiran Shanbhog kiran@vmware.com diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index c1daa1dc1a7..bd4530567aa 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -1671,8 +1671,14 @@ port_construct(struct ofport *port_) if (netdev_get_tunnel_config(netdev)) { atomic_count_inc(&ofproto->backer->tnl_count); - tnl_port_add(port, port->up.netdev, port->odp_port, - ovs_native_tunneling_is_on(ofproto), namebuf); + error = tnl_port_add(port, port->up.netdev, port->odp_port, + ovs_native_tunneling_is_on(ofproto), namebuf); + if (error) { + atomic_count_dec(&ofproto->backer->tnl_count); + dpif_port_destroy(&dpif_port); + return error; + } + port->is_tunnel = true; if (ofproto->ipfix) { dpif_ipfix_add_tunnel_port(ofproto->ipfix, port_, port->odp_port); diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index 3ea0eb44f92..d2ac7c6a80c 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -1,4 +1,4 @@ -/* Copyright (c) 2013, 2014 Nicira, Inc. +/* Copyright (c) 2013, 2014, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -203,14 +203,20 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev, /* Adds 'ofport' to the module with datapath port number 'odp_port'. 'ofport's * must be added before they can be used by the module. 'ofport' must be a - * tunnel. */ -void + * tunnel. + * + * Returns 0 if successful, otherwise a positive errno value. */ +int tnl_port_add(const struct ofport_dpif *ofport, const struct netdev *netdev, odp_port_t odp_port, bool native_tnl, const char name[]) OVS_EXCLUDED(rwlock) { + bool ok; + fat_rwlock_wrlock(&rwlock); - tnl_port_add__(ofport, netdev, odp_port, true, native_tnl, name); + ok = tnl_port_add__(ofport, netdev, odp_port, true, native_tnl, name); fat_rwlock_unlock(&rwlock); + + return ok ? 0 : EEXIST; } /* Checks if the tunnel represented by 'ofport' reconfiguration due to changes diff --git a/ofproto/tunnel.h b/ofproto/tunnel.h index 6181762b2e1..b8415abb287 100644 --- a/ofproto/tunnel.h +++ b/ofproto/tunnel.h @@ -1,4 +1,4 @@ -/* Copyright (c) 2013 Nicira, Inc. +/* Copyright (c) 2013, 2015 Nicira, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,8 +33,8 @@ void ofproto_tunnel_init(void); bool tnl_port_reconfigure(const struct ofport_dpif *, const struct netdev *, odp_port_t, bool native_tnl, const char name[]); -void tnl_port_add(const struct ofport_dpif *, const struct netdev *, - odp_port_t odp_port, bool native_tnl, const char name[]); +int tnl_port_add(const struct ofport_dpif *, const struct netdev *, + odp_port_t odp_port, bool native_tnl, const char name[]); void tnl_port_del(const struct ofport_dpif *); const struct ofport_dpif *tnl_port_receive(const struct flow *);