Re: [PATCH net-next v3 1/2] seg6: skip the route refcount in seg6local IPv6 lookups
From: Andrea Mayer
Date: Mon Oct 19 2026 - 19:05:44 EST
On Thu, 15 Oct 2026 23:39:27 +0900
Yuya Kusakabe <yuya.kusakabe@xxxxxxxxx> wrote:
Hi Yuya,
Thanks for v3 and considering my comments.
> [snip]
> if (!table)
> goto out;
>
> + if (noref)
> + flags |= RT6_LOOKUP_F_DST_NOREF;
Even with the change below, the "out:" branch still takes a reference when
fib6_get_table() returns NULL, because RT6_LOOKUP_F_DST_NOREF is set only
after that call. Setting RT6_LOOKUP_F_DST_NOREF before fib6_get_table(),
inside the table branch, would avoid that reference too. The oif branch
needs the flag clear, because ip6_route_output() returns the dst with a
reference.
> [snip]
> rt = net->ipv6.ip6_blk_hole_entry;
> dst = &rt->dst;
> dst_hold(dst);
> + flags &= ~RT6_LOOKUP_F_DST_NOREF;
> }
With this patch applied, the end of seg6_lookup_any_nexthop() reads:
out:
if (!dst) {
rt = net->ipv6.ip6_blk_hole_entry;
dst = &rt->dst;
dst_hold(dst);
flags &= ~RT6_LOOKUP_F_DST_NOREF;
}
skb_dst_drop(skb);
if ((flags & RT6_LOOKUP_F_DST_NOREF) && !dst->rt_uncached_list)
skb_dst_set_noref(skb, dst);
else
skb_dst_set(skb, dst);
return dst->error;
After a noref lookup, the "out:" branch still takes a reference on
ip6_blk_hole_entry and then clears RT6_LOOKUP_F_DST_NOREF.
This branch can be taken at steady state. The noref lookups, except the
ones in input_action_end_dt6(), run with local_delivery false. For example,
with End and a next segment that is a local address of the node, the lookup
returns a local route, seg6_lookup_any_nexthop() discards it, and every
packet takes and drops a reference on ip6_blk_hole_entry in the "out:"
branch. The commit message describes the same pattern for ip6_null_entry.
For a blackhole rule, __fib6_rule_action() picks ip6_blk_hole_entry and
takes no reference on it when the lookup has RT6_LOOKUP_F_DST_NOREF. The
"out:" branch could do the same, for example:
if (!dst) {
dst = &net->ipv6.ip6_blk_hole_entry->dst;
if (!(flags & RT6_LOOKUP_F_DST_NOREF))
dst_hold(dst);
}
RT6_LOOKUP_F_DST_NOREF then stays set, and the skb_dst_set_noref() at the
end of the function attaches ip6_blk_hole_entry without a reference. The
line that clears RT6_LOOKUP_F_DST_NOREF is removed as well.
What do you think?
Nit: seg6_lookup_any_nexthop_noref() and seg6_lookup_nexthop_noref() can
attach the dst without a reference. They rely on being called under RCU. A
one line comment about this, like the one ip6_route_input() has, could help
the next reader.
Ciao,
Andrea