Skip to content

Commit

Permalink
net: bridge: avoid duplicate notification on up/down/change netdev ev…
Browse files Browse the repository at this point in the history
…ents

While handling netdevice events, br_device_event() sometimes uses
br_stp_(disable|enable)_port which unconditionally send a notification,
but then a second notification for the same event is sent at the end of
the br_device_event() function. To avoid sending duplicate notifications
in such cases, check if one has already been sent (i.e.
br_stp_enable/disable_port have been called).
The patch is based on a change by Satish Ashok.

Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Nikolay Aleksandrov authored and David S. Miller committed May 3, 2018
1 parent 2e51855 commit faa1cd8
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 8 deletions.
12 changes: 8 additions & 4 deletions net/bridge/br.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
struct net_bridge_port *p;
struct net_bridge *br;
bool notified = false;
bool changed_addr;
int err;

Expand Down Expand Up @@ -67,7 +68,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
break;

case NETDEV_CHANGE:
br_port_carrier_check(p);
br_port_carrier_check(p, &notified);
break;

case NETDEV_FEAT_CHANGE:
Expand All @@ -76,15 +77,18 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v

case NETDEV_DOWN:
spin_lock_bh(&br->lock);
if (br->dev->flags & IFF_UP)
if (br->dev->flags & IFF_UP) {
br_stp_disable_port(p);
notified = true;
}
spin_unlock_bh(&br->lock);
break;

case NETDEV_UP:
if (netif_running(br->dev) && netif_oper_up(dev)) {
spin_lock_bh(&br->lock);
br_stp_enable_port(p);
notified = true;
spin_unlock_bh(&br->lock);
}
break;
Expand All @@ -110,8 +114,8 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
}

/* Events that may cause spanning tree to refresh */
if (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
event == NETDEV_CHANGE || event == NETDEV_DOWN)
if (!notified && (event == NETDEV_CHANGEADDR || event == NETDEV_UP ||
event == NETDEV_CHANGE || event == NETDEV_DOWN))
br_ifinfo_notify(RTM_NEWLINK, NULL, p);

return NOTIFY_DONE;
Expand Down
11 changes: 8 additions & 3 deletions net/bridge/br_if.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ static int port_cost(struct net_device *dev)


/* Check for port carrier transitions. */
void br_port_carrier_check(struct net_bridge_port *p)
void br_port_carrier_check(struct net_bridge_port *p, bool *notified)
{
struct net_device *dev = p->dev;
struct net_bridge *br = p->br;
Expand All @@ -73,16 +73,21 @@ void br_port_carrier_check(struct net_bridge_port *p)
netif_running(dev) && netif_oper_up(dev))
p->path_cost = port_cost(dev);

*notified = false;
if (!netif_running(br->dev))
return;

spin_lock_bh(&br->lock);
if (netif_running(dev) && netif_oper_up(dev)) {
if (p->state == BR_STATE_DISABLED)
if (p->state == BR_STATE_DISABLED) {
br_stp_enable_port(p);
*notified = true;
}
} else {
if (p->state != BR_STATE_DISABLED)
if (p->state != BR_STATE_DISABLED) {
br_stp_disable_port(p);
*notified = true;
}
}
spin_unlock_bh(&br->lock);
}
Expand Down
2 changes: 1 addition & 1 deletion net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -573,7 +573,7 @@ void br_flood(struct net_bridge *br, struct sk_buff *skb,
enum br_pkt_type pkt_type, bool local_rcv, bool local_orig);

/* br_if.c */
void br_port_carrier_check(struct net_bridge_port *p);
void br_port_carrier_check(struct net_bridge_port *p, bool *notified);
int br_add_bridge(struct net *net, const char *name);
int br_del_bridge(struct net *net, const char *name);
int br_add_if(struct net_bridge *br, struct net_device *dev,
Expand Down

0 comments on commit faa1cd8

Please sign in to comment.