Commit 5dac9eaa authored by David S. Miller's avatar David S. Miller

Merge branch 'mpls-multipath-route-cleanups'

David Ahern says:

====================
net: mpls: multipath route cleanups

When a device associated with a nexthop is deleted, the nexthop in
the route is effectively removed, so remove it from the route dump.

Further, when all nexhops have been deleted the route is effectively
done, so remove the route.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 88275ed0 4ea8efad
...@@ -1299,7 +1299,7 @@ static void mpls_ifdown(struct net_device *dev, int event) ...@@ -1299,7 +1299,7 @@ static void mpls_ifdown(struct net_device *dev, int event)
struct mpls_route __rcu **platform_label; struct mpls_route __rcu **platform_label;
struct net *net = dev_net(dev); struct net *net = dev_net(dev);
unsigned int nh_flags = RTNH_F_DEAD | RTNH_F_LINKDOWN; unsigned int nh_flags = RTNH_F_DEAD | RTNH_F_LINKDOWN;
unsigned int alive; unsigned int alive, deleted;
unsigned index; unsigned index;
platform_label = rtnl_dereference(net->mpls.platform_label); platform_label = rtnl_dereference(net->mpls.platform_label);
...@@ -1310,6 +1310,7 @@ static void mpls_ifdown(struct net_device *dev, int event) ...@@ -1310,6 +1310,7 @@ static void mpls_ifdown(struct net_device *dev, int event)
continue; continue;
alive = 0; alive = 0;
deleted = 0;
change_nexthops(rt) { change_nexthops(rt) {
if (rtnl_dereference(nh->nh_dev) != dev) if (rtnl_dereference(nh->nh_dev) != dev)
goto next; goto next;
...@@ -1328,9 +1329,15 @@ static void mpls_ifdown(struct net_device *dev, int event) ...@@ -1328,9 +1329,15 @@ static void mpls_ifdown(struct net_device *dev, int event)
next: next:
if (!(nh->nh_flags & nh_flags)) if (!(nh->nh_flags & nh_flags))
alive++; alive++;
if (!rtnl_dereference(nh->nh_dev))
deleted++;
} endfor_nexthops(rt); } endfor_nexthops(rt);
WRITE_ONCE(rt->rt_nhn_alive, alive); 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);
} }
} }
...@@ -1769,12 +1776,14 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event, ...@@ -1769,12 +1776,14 @@ static int mpls_dump_route(struct sk_buff *skb, u32 portid, u32 seq, int event,
goto nla_put_failure; goto nla_put_failure;
for_nexthops(rt) { for_nexthops(rt) {
dev = rtnl_dereference(nh->nh_dev);
if (!dev)
continue;
rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh)); rtnh = nla_reserve_nohdr(skb, sizeof(*rtnh));
if (!rtnh) if (!rtnh)
goto nla_put_failure; goto nla_put_failure;
dev = rtnl_dereference(nh->nh_dev);
if (dev)
rtnh->rtnh_ifindex = dev->ifindex; rtnh->rtnh_ifindex = dev->ifindex;
if (nh->nh_flags & RTNH_F_LINKDOWN) { if (nh->nh_flags & RTNH_F_LINKDOWN) {
rtnh->rtnh_flags |= RTNH_F_LINKDOWN; rtnh->rtnh_flags |= RTNH_F_LINKDOWN;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment