diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c index 3861f8dfa9c1..74755920c689 100644 --- a/net/mpls/af_mpls.c +++ b/net/mpls/af_mpls.c @@ -1299,7 +1299,7 @@ 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 int alive, deleted; unsigned index; platform_label = rtnl_dereference(net->mpls.platform_label); @@ -1310,6 +1310,7 @@ static void mpls_ifdown(struct net_device *dev, int event) continue; alive = 0; + deleted = 0; change_nexthops(rt) { if (rtnl_dereference(nh->nh_dev) != dev) goto next; @@ -1328,9 +1329,15 @@ static void mpls_ifdown(struct net_device *dev, int event) next: if (!(nh->nh_flags & nh_flags)) alive++; + if (!rtnl_dereference(nh->nh_dev)) + deleted++; } endfor_nexthops(rt); WRITE_ONCE(rt->rt_nhn_alive, alive); + + /* if there are no more nexthops, delete the route */ + if (event == NETDEV_UNREGISTER && deleted == rt->rt_nhn) + mpls_route_update(net, index, NULL, NULL); } }