ipv6: honor RT6_LOOKUP_F_DST_NOREF in rule lookup logic

This patch specifically converts the rule lookup logic to honor this
flag and not release refcnt when traversing each rule and calling
lookup() on each routing table.
Similar to previous patch, we also need some special handling of dst
entries in uncached list because there is always 1 refcnt taken for them
even if RT6_LOOKUP_F_DST_NOREF flag is set.

Signed-off-by: Wei Wang <weiwan@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Wei Wang
2019-06-20 17:36:39 -07:00
کامیت شده توسط David S. Miller
والد 74109218b0
کامیت d64a1f574a
3فایلهای تغییر یافته به همراه20 افزوده شده و 7 حذف شده

مشاهده پرونده

@@ -113,14 +113,15 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
rt = lookup(net, net->ipv6.fib6_local_tbl, fl6, skb, flags);
if (rt != net->ipv6.ip6_null_entry && rt->dst.error != -EAGAIN)
return &rt->dst;
ip6_rt_put(rt);
ip6_rt_put_flags(rt, flags);
rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, skb, flags);
if (rt->dst.error != -EAGAIN)
return &rt->dst;
ip6_rt_put(rt);
ip6_rt_put_flags(rt, flags);
}
dst_hold(&net->ipv6.ip6_null_entry->dst);
if (!(flags & RT6_LOOKUP_F_DST_NOREF))
dst_hold(&net->ipv6.ip6_null_entry->dst);
return &net->ipv6.ip6_null_entry->dst;
}
@@ -237,13 +238,14 @@ static int __fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
goto out;
}
again:
ip6_rt_put(rt);
ip6_rt_put_flags(rt, flags);
err = -EAGAIN;
rt = NULL;
goto out;
discard_pkt:
dst_hold(&rt->dst);
if (!(flags & RT6_LOOKUP_F_DST_NOREF))
dst_hold(&rt->dst);
out:
res->rt6 = rt;
return err;

مشاهده پرونده

@@ -316,9 +316,10 @@ struct dst_entry *fib6_rule_lookup(struct net *net, struct flowi6 *fl6,
rt = lookup(net, net->ipv6.fib6_main_tbl, fl6, skb, flags);
if (rt->dst.error == -EAGAIN) {
ip6_rt_put(rt);
ip6_rt_put_flags(rt, flags);
rt = net->ipv6.ip6_null_entry;
dst_hold(&rt->dst);
if (!(flags | RT6_LOOKUP_F_DST_NOREF))
dst_hold(&rt->dst);
}
return &rt->dst;