aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ipvlan/ipvlan_main.c
diff options
context:
space:
mode:
authorMahesh Bandewar <maheshb@google.com>2016-04-27 17:59:27 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-28 17:23:08 -0400
commit494e8489db50157637d146ee377991ed6f0018f1 (patch)
treeb4caedab38388527503bb7d2ddeb857774411b81 /drivers/net/ipvlan/ipvlan_main.c
parent222e4d0b13c674b28a562d67c270367d45d0a53d (diff)
ipvlan: Fix failure path in dev registration during link creation
When newlink creation fails at device-registration, the port->count is decremented twice. Francesco Ruggeri (fruggeri@arista.com) found this issue in Macvlan and the same exists in IPvlan driver too. While fixing this issue I noticed another issue of missing unregister in case of failure, so adding it to the fix which is similar to the macvlan fix by Francesco in commit 308379607548 ("macvlan: fix failure during registration v3") Reported-by: Francesco Ruggeri <fruggeri@arista.com> Signed-off-by: Mahesh Bandewar <maheshb@google.com> CC: Eric Dumazet <edumazet@google.com> CC: Eric W. Biederman <ebiederm@xmission.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ipvlan/ipvlan_main.c')
-rw-r--r--drivers/net/ipvlan/ipvlan_main.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/net/ipvlan/ipvlan_main.c b/drivers/net/ipvlan/ipvlan_main.c
index 57941d3f4227..1c4d395fbd49 100644
--- a/drivers/net/ipvlan/ipvlan_main.c
+++ b/drivers/net/ipvlan/ipvlan_main.c
@@ -113,6 +113,7 @@ static int ipvlan_init(struct net_device *dev)
113{ 113{
114 struct ipvl_dev *ipvlan = netdev_priv(dev); 114 struct ipvl_dev *ipvlan = netdev_priv(dev);
115 const struct net_device *phy_dev = ipvlan->phy_dev; 115 const struct net_device *phy_dev = ipvlan->phy_dev;
116 struct ipvl_port *port = ipvlan->port;
116 117
117 dev->state = (dev->state & ~IPVLAN_STATE_MASK) | 118 dev->state = (dev->state & ~IPVLAN_STATE_MASK) |
118 (phy_dev->state & IPVLAN_STATE_MASK); 119 (phy_dev->state & IPVLAN_STATE_MASK);
@@ -128,6 +129,8 @@ static int ipvlan_init(struct net_device *dev)
128 if (!ipvlan->pcpu_stats) 129 if (!ipvlan->pcpu_stats)
129 return -ENOMEM; 130 return -ENOMEM;
130 131
132 port->count += 1;
133
131 return 0; 134 return 0;
132} 135}
133 136
@@ -481,27 +484,21 @@ static int ipvlan_link_new(struct net *src_net, struct net_device *dev,
481 484
482 dev->priv_flags |= IFF_IPVLAN_SLAVE; 485 dev->priv_flags |= IFF_IPVLAN_SLAVE;
483 486
484 port->count += 1;
485 err = register_netdevice(dev); 487 err = register_netdevice(dev);
486 if (err < 0) 488 if (err < 0)
487 goto ipvlan_destroy_port; 489 return err;
488 490
489 err = netdev_upper_dev_link(phy_dev, dev); 491 err = netdev_upper_dev_link(phy_dev, dev);
490 if (err) 492 if (err) {
491 goto ipvlan_destroy_port; 493 unregister_netdevice(dev);
494 return err;
495 }
492 496
493 list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans); 497 list_add_tail_rcu(&ipvlan->pnode, &port->ipvlans);
494 ipvlan_set_port_mode(port, mode); 498 ipvlan_set_port_mode(port, mode);
495 499
496 netif_stacked_transfer_operstate(phy_dev, dev); 500 netif_stacked_transfer_operstate(phy_dev, dev);
497 return 0; 501 return 0;
498
499ipvlan_destroy_port:
500 port->count -= 1;
501 if (!port->count)
502 ipvlan_port_destroy(phy_dev);
503
504 return err;
505} 502}
506 503
507static void ipvlan_link_delete(struct net_device *dev, struct list_head *head) 504static void ipvlan_link_delete(struct net_device *dev, struct list_head *head)