Skip to content

Commit

Permalink
net: ipv6: fix dst ref loop on input in seg6 lwt
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Justin Iurman authored and Paolo Abeni committed Feb 27, 2025
1 parent 1cf9631 commit c64a072
Showing 1 changed file with 12 additions and 2 deletions.
14 changes: 12 additions & 2 deletions net/ipv6/seg6_iptunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,10 +472,18 @@ static int seg6_input_core(struct net *net, struct sock *sk,
{
struct dst_entry *orig_dst = skb_dst(skb);
struct dst_entry *dst = NULL;
struct lwtunnel_state *lwtst;
struct seg6_lwt *slwt;
int err;

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

slwt = seg6_lwt_lwtunnel(lwtst);

local_bh_disable();
dst = dst_cache_get(&slwt->cache);
Expand All @@ -490,7 +498,9 @@ static int seg6_input_core(struct net *net, struct sock *sk,
if (!dst) {
ip6_route_input(skb);
dst = skb_dst(skb);
if (!dst->error) {

/* cache only if we don't create a dst reference loop */
if (!dst->error && lwtst != dst->lwtstate) {
local_bh_disable();
dst_cache_set_ip6(&slwt->cache, dst,
&ipv6_hdr(skb)->saddr);
Expand Down

0 comments on commit c64a072

Please sign in to comment.