Skip to content

Commit

Permalink
Merge tag 'ipsec-2025-03-19' of git://git.kernel.org/pub/scm/linux/ke…
Browse files Browse the repository at this point in the history
…rnel/git/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2025-03-19

1) Fix tunnel mode TX datapath in packet offload mode
   by directly putting it to the xmit path.
   From Alexandre Cassen.

2) Force software GSO only in tunnel mode in favor
   of potential HW GSO. From Cosmin Ratiu.

ipsec-2025-03-19

* tag 'ipsec-2025-03-19' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec:
  xfrm_output: Force software GSO only in tunnel mode
  xfrm: fix tunnel mode TX datapath in packet offload mode
====================

Link: https://patch.msgid.link/20250319065513.987135-1-steffen.klassert@secunet.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Paolo Abeni committed Mar 20, 2025
2 parents 2fdf088 + 0aae286 commit 8476165
Showing 1 changed file with 42 additions and 1 deletion.
43 changes: 42 additions & 1 deletion net/xfrm/xfrm_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,40 @@ int xfrm_output_resume(struct sock *sk, struct sk_buff *skb, int err)
}
EXPORT_SYMBOL_GPL(xfrm_output_resume);

static int xfrm_dev_direct_output(struct sock *sk, struct xfrm_state *x,
struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
struct net *net = xs_net(x);
int err;

dst = skb_dst_pop(skb);
if (!dst) {
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTERROR);
kfree_skb(skb);
return -EHOSTUNREACH;
}
skb_dst_set(skb, dst);
nf_reset_ct(skb);

err = skb_dst(skb)->ops->local_out(net, sk, skb);
if (unlikely(err != 1)) {
kfree_skb(skb);
return err;
}

/* In transport mode, network destination is
* directly reachable, while in tunnel mode,
* inner packet network may not be. In packet
* offload type, HW is responsible for hard
* header packet mangling so directly xmit skb
* to netdevice.
*/
skb->dev = x->xso.dev;
__skb_push(skb, skb->dev->hard_header_len);
return dev_queue_xmit(skb);
}

static int xfrm_output2(struct net *net, struct sock *sk, struct sk_buff *skb)
{
return xfrm_output_resume(sk, skb, 1);
Expand Down Expand Up @@ -735,6 +769,13 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
return -EHOSTUNREACH;
}

/* Exclusive direct xmit for tunnel mode, as
* some filtering or matching rules may apply
* in transport mode.
*/
if (x->props.mode == XFRM_MODE_TUNNEL)
return xfrm_dev_direct_output(sk, x, skb);

return xfrm_output_resume(sk, skb, 0);
}

Expand All @@ -758,7 +799,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb)
skb->encapsulation = 1;

if (skb_is_gso(skb)) {
if (skb->inner_protocol)
if (skb->inner_protocol && x->props.mode == XFRM_MODE_TUNNEL)
return xfrm_output_gso(net, sk, skb);

skb_shinfo(skb)->gso_type |= SKB_GSO_ESP;
Expand Down

0 comments on commit 8476165

Please sign in to comment.