diff mbox

[2/3] bridge: trigger a bridge calculation upon port changes

Message ID 1394680527-28970-3-git-send-email-mcgrof@do-not-panic.com
State Changes Requested, archived
Delegated to: David Miller
Headers show

Commit Message

Luis R. Rodriguez March 13, 2014, 3:15 a.m. UTC
From: "Luis R. Rodriguez" <mcgrof@suse.com>

If netlink is used to tune a port we currently don't trigger a
new recalculation of the bridge id, ensure that happens just as
if we're adding a new net_device onto the bridge.

Cc: Stephen Hemminger <stephen@networkplumber.org>
Cc: bridge@lists.linux-foundation.org
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Cc: xen-devel@lists.xenproject.org
Cc: kvm@vger.kernel.org
Signed-off-by: Luis R. Rodriguez <mcgrof@suse.com>
---
 net/bridge/br_netlink.c | 6 ++++++
 1 file changed, 6 insertions(+)

Comments

Cong Wang March 13, 2014, 6:26 p.m. UTC | #1
On Wed, Mar 12, 2014 at 8:15 PM, Luis R. Rodriguez
<mcgrof@do-not-panic.com> wrote:
>                         spin_lock_bh(&p->br->lock);
>                         err = br_setport(p, tb);
> +                       changed = br_stp_recalculate_bridge_id(p->br);

Looks like you only want to check if the mac addr gets changed here,
but br_stp_recalculate_bridge_id() does more than just checking it,
are you sure the side-effects are all what you want here?

>                         spin_unlock_bh(&p->br->lock);
> +                       if (changed)
> +                               call_netdevice_notifiers(NETDEV_CHANGEADDR,
> +                                                        p->br->dev);
> +                       netdev_update_features(p->br->dev);

I think this is supposed to be in netdev event handler of br->dev
instead of here.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Luis R. Rodriguez March 15, 2014, 1:39 a.m. UTC | #2
On Thu, Mar 13, 2014 at 11:26:25AM -0700, Cong Wang wrote:
> On Wed, Mar 12, 2014 at 8:15 PM, Luis R. Rodriguez
> <mcgrof@do-not-panic.com> wrote:
> >                         spin_lock_bh(&p->br->lock);
> >                         err = br_setport(p, tb);
> > +                       changed = br_stp_recalculate_bridge_id(p->br);
> 
> Looks like you only want to check if the mac addr gets changed here,

Nope, the reason why we want a full thorough check is that br_setport()
may change currently any of these:
                                                                                
  * IFLA_BRPORT_MODE
  * IFLA_BRPORT_GUARD
  * IFLA_BRPORT_FAST_LEAVE
  * IFLA_BRPORT_PROTECT
  * IFLA_BRPORT_LEARNING,
  * IFLA_BRPORT_UNICAST_FLOOD
  * IFLA_BRPORT_COST
  * IFLA_BRPORT_PRIORITY
  * IFLA_BRPORT_STATE

That's good reason to trigger a good inspection. Having the MAC address
change would be simply collateral and its just something we need to do
some additional work for outside of the locking context.

> but br_stp_recalculate_bridge_id() does more than just checking it,
> are you sure the side-effects are all what you want here?

Yeap.

> >                         spin_unlock_bh(&p->br->lock);
> > +                       if (changed)
> > +                               call_netdevice_notifiers(NETDEV_CHANGEADDR,
> > +                                                        p->br->dev);
> > +                       netdev_update_features(p->br->dev);
> 
> I think this is supposed to be in netdev event handler of br->dev
> instead of here.

Do you mean netdev_update_features() ? I mimic'd what was being done on
br_del_if() given that root blocking is doing something similar. If
we need to change something for the above then I suppose it means we need
to change br_del_if() too. Let me know if you see any reason for something
else.

  Luis
Cong Wang March 18, 2014, 8:46 p.m. UTC | #3
On Fri, Mar 14, 2014 at 6:39 PM, Luis R. Rodriguez <mcgrof@suse.com> wrote:
> On Thu, Mar 13, 2014 at 11:26:25AM -0700, Cong Wang wrote:
>> On Wed, Mar 12, 2014 at 8:15 PM, Luis R. Rodriguez
>> <mcgrof@do-not-panic.com> wrote:
>> >                         spin_unlock_bh(&p->br->lock);
>> > +                       if (changed)
>> > +                               call_netdevice_notifiers(NETDEV_CHANGEADDR,
>> > +                                                        p->br->dev);
>> > +                       netdev_update_features(p->br->dev);
>>
>> I think this is supposed to be in netdev event handler of br->dev
>> instead of here.
>
> Do you mean netdev_update_features() ? I mimic'd what was being done on
> br_del_if() given that root blocking is doing something similar. If
> we need to change something for the above then I suppose it means we need
> to change br_del_if() too. Let me know if you see any reason for something
> else.
>

Yeah, for me it looks like it's better to call netdev_update_features()
in the event handler of br->dev, rather than where calling
call_netdevice_notifiers(..., br->dev);.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index e74b6d53..6f1b26d 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -364,6 +364,7 @@  int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
 	struct net_bridge_port *p;
 	struct nlattr *tb[IFLA_BRPORT_MAX + 1];
 	int err = 0;
+	bool changed;
 
 	protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_PROTINFO);
 	afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
@@ -386,7 +387,12 @@  int br_setlink(struct net_device *dev, struct nlmsghdr *nlh)
 
 			spin_lock_bh(&p->br->lock);
 			err = br_setport(p, tb);
+			changed = br_stp_recalculate_bridge_id(p->br);
 			spin_unlock_bh(&p->br->lock);
+			if (changed)
+				call_netdevice_notifiers(NETDEV_CHANGEADDR,
+							 p->br->dev);
+			netdev_update_features(p->br->dev);
 		} else {
 			/* Binary compatibility with old RSTP */
 			if (nla_len(protinfo) < sizeof(u8))