aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/bridge/br_netlink.c5
-rw-r--r--net/core/rtnetlink.c45
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
2883static int rtnl_bridge_notify(struct net_device *dev, u16 flags) 2883static 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);
2988out: 2982out:
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);
3061out: 3058out:
3062 return err; 3059 return err;
3063} 3060}