Skip to content

Commit 29c6735

Browse files
author
Hangbin Liu
committed
net: ipv6: fix dst ref loop on input in seg6 lwt
JIRA: https://issues.redhat.com/browse/RHEL-84573 Upstream Status: net.git commit c64a072 Conflicts: context conflicts due to missing commit 40475b6 ("net: ipv6: seg6_iptunnel: mitigate 2-realloc issue"). commit c64a072 Author: Justin Iurman <justin.iurman@uliege.be> Date: Tue Feb 25 18:51:38 2025 +0100 net: ipv6: fix dst ref loop on input in seg6 lwt Prevent a dst ref loop on input in seg6_iptunnel. Fixes: af4a220 ("ipv6: sr: use dst_cache in seg6_input") Cc: David Lebrun <dlebrun@google.com> Cc: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Justin Iurman <justin.iurman@uliege.be> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Hangbin Liu <haliu@redhat.com>
1 parent 98af8bc commit 29c6735

File tree

1 file changed

+12
-2
lines changed

1 file changed

+12
-2
lines changed

net/ipv6/seg6_iptunnel.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -455,22 +455,32 @@ static int seg6_input_core(struct net *net, struct sock *sk,
455455
{
456456
struct dst_entry *orig_dst = skb_dst(skb);
457457
struct dst_entry *dst = NULL;
458+
struct lwtunnel_state *lwtst;
458459
struct seg6_lwt *slwt;
459460
int err;
460461

461462
err = seg6_do_srh(skb);
462463
if (unlikely(err))
463464
goto drop;
464465

465-
slwt = seg6_lwt_lwtunnel(orig_dst->lwtstate);
466+
/* We cannot dereference "orig_dst" once ip6_route_input() or
467+
* skb_dst_drop() is called. However, in order to detect a dst loop, we
468+
* need the address of its lwtstate. So, save the address of lwtstate
469+
* now and use it later as a comparison.
470+
*/
471+
lwtst = orig_dst->lwtstate;
472+
473+
slwt = seg6_lwt_lwtunnel(lwtst);
466474

467475
local_bh_disable();
468476
dst = dst_cache_get(&slwt->cache);
469477

470478
if (!dst) {
471479
ip6_route_input(skb);
472480
dst = skb_dst(skb);
473-
if (!dst->error) {
481+
482+
/* cache only if we don't create a dst reference loop */
483+
if (!dst->error && lwtst != dst->lwtstate) {
474484
dst_cache_set_ip6(&slwt->cache, dst,
475485
&ipv6_hdr(skb)->saddr);
476486
}

0 commit comments

Comments
 (0)