diff options
-rw-r--r-- | net/bridge/br_netlink.c | 5 | ||||
-rw-r--r-- | net/core/rtnetlink.c | 45 |
2 files changed, 26 insertions, 24 deletions
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 66ece91ee165..163950b10d8c 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -569,6 +569,11 @@ int br_dellink(struct net_device *dev, struct nlmsghdr *nlh) | |||
569 | 569 | ||
570 | err = br_afspec((struct net_bridge *)netdev_priv(dev), p, | 570 | err = br_afspec((struct net_bridge *)netdev_priv(dev), p, |
571 | afspec, RTM_DELLINK); | 571 | afspec, RTM_DELLINK); |
572 | if (err == 0) | ||
573 | /* Send RTM_NEWLINK because userspace | ||
574 | * expects RTM_NEWLINK for vlan dels | ||
575 | */ | ||
576 | br_ifinfo_notify(RTM_NEWLINK, p); | ||
572 | 577 | ||
573 | return err; | 578 | return err; |
574 | } | 579 | } |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index 6a6cdade1676..eadc5c0e2dfa 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -2880,32 +2880,24 @@ static inline size_t bridge_nlmsg_size(void) | |||
2880 | + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */ | 2880 | + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */ |
2881 | } | 2881 | } |
2882 | 2882 | ||
2883 | static int rtnl_bridge_notify(struct net_device *dev, u16 flags) | 2883 | static int rtnl_bridge_notify(struct net_device *dev) |
2884 | { | 2884 | { |
2885 | struct net *net = dev_net(dev); | 2885 | struct net *net = dev_net(dev); |
2886 | struct net_device *br_dev = netdev_master_upper_dev_get(dev); | ||
2887 | struct sk_buff *skb; | 2886 | struct sk_buff *skb; |
2888 | int err = -EOPNOTSUPP; | 2887 | int err = -EOPNOTSUPP; |
2889 | 2888 | ||
2889 | if (!dev->netdev_ops->ndo_bridge_getlink) | ||
2890 | return 0; | ||
2891 | |||
2890 | skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC); | 2892 | skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC); |
2891 | if (!skb) { | 2893 | if (!skb) { |
2892 | err = -ENOMEM; | 2894 | err = -ENOMEM; |
2893 | goto errout; | 2895 | goto errout; |
2894 | } | 2896 | } |
2895 | 2897 | ||
2896 | if ((!flags || (flags & BRIDGE_FLAGS_MASTER)) && | 2898 | err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0); |
2897 | br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { | 2899 | if (err < 0) |
2898 | err = br_dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0); | 2900 | goto errout; |
2899 | if (err < 0) | ||
2900 | goto errout; | ||
2901 | } | ||
2902 | |||
2903 | if ((flags & BRIDGE_FLAGS_SELF) && | ||
2904 | dev->netdev_ops->ndo_bridge_getlink) { | ||
2905 | err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev, 0); | ||
2906 | if (err < 0) | ||
2907 | goto errout; | ||
2908 | } | ||
2909 | 2901 | ||
2910 | rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); | 2902 | rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); |
2911 | return 0; | 2903 | return 0; |
@@ -2975,16 +2967,18 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2975 | err = -EOPNOTSUPP; | 2967 | err = -EOPNOTSUPP; |
2976 | else | 2968 | else |
2977 | err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh); | 2969 | err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh); |
2978 | 2970 | if (!err) { | |
2979 | if (!err) | ||
2980 | flags &= ~BRIDGE_FLAGS_SELF; | 2971 | flags &= ~BRIDGE_FLAGS_SELF; |
2972 | |||
2973 | /* Generate event to notify upper layer of bridge | ||
2974 | * change | ||
2975 | */ | ||
2976 | err = rtnl_bridge_notify(dev); | ||
2977 | } | ||
2981 | } | 2978 | } |
2982 | 2979 | ||
2983 | if (have_flags) | 2980 | if (have_flags) |
2984 | memcpy(nla_data(attr), &flags, sizeof(flags)); | 2981 | memcpy(nla_data(attr), &flags, sizeof(flags)); |
2985 | /* Generate event to notify upper layer of bridge change */ | ||
2986 | if (!err) | ||
2987 | err = rtnl_bridge_notify(dev, oflags); | ||
2988 | out: | 2982 | out: |
2989 | return err; | 2983 | return err; |
2990 | } | 2984 | } |
@@ -3049,15 +3043,18 @@ static int rtnl_bridge_dellink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
3049 | else | 3043 | else |
3050 | err = dev->netdev_ops->ndo_bridge_dellink(dev, nlh); | 3044 | err = dev->netdev_ops->ndo_bridge_dellink(dev, nlh); |
3051 | 3045 | ||
3052 | if (!err) | 3046 | if (!err) { |
3053 | flags &= ~BRIDGE_FLAGS_SELF; | 3047 | flags &= ~BRIDGE_FLAGS_SELF; |
3048 | |||
3049 | /* Generate event to notify upper layer of bridge | ||
3050 | * change | ||
3051 | */ | ||
3052 | err = rtnl_bridge_notify(dev); | ||
3053 | } | ||
3054 | } | 3054 | } |
3055 | 3055 | ||
3056 | if (have_flags) | 3056 | if (have_flags) |
3057 | memcpy(nla_data(attr), &flags, sizeof(flags)); | 3057 | memcpy(nla_data(attr), &flags, sizeof(flags)); |
3058 | /* Generate event to notify upper layer of bridge change */ | ||
3059 | if (!err) | ||
3060 | err = rtnl_bridge_notify(dev, oflags); | ||
3061 | out: | 3058 | out: |
3062 | return err; | 3059 | return err; |
3063 | } | 3060 | } |