diff options
author | David S. Miller <davem@davemloft.net> | 2017-03-23 15:11:56 -0700 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-03-23 16:41:27 -0700 |
commit | 16ae1f223601c44e5cb65c99257ffae003504704 (patch) | |
tree | 1f5284c0e82e4d94ca07eb022fa7911d99bb0cb6 /net/mpls | |
parent | 6f359f99b8c2ff3b09329611da00fe39a7c10e7e (diff) | |
parent | d038e3dcfff6e3de132726a9c7174d8170032aa4 (diff) | |
download | linux-16ae1f223601c44e5cb65c99257ffae003504704.tar.gz linux-16ae1f223601c44e5cb65c99257ffae003504704.tar.bz2 linux-16ae1f223601c44e5cb65c99257ffae003504704.zip |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts:
drivers/net/ethernet/broadcom/genet/bcmmii.c
drivers/net/hyperv/netvsc.c
kernel/bpf/hashtab.c
Almost entirely overlapping changes.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/mpls')
-rw-r--r-- | net/mpls/af_mpls.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index f7a08e5f9763..82589b2abf3c 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1298,6 +1298,8 @@ static void mpls_ifdown(struct net_device *dev, int event) { struct mpls_route __rcu **platform_label; struct net *net = dev_net(dev); + unsigned int nh_flags = RTNH_F_DEAD | RTNH_F_LINKDOWN; + unsigned int alive; unsigned index; platform_label = rtnl_dereference(net->mpls.platform_label); @@ -1307,9 +1309,11 @@ static void mpls_ifdown(struct net_device *dev, int event) if (!rt) continue; + alive = 0; change_nexthops(rt) { if (rtnl_dereference(nh->nh_dev) != dev) - continue; + goto next; + switch (event) { case NETDEV_DOWN: case NETDEV_UNREGISTER: @@ -1317,13 +1321,16 @@ static void mpls_ifdown(struct net_device *dev, int event) /* fall through */ case NETDEV_CHANGE: nh->nh_flags |= RTNH_F_LINKDOWN; - if (event != NETDEV_UNREGISTER) - ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; break; } if (event == NETDEV_UNREGISTER) RCU_INIT_POINTER(nh->nh_dev, NULL); +next: + if (!(nh->nh_flags & nh_flags)) + alive++; } endfor_nexthops(rt); + + WRITE_ONCE(rt->rt_nhn_alive, alive); } } |