Skip to content

Commit 7343ff3

Browse files
committed
ipv6: Don't create clones of host routes.
Addresses https://bugzilla.kernel.org/show_bug.cgi?id=29252 Addresses https://bugzilla.kernel.org/show_bug.cgi?id=30462 In commit d80bc0f ("ipv6: Always clone offlink routes.") we forced the kernel to always clone offlink routes. The reason we do that is to make sure we never bind an inetpeer to a prefixed route. The logic turned on here has existed in the tree for many years, but was always off due to a protecting CPP define. So perhaps it's no surprise that there is a logic bug here. The problem is that we canot clone a route that is already a host route (ie. has DST_HOST set). Because if we do, an identical entry already exists in the routing tree and therefore the ip6_rt_ins() call is going to fail. This sets off a series of failures and high cpu usage, because when ip6_rt_ins() fails we loop retrying this operation a few times in order to handle a race between two threads trying to clone and insert the same host route at the same time. Fix this by simply using the route as-is when DST_HOST is set. Reported-by: [email protected] Reported-by: Ernst Sjöstrand <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 03a14ab commit 7343ff3

File tree

1 file changed

+3
-1
lines changed

1 file changed

+3
-1
lines changed

net/ipv6/route.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -739,8 +739,10 @@ static struct rt6_info *ip6_pol_route(struct net *net, struct fib6_table *table,
739739

740740
if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
741741
nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
742-
else
742+
else if (!(rt->dst.flags & DST_HOST))
743743
nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
744+
else
745+
goto out2;
744746

745747
dst_release(&rt->dst);
746748
rt = nrt ? : net->ipv6.ip6_null_entry;

0 commit comments

Comments
 (0)