summaryrefslogtreecommitdiff
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2019-04-09 14:41:16 -0700
committerDavid S. Miller <davem@davemloft.net>2019-04-11 14:24:06 -0700
commitaf52a52cbabd8751154483dc8e6685a28746970f (patch)
treedd7bfb604d96ef13f43e6aeb480c320600452503 /net/ipv6/route.c
parent30c15f033847c519bae4a3dc23320e1fbee868eb (diff)
ipv6: Be smarter with null_entry handling in ip6_pol_route_lookup
Clean up the fib6_null_entry handling in ip6_pol_route_lookup. rt6_device_match can return fib6_null_entry, but fib6_multipath_select can not. Consolidate the fib6_null_entry handling and on the final null_entry check set rt and goto out - no need to defer to a second check after rt6_find_cached_rt. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 52aa48a8dbda..0745ed872e5b 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1062,36 +1062,37 @@ static struct rt6_info *ip6_pol_route_lookup(struct net *net,
fn = fib6_node_lookup(&table->tb6_root, &fl6->daddr, &fl6->saddr);
restart:
f6i = rcu_dereference(fn->leaf);
- if (!f6i) {
+ if (!f6i)
f6i = net->ipv6.fib6_null_entry;
- } else {
+ else
f6i = rt6_device_match(net, f6i, &fl6->saddr,
fl6->flowi6_oif, flags);
- if (f6i->fib6_nsiblings && fl6->flowi6_oif == 0)
- f6i = fib6_multipath_select(net, f6i, fl6,
- fl6->flowi6_oif, skb,
- flags);
- }
+
if (f6i == net->ipv6.fib6_null_entry) {
fn = fib6_backtrack(fn, &fl6->saddr);
if (fn)
goto restart;
- }
- trace_fib6_table_lookup(net, f6i, table, fl6);
+ rt = net->ipv6.ip6_null_entry;
+ dst_hold(&rt->dst);
+ goto out;
+ }
+ if (f6i->fib6_nsiblings && fl6->flowi6_oif == 0)
+ f6i = fib6_multipath_select(net, f6i, fl6, fl6->flowi6_oif, skb,
+ flags);
/* Search through exception table */
rt = rt6_find_cached_rt(f6i, &fl6->daddr, &fl6->saddr);
if (rt) {
if (ip6_hold_safe(net, &rt))
dst_use_noref(&rt->dst, jiffies);
- } else if (f6i == net->ipv6.fib6_null_entry) {
- rt = net->ipv6.ip6_null_entry;
- dst_hold(&rt->dst);
} else {
rt = ip6_create_rt_rcu(f6i);
}
+out:
+ trace_fib6_table_lookup(net, f6i, table, fl6);
+
rcu_read_unlock();
return rt;