diff options
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r-- | net/core/rtnetlink.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 393b1bc9a618..120eecc0f5a4 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); |
@@ -2116,12 +2121,13 @@ EXPORT_SYMBOL(rtmsg_ifinfo); | |||
2116 | static int nlmsg_populate_fdb_fill(struct sk_buff *skb, | 2121 | static int nlmsg_populate_fdb_fill(struct sk_buff *skb, |
2117 | struct net_device *dev, | 2122 | struct net_device *dev, |
2118 | u8 *addr, u32 pid, u32 seq, | 2123 | u8 *addr, u32 pid, u32 seq, |
2119 | int type, unsigned int flags) | 2124 | int type, unsigned int flags, |
2125 | int nlflags) | ||
2120 | { | 2126 | { |
2121 | struct nlmsghdr *nlh; | 2127 | struct nlmsghdr *nlh; |
2122 | struct ndmsg *ndm; | 2128 | struct ndmsg *ndm; |
2123 | 2129 | ||
2124 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), NLM_F_MULTI); | 2130 | nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ndm), nlflags); |
2125 | if (!nlh) | 2131 | if (!nlh) |
2126 | return -EMSGSIZE; | 2132 | return -EMSGSIZE; |
2127 | 2133 | ||
@@ -2159,7 +2165,7 @@ static void rtnl_fdb_notify(struct net_device *dev, u8 *addr, int type) | |||
2159 | if (!skb) | 2165 | if (!skb) |
2160 | goto errout; | 2166 | goto errout; |
2161 | 2167 | ||
2162 | err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF); | 2168 | err = nlmsg_populate_fdb_fill(skb, dev, addr, 0, 0, type, NTF_SELF, 0); |
2163 | if (err < 0) { | 2169 | if (err < 0) { |
2164 | kfree_skb(skb); | 2170 | kfree_skb(skb); |
2165 | goto errout; | 2171 | goto errout; |
@@ -2384,7 +2390,8 @@ static int nlmsg_populate_fdb(struct sk_buff *skb, | |||
2384 | 2390 | ||
2385 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, | 2391 | err = nlmsg_populate_fdb_fill(skb, dev, ha->addr, |
2386 | portid, seq, | 2392 | portid, seq, |
2387 | RTM_NEWNEIGH, NTF_SELF); | 2393 | RTM_NEWNEIGH, NTF_SELF, |
2394 | NLM_F_MULTI); | ||
2388 | if (err < 0) | 2395 | if (err < 0) |
2389 | return err; | 2396 | return err; |
2390 | skip: | 2397 | skip: |