From 5deaa6f55b00547980035ef0d6e7ba4514ee24e5 Mon Sep 17 00:00:00 2001 From: John Fastabend Date: Fri, 2 Nov 2012 16:32:36 +0000 Subject: [PATCH] --- yaml --- r: 340645 b: refs/heads/master c: c38e01b8b958cb6606bcc156d3d00c3ee99a13f8 h: refs/heads/master i: 340643: b20d0e98a6dd414c706e646a469e33441fd81f2c v: v3 --- [refs] | 2 +- trunk/net/core/rtnetlink.c | 26 ++++++++++++++++++-------- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/[refs] b/[refs] index 226faec3ad62..700fa60c0bc6 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 26cdfb4915a9a408f4c1f04111999a11eb0ee606 +refs/heads/master: c38e01b8b958cb6606bcc156d3d00c3ee99a13f8 diff --git a/trunk/net/core/rtnetlink.c b/trunk/net/core/rtnetlink.c index a0e350763fbe..04a201abcf0e 100644 --- a/trunk/net/core/rtnetlink.c +++ b/trunk/net/core/rtnetlink.c @@ -2364,13 +2364,19 @@ static int rtnl_bridge_notify(struct net_device *dev, u16 flags) goto errout; } - if (!flags && master && master->netdev_ops->ndo_bridge_getlink) + if ((!flags || (flags & BRIDGE_FLAGS_MASTER)) && + master && master->netdev_ops->ndo_bridge_getlink) { err = master->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); - else if (dev->netdev_ops->ndo_bridge_getlink) - err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); + if (err < 0) + goto errout; + } - if (err < 0) - goto errout; + if ((flags & BRIDGE_FLAGS_SELF) && + dev->netdev_ops->ndo_bridge_getlink) { + err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); + if (err < 0) + goto errout; + } rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); return 0; @@ -2389,7 +2395,8 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, struct net_device *dev; struct nlattr *br_spec, *attr = NULL; int rem, err = -EOPNOTSUPP; - u16 flags = 0; + u16 oflags, flags = 0; + bool have_flags = false; if (nlmsg_len(nlh) < sizeof(*ifm)) return -EINVAL; @@ -2408,12 +2415,15 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, if (br_spec) { nla_for_each_nested(attr, br_spec, rem) { if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { + have_flags = true; flags = nla_get_u16(attr); break; } } } + oflags = flags; + if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { if (!dev->master || !dev->master->netdev_ops->ndo_bridge_setlink) { @@ -2438,11 +2448,11 @@ static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, flags &= ~BRIDGE_FLAGS_SELF; } - if (attr && nla_type(attr) == IFLA_BRIDGE_FLAGS) + if (have_flags) memcpy(nla_data(attr), &flags, sizeof(flags)); /* Generate event to notify upper layer of bridge change */ if (!err) - err = rtnl_bridge_notify(dev, flags); + err = rtnl_bridge_notify(dev, oflags); out: return err; }