diff options
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 393b1bc9a618..1a0dac2ef9ad 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) | |||
374 | if (!master_dev) | 374 | if (!master_dev) |
375 | return 0; | 375 | return 0; |
376 | ops = master_dev->rtnl_link_ops; | 376 | ops = master_dev->rtnl_link_ops; |
377 | if (!ops->get_slave_size) | 377 | if (!ops || !ops->get_slave_size) |
378 | return 0; | 378 | return 0; |
379 | /* IFLA_INFO_SLAVE_DATA + nested data */ | 379 | /* IFLA_INFO_SLAVE_DATA + nested data */ |
380 | return nla_total_size(sizeof(struct nlattr)) + | 380 | return nla_total_size(sizeof(struct nlattr)) + |
@@ -1963,16 +1963,21 @@ replay: | |||
1963 | 1963 | ||
1964 | dev->ifindex = ifm->ifi_index; | 1964 | dev->ifindex = ifm->ifi_index; |
1965 | 1965 | ||
1966 | if (ops->newlink) | 1966 | if (ops->newlink) { |
1967 | err = ops->newlink(net, dev, tb, data); | 1967 | err = ops->newlink(net, dev, tb, data); |
1968 | else | 1968 | /* Drivers should call free_netdev() in ->destructor |
1969 | * and unregister it on failure so that device could be | ||
1970 | * finally freed in rtnl_unlock. | ||
1971 | */ | ||
1972 | if (err < 0) | ||
1973 | goto out; | ||
1974 | } else { | ||
1969 | err = register_netdevice(dev); | 1975 | err = register_netdevice(dev); |
1970 | 1976 | if (err < 0) { | |
1971 | if (err < 0) { | 1977 | free_netdev(dev); |
1972 | free_netdev(dev); | 1978 | goto out; |
1973 | goto out; | 1979 | } |
1974 | } | 1980 | } |
1975 | |||
1976 | err = rtnl_configure_link(dev, ifm); | 1981 | err = rtnl_configure_link(dev, ifm); |
1977 | if (err < 0) | 1982 | if (err < 0) |
1978 | unregister_netdevice(dev); | 1983 | unregister_netdevice(dev); |