diff options
Diffstat (limited to 'net/mpls/af_mpls.c')
-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 33211f9a2656..6414079aa729 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c | |||
@@ -1269,6 +1269,8 @@ static void mpls_ifdown(struct net_device *dev, int event) | |||
1269 | { | 1269 | { |
1270 | struct mpls_route __rcu **platform_label; | 1270 | struct mpls_route __rcu **platform_label; |
1271 | struct net *net = dev_net(dev); | 1271 | struct net *net = dev_net(dev); |
1272 | unsigned int nh_flags = RTNH_F_DEAD | RTNH_F_LINKDOWN; | ||
1273 | unsigned int alive; | ||
1272 | unsigned index; | 1274 | unsigned index; |
1273 | 1275 | ||
1274 | platform_label = rtnl_dereference(net->mpls.platform_label); | 1276 | platform_label = rtnl_dereference(net->mpls.platform_label); |
@@ -1278,9 +1280,11 @@ static void mpls_ifdown(struct net_device *dev, int event) | |||
1278 | if (!rt) | 1280 | if (!rt) |
1279 | continue; | 1281 | continue; |
1280 | 1282 | ||
1283 | alive = 0; | ||
1281 | change_nexthops(rt) { | 1284 | change_nexthops(rt) { |
1282 | if (rtnl_dereference(nh->nh_dev) != dev) | 1285 | if (rtnl_dereference(nh->nh_dev) != dev) |
1283 | continue; | 1286 | goto next; |
1287 | |||
1284 | switch (event) { | 1288 | switch (event) { |
1285 | case NETDEV_DOWN: | 1289 | case NETDEV_DOWN: |
1286 | case NETDEV_UNREGISTER: | 1290 | case NETDEV_UNREGISTER: |
@@ -1288,13 +1292,16 @@ static void mpls_ifdown(struct net_device *dev, int event) | |||
1288 | /* fall through */ | 1292 | /* fall through */ |
1289 | case NETDEV_CHANGE: | 1293 | case NETDEV_CHANGE: |
1290 | nh->nh_flags |= RTNH_F_LINKDOWN; | 1294 | nh->nh_flags |= RTNH_F_LINKDOWN; |
1291 | if (event != NETDEV_UNREGISTER) | ||
1292 | ACCESS_ONCE(rt->rt_nhn_alive) = rt->rt_nhn_alive - 1; | ||
1293 | break; | 1295 | break; |
1294 | } | 1296 | } |
1295 | if (event == NETDEV_UNREGISTER) | 1297 | if (event == NETDEV_UNREGISTER) |
1296 | RCU_INIT_POINTER(nh->nh_dev, NULL); | 1298 | RCU_INIT_POINTER(nh->nh_dev, NULL); |
1299 | next: | ||
1300 | if (!(nh->nh_flags & nh_flags)) | ||
1301 | alive++; | ||
1297 | } endfor_nexthops(rt); | 1302 | } endfor_nexthops(rt); |
1303 | |||
1304 | WRITE_ONCE(rt->rt_nhn_alive, alive); | ||
1298 | } | 1305 | } |
1299 | } | 1306 | } |
1300 | 1307 | ||