summaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
authorLinus Walleij <linus.walleij@linaro.org>2014-03-14 10:26:45 +0100
committerLinus Walleij <linus.walleij@linaro.org>2014-03-14 10:26:45 +0100
commit9e294427f6e427dbaf46140303acded06365f53c (patch)
tree0669100cbd79fe8612463900171c98873d8dc454 /net/core/rtnetlink.c
parent23600969ff137cf4c3bc9098f77e381de334e3f7 (diff)
parentfa389e220254c69ffae0d403eac4146171062d08 (diff)
Merge tag 'v3.14-rc6' into devel
Linux 3.14-rc6
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 393b1bc9a61..1a0dac2ef9a 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -374,7 +374,7 @@ static size_t rtnl_link_get_slave_info_data_size(const struct net_device *dev)
if (!master_dev)
return 0;
ops = master_dev->rtnl_link_ops;
- if (!ops->get_slave_size)
+ if (!ops || !ops->get_slave_size)
return 0;
/* IFLA_INFO_SLAVE_DATA + nested data */
return nla_total_size(sizeof(struct nlattr)) +
@@ -1963,16 +1963,21 @@ replay:
dev->ifindex = ifm->ifi_index;
- if (ops->newlink)
+ if (ops->newlink) {
err = ops->newlink(net, dev, tb, data);
- else
+ /* Drivers should call free_netdev() in ->destructor
+ * and unregister it on failure so that device could be
+ * finally freed in rtnl_unlock.
+ */
+ if (err < 0)
+ goto out;
+ } else {
err = register_netdevice(dev);
-
- if (err < 0) {
- free_netdev(dev);
- goto out;
+ if (err < 0) {
+ free_netdev(dev);
+ goto out;
+ }
}
-
err = rtnl_configure_link(dev, ifm);
if (err < 0)
unregister_netdevice(dev);