diff options
author | Steffen Klassert <steffen.klassert@secunet.com> | 2024-07-13 12:14:04 +0300 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2024-07-13 12:14:04 +0300 |
commit | d5b60c6517d227b044674718a993caae19080f7b (patch) | |
tree | 4ea6ca4711e34aa7695c69e4c020c5f9ec8deae0 /net/xfrm | |
parent | f531d13bdfe3f4f084aaa8acae2cb0f02295f5ae (diff) | |
parent | 447bc4b1906f100e65c662528b7ae4e1dc2e9b80 (diff) | |
download | linux-d5b60c6517d227b044674718a993caae19080f7b.tar.xz |
Merge branch 'Support IPsec crypto offload for IPv6 ESP and IPv4 UDP-encapsulated ESP data paths'
Mike Yu says:
====================
Currently, IPsec crypto offload is enabled for GRO code path. However, there
are other code paths where the XFRM stack is involved; for example, IPv6 ESP
packets handled by xfrm6_esp_rcv() in ESP layer, and IPv4 UDP-encapsulated
ESP packets handled by udp_rcv() in UDP layer.
This patchset extends the crypto offload support to cover these two cases.
This is useful for devices with traffic accounting (e.g., Android), where GRO
can lead to inaccurate accounting on the underlying network. For example, VPN
traffic might not be counted on the wifi network interface wlan0 if the packets
are handled in GRO code path before entering the network stack for accounting.
Below is the RX data path scenario the crypto offload can be applied to.
+-----------+ +-------+
| HW Driver |-->| wlan0 |--------+
+-----------+ +-------+ |
v
+---------------+ +------+
+------>| Network Stack |-->| Apps |
| +---------------+ +------+
| |
| v
+--------+ +------------+
| ipsec1 |<--| XFRM Stack |
+--------+ +------------+
====================
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_device.c | 6 | ||||
-rw-r--r-- | net/xfrm/xfrm_input.c | 3 | ||||
-rw-r--r-- | net/xfrm/xfrm_policy.c | 5 |
3 files changed, 9 insertions, 5 deletions
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c index 2455a76a1cff..9a44d363ba62 100644 --- a/net/xfrm/xfrm_device.c +++ b/net/xfrm/xfrm_device.c @@ -261,9 +261,9 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, is_packet_offload = xuo->flags & XFRM_OFFLOAD_PACKET; - /* We don't yet support UDP encapsulation and TFC padding. */ - if ((!is_packet_offload && x->encap) || x->tfcpad) { - NL_SET_ERR_MSG(extack, "Encapsulation and TFC padding can't be offloaded"); + /* We don't yet support TFC padding. */ + if (x->tfcpad) { + NL_SET_ERR_MSG(extack, "TFC padding can't be offloaded"); return -EINVAL; } diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c index d2ea18dcb0cb..7cee9c0a2cdc 100644 --- a/net/xfrm/xfrm_input.c +++ b/net/xfrm/xfrm_input.c @@ -471,7 +471,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type) struct xfrm_offload *xo = xfrm_offload(skb); struct sec_path *sp; - if (encap_type < 0 || (xo && xo->flags & XFRM_GRO)) { + if (encap_type < 0 || (xo && (xo->flags & XFRM_GRO || encap_type == 0 || + encap_type == UDP_ENCAP_ESPINUDP))) { x = xfrm_input_state(skb); if (unlikely(x->dir && x->dir != XFRM_SA_DIR_IN)) { diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 6603d3bd171f..2a9a31f2a9c1 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c @@ -3718,12 +3718,15 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb, pol = xfrm_in_fwd_icmp(skb, &fl, family, if_id); if (!pol) { + const bool is_crypto_offload = sp && + (xfrm_input_state(skb)->xso.type == XFRM_DEV_OFFLOAD_CRYPTO); + if (net->xfrm.policy_default[dir] == XFRM_USERPOLICY_BLOCK) { XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS); return 0; } - if (sp && secpath_has_nontransport(sp, 0, &xerr_idx)) { + if (sp && secpath_has_nontransport(sp, 0, &xerr_idx) && !is_crypto_offload) { xfrm_secpath_reject(xerr_idx, skb, &fl); XFRM_INC_STATS(net, LINUX_MIB_XFRMINNOPOLS); return 0; |