diff mbox series

[RFC,ipsec-next,7/8] iptfs: xfrm: add generic iptfs defines and functionality

Message ID 20231110113719.3055788-8-chopps@chopps.org (mailing list archive)
State RFC
Delegated to: Netdev Maintainers
Headers show
Series [RFC,ipsec-next,1/8] iptfs: config: add CONFIG_XFRM_IPTFS | expand

Checks

Context Check Description
netdev/series_format warning Series does not have a cover letter
netdev/tree_selection success Guessed tree name to be net-next
netdev/fixes_present success Fixes tag not required for -next series
netdev/header_inline success No static functions without inline keyword in header files
netdev/build_32bit fail Errors and warnings before: 4140 this patch: 4239
netdev/cc_maintainers warning 15 maintainers not CCed: 0x7f454c46@gmail.com kadlec@netfilter.org coreteam@netfilter.org fw@strlen.de heng.guo@windriver.com fruggeri@arista.com herbert@gondor.apana.org.au kuba@kernel.org edumazet@google.com pabeni@redhat.com noureddine@arista.com dsahern@kernel.org jamie.bainbridge@gmail.com netfilter-devel@vger.kernel.org pablo@netfilter.org
netdev/build_clang fail Errors and warnings before: 246 this patch: 243
netdev/verify_signedoff success Signed-off-by tag matches author and committer
netdev/deprecated_api success None detected
netdev/check_selftest success No net selftest shell script
netdev/verify_fixes success No Fixes tag
netdev/build_allmodconfig_warn fail Errors and warnings before: 4458 this patch: 4554
netdev/checkpatch success total: 0 errors, 0 warnings, 0 checks, 168 lines checked
netdev/build_clang_rust success No Rust files in patch. Skipping build
netdev/kdoc success Errors and warnings before: 0 this patch: 0
netdev/source_inline success Was 0 now: 0

Commit Message

Christian Hopps Nov. 10, 2023, 11:37 a.m. UTC
From: Christian Hopps <chopps@labn.net>

Define `XFRM_MODE_IPTFS` and `IPSEC_MODE_IPTFS` constants, and add these to
switch case and conditionals adjacent with the existing TUNNEL modes.

Signed-off-by: Christian Hopps <chopps@labn.net>
---
 include/net/xfrm.h         |  1 +
 include/uapi/linux/ipsec.h |  3 ++-
 include/uapi/linux/snmp.h  |  2 ++
 include/uapi/linux/xfrm.h  |  3 ++-
 net/ipv4/esp4.c            |  3 ++-
 net/ipv6/esp6.c            |  3 ++-
 net/netfilter/nft_xfrm.c   |  3 ++-
 net/xfrm/xfrm_device.c     |  1 +
 net/xfrm/xfrm_output.c     |  4 ++++
 net/xfrm/xfrm_policy.c     |  8 ++++++--
 net/xfrm/xfrm_proc.c       |  2 ++
 net/xfrm/xfrm_state.c      | 12 ++++++++++++
 net/xfrm/xfrm_user.c       |  3 +++
 13 files changed, 41 insertions(+), 7 deletions(-)

Comments

Antony Antony Nov. 12, 2023, 7:44 p.m. UTC | #1
On Fri, Nov 10, 2023 at 06:37:18AM -0500, Christian Hopps via Devel wrote:
> From: Christian Hopps <chopps@labn.net>
> 
> Define `XFRM_MODE_IPTFS` and `IPSEC_MODE_IPTFS` constants, and add these to
> switch case and conditionals adjacent with the existing TUNNEL modes.
> 
> Signed-off-by: Christian Hopps <chopps@labn.net>
> ---
>  include/net/xfrm.h         |  1 +
>  include/uapi/linux/ipsec.h |  3 ++-
>  include/uapi/linux/snmp.h  |  2 ++
>  include/uapi/linux/xfrm.h  |  3 ++-
>  net/ipv4/esp4.c            |  3 ++-
>  net/ipv6/esp6.c            |  3 ++-
>  net/netfilter/nft_xfrm.c   |  3 ++-
>  net/xfrm/xfrm_device.c     |  1 +
>  net/xfrm/xfrm_output.c     |  4 ++++
>  net/xfrm/xfrm_policy.c     |  8 ++++++--
>  net/xfrm/xfrm_proc.c       |  2 ++
>  net/xfrm/xfrm_state.c      | 12 ++++++++++++
>  net/xfrm/xfrm_user.c       |  3 +++
>  13 files changed, 41 insertions(+), 7 deletions(-)
> 
> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
> index aeeadadc9545..a6e0e848918d 100644
> --- a/include/net/xfrm.h
> +++ b/include/net/xfrm.h
> @@ -37,6 +37,7 @@
>  #define XFRM_PROTO_COMP		108
>  #define XFRM_PROTO_IPIP		4
>  #define XFRM_PROTO_IPV6		41
> +#define XFRM_PROTO_IPTFS	IPPROTO_AGGFRAG
>  #define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
>  #define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS
>  
> diff --git a/include/uapi/linux/ipsec.h b/include/uapi/linux/ipsec.h
> index 50d8ee1791e2..696b790f4346 100644
> --- a/include/uapi/linux/ipsec.h
> +++ b/include/uapi/linux/ipsec.h
> @@ -14,7 +14,8 @@ enum {
>  	IPSEC_MODE_ANY		= 0,	/* We do not support this for SA */
>  	IPSEC_MODE_TRANSPORT	= 1,
>  	IPSEC_MODE_TUNNEL	= 2,
> -	IPSEC_MODE_BEET         = 3
> +	IPSEC_MODE_BEET         = 3,
> +	IPSEC_MODE_IPTFS        = 4

Consider using 'IPSEC_MODE_IPTFS_TUNNEL' for a more descriptive name? 

I imagine IPSEC_MODE_BEET could support IPTFS, resulting in 'iptfs-beet.' 

In applications like iproute2, using 
'ip xfrm state add ...  mode iptfs-tunnel' might be clearer than 'iptfs' 
alone, especially with possibility of IPTF 'Congestion Control' and  
'Non-Congestion-Controlled'. Would be seperate modes? Or attributes of 
"iptfs" mode?


>  };
>  
>  enum {
> diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
> index 26f33a4c253d..d0b45f4c22c7 100644
> --- a/include/uapi/linux/snmp.h
> +++ b/include/uapi/linux/snmp.h
> @@ -331,6 +331,8 @@ enum
>  	LINUX_MIB_XFRMFWDHDRERROR,		/* XfrmFwdHdrError*/
>  	LINUX_MIB_XFRMOUTSTATEINVALID,		/* XfrmOutStateInvalid */
>  	LINUX_MIB_XFRMACQUIREERROR,		/* XfrmAcquireError */
> +	LINUX_MIB_XFRMINIPTFSERROR,		/* XfrmInIptfsError */
> +	LINUX_MIB_XFRMOUTNOQSPACE,		/* XfrmOutNoQueueSpace */
>  	__LINUX_MIB_XFRMMAX
>  };
>  
> diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
> index fa6d264f2ad1..2e7ffc9b7309 100644
> --- a/include/uapi/linux/xfrm.h
> +++ b/include/uapi/linux/xfrm.h
> @@ -153,7 +153,8 @@ enum {
>  #define XFRM_MODE_ROUTEOPTIMIZATION 2
>  #define XFRM_MODE_IN_TRIGGER 3
>  #define XFRM_MODE_BEET 4
> -#define XFRM_MODE_MAX 5
> +#define XFRM_MODE_IPTFS 5

same here XFRM_MODE_IPTFS_TUNNEL 

I wonder if the patches are in the right order. While XFRM_MODE_IPTFS is 
defined in 7/8 it is already used in 5/8. May be Simon Horman pointed out 
the same.


> +#define XFRM_MODE_MAX 6
>  
>  /* Netlink configuration messages.  */
>  enum {
> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
> index 2be2d4922557..b7047c0dd7ea 100644
> --- a/net/ipv4/esp4.c
> +++ b/net/ipv4/esp4.c
> @@ -816,7 +816,8 @@ int esp_input_done2(struct sk_buff *skb, int err)
>  	}
>  
>  	skb_pull_rcsum(skb, hlen);
> -	if (x->props.mode == XFRM_MODE_TUNNEL)
> +	if (x->props.mode == XFRM_MODE_TUNNEL ||
> +	    x->props.mode == XFRM_MODE_IPTFS)
>  		skb_reset_transport_header(skb);
>  	else
>  		skb_set_transport_header(skb, -ihl);
> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
> index fddd0cbdede1..10f2190207a8 100644
> --- a/net/ipv6/esp6.c
> +++ b/net/ipv6/esp6.c
> @@ -865,7 +865,8 @@ int esp6_input_done2(struct sk_buff *skb, int err)
>  	skb_postpull_rcsum(skb, skb_network_header(skb),
>  			   skb_network_header_len(skb));
>  	skb_pull_rcsum(skb, hlen);
> -	if (x->props.mode == XFRM_MODE_TUNNEL)
> +	if (x->props.mode == XFRM_MODE_TUNNEL ||
> +	    x->props.mode == XFRM_MODE_IPTFS)
>  		skb_reset_transport_header(skb);
>  	else
>  		skb_set_transport_header(skb, -hdr_len);
> diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c
> index 452f8587adda..291b029391cd 100644
> --- a/net/netfilter/nft_xfrm.c
> +++ b/net/netfilter/nft_xfrm.c
> @@ -112,7 +112,8 @@ static bool xfrm_state_addr_ok(enum nft_xfrm_keys k, u8 family, u8 mode)
>  		return true;
>  	}
>  
> -	return mode == XFRM_MODE_BEET || mode == XFRM_MODE_TUNNEL;
> +	return mode == XFRM_MODE_BEET || mode == XFRM_MODE_TUNNEL ||
> +	       mode == XFRM_MODE_IPTFS;
>  }
>  
>  static void nft_xfrm_state_get_key(const struct nft_xfrm *priv,
> diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
> index 8b848540ea47..a40f5e09829e 100644
> --- a/net/xfrm/xfrm_device.c
> +++ b/net/xfrm/xfrm_device.c
> @@ -69,6 +69,7 @@ static void __xfrm_mode_beet_prep(struct xfrm_state *x, struct sk_buff *skb,
>  static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
>  {
>  	switch (x->outer_mode.encap) {
> +	case XFRM_MODE_IPTFS:
>  	case XFRM_MODE_TUNNEL:
>  		if (x->outer_mode.family == AF_INET)
>  			return __xfrm_mode_tunnel_prep(x, skb,
> diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
> index 4390c111410d..16c981ca61ca 100644
> --- a/net/xfrm/xfrm_output.c
> +++ b/net/xfrm/xfrm_output.c
> @@ -680,6 +680,10 @@ static void xfrm_get_inner_ipproto(struct sk_buff *skb, struct xfrm_state *x)
>  
>  		return;
>  	}
> +	if (x->outer_mode.encap == XFRM_MODE_IPTFS) {
> +		xo->inner_ipproto = IPPROTO_AGGFRAG;
> +		return;
> +	}
>  
>  	/* non-Tunnel Mode */
>  	if (!skb->encapsulation)
> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
> index 3220b01121f3..94e5889a77d6 100644
> --- a/net/xfrm/xfrm_policy.c
> +++ b/net/xfrm/xfrm_policy.c
> @@ -2468,6 +2468,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
>  		struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
>  
>  		if (tmpl->mode == XFRM_MODE_TUNNEL ||
> +		    tmpl->mode == XFRM_MODE_IPTFS ||
>  		    tmpl->mode == XFRM_MODE_BEET) {
>  			remote = &tmpl->id.daddr;
>  			local = &tmpl->saddr;
> @@ -3252,7 +3253,8 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
>  ok:
>  	xfrm_pols_put(pols, drop_pols);
>  	if (dst && dst->xfrm &&
> -	    dst->xfrm->props.mode == XFRM_MODE_TUNNEL)
> +	    (dst->xfrm->props.mode == XFRM_MODE_TUNNEL ||
> +	     dst->xfrm->props.mode == XFRM_MODE_IPTFS))
>  		dst->flags |= DST_XFRM_TUNNEL;
>  	return dst;
>  
> @@ -4353,6 +4355,7 @@ static int migrate_tmpl_match(const struct xfrm_migrate *m, const struct xfrm_tm
>  		switch (t->mode) {
>  		case XFRM_MODE_TUNNEL:
>  		case XFRM_MODE_BEET:
> +		case XFRM_MODE_IPTFS:
>  			if (xfrm_addr_equal(&t->id.daddr, &m->old_daddr,
>  					    m->old_family) &&
>  			    xfrm_addr_equal(&t->saddr, &m->old_saddr,
> @@ -4395,7 +4398,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
>  				continue;
>  			n++;
>  			if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
> -			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
> +			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET &&
> +			    pol->xfrm_vec[i].mode != XFRM_MODE_IPTFS)
>  				continue;
>  			/* update endpoints */
>  			memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
> diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
> index fee9b5cf37a7..d92b1b760749 100644
> --- a/net/xfrm/xfrm_proc.c
> +++ b/net/xfrm/xfrm_proc.c
> @@ -41,6 +41,8 @@ static const struct snmp_mib xfrm_mib_list[] = {
>  	SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR),
>  	SNMP_MIB_ITEM("XfrmOutStateInvalid", LINUX_MIB_XFRMOUTSTATEINVALID),
>  	SNMP_MIB_ITEM("XfrmAcquireError", LINUX_MIB_XFRMACQUIREERROR),
> +	SNMP_MIB_ITEM("XfrmInIptfsError", LINUX_MIB_XFRMINIPTFSERROR),
> +	SNMP_MIB_ITEM("XfrmOutNoQueueSpace", LINUX_MIB_XFRMOUTNOQSPACE),
>  	SNMP_MIB_SENTINEL
>  };
>  
> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
> index f5e1a17ebf74..786f3fc0d428 100644
> --- a/net/xfrm/xfrm_state.c
> +++ b/net/xfrm/xfrm_state.c
> @@ -465,6 +465,11 @@ static const struct xfrm_mode xfrm4_mode_map[XFRM_MODE_MAX] = {
>  		.flags = XFRM_MODE_FLAG_TUNNEL,
>  		.family = AF_INET,
>  	},
> +	[XFRM_MODE_IPTFS] = {
> +		.encap = XFRM_MODE_IPTFS,
> +		.flags = XFRM_MODE_FLAG_TUNNEL,
> +		.family = AF_INET,
> +	},
>  };
>  
>  static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = {
> @@ -486,6 +491,11 @@ static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = {
>  		.flags = XFRM_MODE_FLAG_TUNNEL,
>  		.family = AF_INET6,
>  	},
> +	[XFRM_MODE_IPTFS] = {
> +		.encap = XFRM_MODE_IPTFS,
> +		.flags = XFRM_MODE_FLAG_TUNNEL,
> +		.family = AF_INET6,
> +	},
>  };
>  
>  static const struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
> @@ -2083,6 +2093,7 @@ static int __xfrm6_state_sort_cmp(const void *p)
>  #endif
>  	case XFRM_MODE_TUNNEL:
>  	case XFRM_MODE_BEET:
> +	case XFRM_MODE_IPTFS:
>  		return 4;
>  	}
>  	return 5;
> @@ -2109,6 +2120,7 @@ static int __xfrm6_tmpl_sort_cmp(const void *p)
>  #endif
>  	case XFRM_MODE_TUNNEL:
>  	case XFRM_MODE_BEET:
> +	case XFRM_MODE_IPTFS:
>  		return 3;
>  	}
>  	return 4;
> diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
> index 8a504331e369..389656056326 100644
> --- a/net/xfrm/xfrm_user.c
> +++ b/net/xfrm/xfrm_user.c
> @@ -353,6 +353,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
>  	case XFRM_MODE_TUNNEL:
>  	case XFRM_MODE_ROUTEOPTIMIZATION:
>  	case XFRM_MODE_BEET:
> +	case XFRM_MODE_IPTFS:
>  		break;
>  
>  	default:
> @@ -1830,6 +1831,8 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
>  				return -EINVAL;
>  			}
>  			break;
> +		case XFRM_MODE_IPTFS:
> +			break;
>  		default:
>  			if (ut[i].family != prev_family) {
>  				NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
> -- 
> 2.42.0
> 
> -- 
> Devel mailing list
> Devel@linux-ipsec.org
> https://linux-ipsec.org/mailman/listinfo/devel
Christian Hopps Nov. 12, 2023, 9 p.m. UTC | #2
Antony Antony <antony@phenome.org> writes:

> On Fri, Nov 10, 2023 at 06:37:18AM -0500, Christian Hopps via Devel wrote:
>> From: Christian Hopps <chopps@labn.net>
>>
>> Define `XFRM_MODE_IPTFS` and `IPSEC_MODE_IPTFS` constants, and add these to
>> switch case and conditionals adjacent with the existing TUNNEL modes.
>>
>> Signed-off-by: Christian Hopps <chopps@labn.net>
>> ---
>>  include/net/xfrm.h         |  1 +
>>  include/uapi/linux/ipsec.h |  3 ++-
>>  include/uapi/linux/snmp.h  |  2 ++
>>  include/uapi/linux/xfrm.h  |  3 ++-
>>  net/ipv4/esp4.c            |  3 ++-
>>  net/ipv6/esp6.c            |  3 ++-
>>  net/netfilter/nft_xfrm.c   |  3 ++-
>>  net/xfrm/xfrm_device.c     |  1 +
>>  net/xfrm/xfrm_output.c     |  4 ++++
>>  net/xfrm/xfrm_policy.c     |  8 ++++++--
>>  net/xfrm/xfrm_proc.c       |  2 ++
>>  net/xfrm/xfrm_state.c      | 12 ++++++++++++
>>  net/xfrm/xfrm_user.c       |  3 +++
>>  13 files changed, 41 insertions(+), 7 deletions(-)
>>
>> diff --git a/include/net/xfrm.h b/include/net/xfrm.h
>> index aeeadadc9545..a6e0e848918d 100644
>> --- a/include/net/xfrm.h
>> +++ b/include/net/xfrm.h
>> @@ -37,6 +37,7 @@
>>  #define XFRM_PROTO_COMP		108
>>  #define XFRM_PROTO_IPIP		4
>>  #define XFRM_PROTO_IPV6		41
>> +#define XFRM_PROTO_IPTFS	IPPROTO_AGGFRAG
>>  #define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
>>  #define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS
>>
>> diff --git a/include/uapi/linux/ipsec.h b/include/uapi/linux/ipsec.h
>> index 50d8ee1791e2..696b790f4346 100644
>> --- a/include/uapi/linux/ipsec.h
>> +++ b/include/uapi/linux/ipsec.h
>> @@ -14,7 +14,8 @@ enum {
>>  	IPSEC_MODE_ANY		= 0,	/* We do not support this for SA */
>>  	IPSEC_MODE_TRANSPORT	= 1,
>>  	IPSEC_MODE_TUNNEL	= 2,
>> -	IPSEC_MODE_BEET         = 3
>> +	IPSEC_MODE_BEET         = 3,
>> +	IPSEC_MODE_IPTFS        = 4
>
> Consider using 'IPSEC_MODE_IPTFS_TUNNEL' for a more descriptive name?
>
> I imagine IPSEC_MODE_BEET could support IPTFS, resulting in 'iptfs-beet.'

I'd like to ask to hold off on making this change if that's OK. Either someone knows what IPTFS is or they are going to have to look it up. Having _TUNNEL on the main identifier (making it even longer) isn't going to help their comprehension, but will cause more line wrapping in the code which does the opposite.

Also, your example of "iptfs-beet" is what it would be currently, with your suggestion change of adding _TUNNEL wouldn't that then yield "mode iptfs-tunnel-beet"? :)

> In applications like iproute2, using
> 'ip xfrm state add ...  mode iptfs-tunnel' might be clearer than 'iptfs'
> alone, especially with possibility of IPTF 'Congestion Control' and
> 'Non-Congestion-Controlled'. Would be seperate modes? Or attributes of
> "iptfs" mode?

For congestion control I'd just have that as another iptfs-opt, I think.

>
>>  };
>>
>>  enum {
>> diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
>> index 26f33a4c253d..d0b45f4c22c7 100644
>> --- a/include/uapi/linux/snmp.h
>> +++ b/include/uapi/linux/snmp.h
>> @@ -331,6 +331,8 @@ enum
>>  	LINUX_MIB_XFRMFWDHDRERROR,		/* XfrmFwdHdrError*/
>>  	LINUX_MIB_XFRMOUTSTATEINVALID,		/* XfrmOutStateInvalid */
>>  	LINUX_MIB_XFRMACQUIREERROR,		/* XfrmAcquireError */
>> +	LINUX_MIB_XFRMINIPTFSERROR,		/* XfrmInIptfsError */
>> +	LINUX_MIB_XFRMOUTNOQSPACE,		/* XfrmOutNoQueueSpace */
>>  	__LINUX_MIB_XFRMMAX
>>  };
>>
>> diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
>> index fa6d264f2ad1..2e7ffc9b7309 100644
>> --- a/include/uapi/linux/xfrm.h
>> +++ b/include/uapi/linux/xfrm.h
>> @@ -153,7 +153,8 @@ enum {
>>  #define XFRM_MODE_ROUTEOPTIMIZATION 2
>>  #define XFRM_MODE_IN_TRIGGER 3
>>  #define XFRM_MODE_BEET 4
>> -#define XFRM_MODE_MAX 5
>> +#define XFRM_MODE_IPTFS 5
>
> same here XFRM_MODE_IPTFS_TUNNEL
>
> I wonder if the patches are in the right order. While XFRM_MODE_IPTFS is
> defined in 7/8 it is already used in 5/8. May be Simon Horman pointed out
> the same.

Yes I'm currently running builds on all the commits after fixing this.

Thanks,
Chris.

>
>
>> +#define XFRM_MODE_MAX 6
>>
>>  /* Netlink configuration messages.  */
>>  enum {
>> diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
>> index 2be2d4922557..b7047c0dd7ea 100644
>> --- a/net/ipv4/esp4.c
>> +++ b/net/ipv4/esp4.c
>> @@ -816,7 +816,8 @@ int esp_input_done2(struct sk_buff *skb, int err)
>>  	}
>>
>>  	skb_pull_rcsum(skb, hlen);
>> -	if (x->props.mode == XFRM_MODE_TUNNEL)
>> +	if (x->props.mode == XFRM_MODE_TUNNEL ||
>> +	    x->props.mode == XFRM_MODE_IPTFS)
>>  		skb_reset_transport_header(skb);
>>  	else
>>  		skb_set_transport_header(skb, -ihl);
>> diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
>> index fddd0cbdede1..10f2190207a8 100644
>> --- a/net/ipv6/esp6.c
>> +++ b/net/ipv6/esp6.c
>> @@ -865,7 +865,8 @@ int esp6_input_done2(struct sk_buff *skb, int err)
>>  	skb_postpull_rcsum(skb, skb_network_header(skb),
>>  			   skb_network_header_len(skb));
>>  	skb_pull_rcsum(skb, hlen);
>> -	if (x->props.mode == XFRM_MODE_TUNNEL)
>> +	if (x->props.mode == XFRM_MODE_TUNNEL ||
>> +	    x->props.mode == XFRM_MODE_IPTFS)
>>  		skb_reset_transport_header(skb);
>>  	else
>>  		skb_set_transport_header(skb, -hdr_len);
>> diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c
>> index 452f8587adda..291b029391cd 100644
>> --- a/net/netfilter/nft_xfrm.c
>> +++ b/net/netfilter/nft_xfrm.c
>> @@ -112,7 +112,8 @@ static bool xfrm_state_addr_ok(enum nft_xfrm_keys k, u8 family, u8 mode)
>>  		return true;
>>  	}
>>
>> -	return mode == XFRM_MODE_BEET || mode == XFRM_MODE_TUNNEL;
>> +	return mode == XFRM_MODE_BEET || mode == XFRM_MODE_TUNNEL ||
>> +	       mode == XFRM_MODE_IPTFS;
>>  }
>>
>>  static void nft_xfrm_state_get_key(const struct nft_xfrm *priv,
>> diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
>> index 8b848540ea47..a40f5e09829e 100644
>> --- a/net/xfrm/xfrm_device.c
>> +++ b/net/xfrm/xfrm_device.c
>> @@ -69,6 +69,7 @@ static void __xfrm_mode_beet_prep(struct xfrm_state *x, struct sk_buff *skb,
>>  static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
>>  {
>>  	switch (x->outer_mode.encap) {
>> +	case XFRM_MODE_IPTFS:
>>  	case XFRM_MODE_TUNNEL:
>>  		if (x->outer_mode.family == AF_INET)
>>  			return __xfrm_mode_tunnel_prep(x, skb,
>> diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
>> index 4390c111410d..16c981ca61ca 100644
>> --- a/net/xfrm/xfrm_output.c
>> +++ b/net/xfrm/xfrm_output.c
>> @@ -680,6 +680,10 @@ static void xfrm_get_inner_ipproto(struct sk_buff *skb, struct xfrm_state *x)
>>
>>  		return;
>>  	}
>> +	if (x->outer_mode.encap == XFRM_MODE_IPTFS) {
>> +		xo->inner_ipproto = IPPROTO_AGGFRAG;
>> +		return;
>> +	}
>>
>>  	/* non-Tunnel Mode */
>>  	if (!skb->encapsulation)
>> diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
>> index 3220b01121f3..94e5889a77d6 100644
>> --- a/net/xfrm/xfrm_policy.c
>> +++ b/net/xfrm/xfrm_policy.c
>> @@ -2468,6 +2468,7 @@ xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
>>  		struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
>>
>>  		if (tmpl->mode == XFRM_MODE_TUNNEL ||
>> +		    tmpl->mode == XFRM_MODE_IPTFS ||
>>  		    tmpl->mode == XFRM_MODE_BEET) {
>>  			remote = &tmpl->id.daddr;
>>  			local = &tmpl->saddr;
>> @@ -3252,7 +3253,8 @@ struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
>>  ok:
>>  	xfrm_pols_put(pols, drop_pols);
>>  	if (dst && dst->xfrm &&
>> -	    dst->xfrm->props.mode == XFRM_MODE_TUNNEL)
>> +	    (dst->xfrm->props.mode == XFRM_MODE_TUNNEL ||
>> +	     dst->xfrm->props.mode == XFRM_MODE_IPTFS))
>>  		dst->flags |= DST_XFRM_TUNNEL;
>>  	return dst;
>>
>> @@ -4353,6 +4355,7 @@ static int migrate_tmpl_match(const struct xfrm_migrate *m, const struct xfrm_tm
>>  		switch (t->mode) {
>>  		case XFRM_MODE_TUNNEL:
>>  		case XFRM_MODE_BEET:
>> +		case XFRM_MODE_IPTFS:
>>  			if (xfrm_addr_equal(&t->id.daddr, &m->old_daddr,
>>  					    m->old_family) &&
>>  			    xfrm_addr_equal(&t->saddr, &m->old_saddr,
>> @@ -4395,7 +4398,8 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
>>  				continue;
>>  			n++;
>>  			if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
>> -			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
>> +			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET &&
>> +			    pol->xfrm_vec[i].mode != XFRM_MODE_IPTFS)
>>  				continue;
>>  			/* update endpoints */
>>  			memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
>> diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
>> index fee9b5cf37a7..d92b1b760749 100644
>> --- a/net/xfrm/xfrm_proc.c
>> +++ b/net/xfrm/xfrm_proc.c
>> @@ -41,6 +41,8 @@ static const struct snmp_mib xfrm_mib_list[] = {
>>  	SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR),
>>  	SNMP_MIB_ITEM("XfrmOutStateInvalid", LINUX_MIB_XFRMOUTSTATEINVALID),
>>  	SNMP_MIB_ITEM("XfrmAcquireError", LINUX_MIB_XFRMACQUIREERROR),
>> +	SNMP_MIB_ITEM("XfrmInIptfsError", LINUX_MIB_XFRMINIPTFSERROR),
>> +	SNMP_MIB_ITEM("XfrmOutNoQueueSpace", LINUX_MIB_XFRMOUTNOQSPACE),
>>  	SNMP_MIB_SENTINEL
>>  };
>>
>> diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
>> index f5e1a17ebf74..786f3fc0d428 100644
>> --- a/net/xfrm/xfrm_state.c
>> +++ b/net/xfrm/xfrm_state.c
>> @@ -465,6 +465,11 @@ static const struct xfrm_mode xfrm4_mode_map[XFRM_MODE_MAX] = {
>>  		.flags = XFRM_MODE_FLAG_TUNNEL,
>>  		.family = AF_INET,
>>  	},
>> +	[XFRM_MODE_IPTFS] = {
>> +		.encap = XFRM_MODE_IPTFS,
>> +		.flags = XFRM_MODE_FLAG_TUNNEL,
>> +		.family = AF_INET,
>> +	},
>>  };
>>
>>  static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = {
>> @@ -486,6 +491,11 @@ static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = {
>>  		.flags = XFRM_MODE_FLAG_TUNNEL,
>>  		.family = AF_INET6,
>>  	},
>> +	[XFRM_MODE_IPTFS] = {
>> +		.encap = XFRM_MODE_IPTFS,
>> +		.flags = XFRM_MODE_FLAG_TUNNEL,
>> +		.family = AF_INET6,
>> +	},
>>  };
>>
>>  static const struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
>> @@ -2083,6 +2093,7 @@ static int __xfrm6_state_sort_cmp(const void *p)
>>  #endif
>>  	case XFRM_MODE_TUNNEL:
>>  	case XFRM_MODE_BEET:
>> +	case XFRM_MODE_IPTFS:
>>  		return 4;
>>  	}
>>  	return 5;
>> @@ -2109,6 +2120,7 @@ static int __xfrm6_tmpl_sort_cmp(const void *p)
>>  #endif
>>  	case XFRM_MODE_TUNNEL:
>>  	case XFRM_MODE_BEET:
>> +	case XFRM_MODE_IPTFS:
>>  		return 3;
>>  	}
>>  	return 4;
>> diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
>> index 8a504331e369..389656056326 100644
>> --- a/net/xfrm/xfrm_user.c
>> +++ b/net/xfrm/xfrm_user.c
>> @@ -353,6 +353,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
>>  	case XFRM_MODE_TUNNEL:
>>  	case XFRM_MODE_ROUTEOPTIMIZATION:
>>  	case XFRM_MODE_BEET:
>> +	case XFRM_MODE_IPTFS:
>>  		break;
>>
>>  	default:
>> @@ -1830,6 +1831,8 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
>>  				return -EINVAL;
>>  			}
>>  			break;
>> +		case XFRM_MODE_IPTFS:
>> +			break;
>>  		default:
>>  			if (ut[i].family != prev_family) {
>>  				NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
>> --
>> 2.42.0
>>
>> --
>> Devel mailing list
>> Devel@linux-ipsec.org
>> https://linux-ipsec.org/mailman/listinfo/devel
diff mbox series

Patch

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index aeeadadc9545..a6e0e848918d 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -37,6 +37,7 @@ 
 #define XFRM_PROTO_COMP		108
 #define XFRM_PROTO_IPIP		4
 #define XFRM_PROTO_IPV6		41
+#define XFRM_PROTO_IPTFS	IPPROTO_AGGFRAG
 #define XFRM_PROTO_ROUTING	IPPROTO_ROUTING
 #define XFRM_PROTO_DSTOPTS	IPPROTO_DSTOPTS
 
diff --git a/include/uapi/linux/ipsec.h b/include/uapi/linux/ipsec.h
index 50d8ee1791e2..696b790f4346 100644
--- a/include/uapi/linux/ipsec.h
+++ b/include/uapi/linux/ipsec.h
@@ -14,7 +14,8 @@  enum {
 	IPSEC_MODE_ANY		= 0,	/* We do not support this for SA */
 	IPSEC_MODE_TRANSPORT	= 1,
 	IPSEC_MODE_TUNNEL	= 2,
-	IPSEC_MODE_BEET         = 3
+	IPSEC_MODE_BEET         = 3,
+	IPSEC_MODE_IPTFS        = 4
 };
 
 enum {
diff --git a/include/uapi/linux/snmp.h b/include/uapi/linux/snmp.h
index 26f33a4c253d..d0b45f4c22c7 100644
--- a/include/uapi/linux/snmp.h
+++ b/include/uapi/linux/snmp.h
@@ -331,6 +331,8 @@  enum
 	LINUX_MIB_XFRMFWDHDRERROR,		/* XfrmFwdHdrError*/
 	LINUX_MIB_XFRMOUTSTATEINVALID,		/* XfrmOutStateInvalid */
 	LINUX_MIB_XFRMACQUIREERROR,		/* XfrmAcquireError */
+	LINUX_MIB_XFRMINIPTFSERROR,		/* XfrmInIptfsError */
+	LINUX_MIB_XFRMOUTNOQSPACE,		/* XfrmOutNoQueueSpace */
 	__LINUX_MIB_XFRMMAX
 };
 
diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h
index fa6d264f2ad1..2e7ffc9b7309 100644
--- a/include/uapi/linux/xfrm.h
+++ b/include/uapi/linux/xfrm.h
@@ -153,7 +153,8 @@  enum {
 #define XFRM_MODE_ROUTEOPTIMIZATION 2
 #define XFRM_MODE_IN_TRIGGER 3
 #define XFRM_MODE_BEET 4
-#define XFRM_MODE_MAX 5
+#define XFRM_MODE_IPTFS 5
+#define XFRM_MODE_MAX 6
 
 /* Netlink configuration messages.  */
 enum {
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 2be2d4922557..b7047c0dd7ea 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -816,7 +816,8 @@  int esp_input_done2(struct sk_buff *skb, int err)
 	}
 
 	skb_pull_rcsum(skb, hlen);
-	if (x->props.mode == XFRM_MODE_TUNNEL)
+	if (x->props.mode == XFRM_MODE_TUNNEL ||
+	    x->props.mode == XFRM_MODE_IPTFS)
 		skb_reset_transport_header(skb);
 	else
 		skb_set_transport_header(skb, -ihl);
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index fddd0cbdede1..10f2190207a8 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -865,7 +865,8 @@  int esp6_input_done2(struct sk_buff *skb, int err)
 	skb_postpull_rcsum(skb, skb_network_header(skb),
 			   skb_network_header_len(skb));
 	skb_pull_rcsum(skb, hlen);
-	if (x->props.mode == XFRM_MODE_TUNNEL)
+	if (x->props.mode == XFRM_MODE_TUNNEL ||
+	    x->props.mode == XFRM_MODE_IPTFS)
 		skb_reset_transport_header(skb);
 	else
 		skb_set_transport_header(skb, -hdr_len);
diff --git a/net/netfilter/nft_xfrm.c b/net/netfilter/nft_xfrm.c
index 452f8587adda..291b029391cd 100644
--- a/net/netfilter/nft_xfrm.c
+++ b/net/netfilter/nft_xfrm.c
@@ -112,7 +112,8 @@  static bool xfrm_state_addr_ok(enum nft_xfrm_keys k, u8 family, u8 mode)
 		return true;
 	}
 
-	return mode == XFRM_MODE_BEET || mode == XFRM_MODE_TUNNEL;
+	return mode == XFRM_MODE_BEET || mode == XFRM_MODE_TUNNEL ||
+	       mode == XFRM_MODE_IPTFS;
 }
 
 static void nft_xfrm_state_get_key(const struct nft_xfrm *priv,
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 8b848540ea47..a40f5e09829e 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -69,6 +69,7 @@  static void __xfrm_mode_beet_prep(struct xfrm_state *x, struct sk_buff *skb,
 static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb)
 {
 	switch (x->outer_mode.encap) {
+	case XFRM_MODE_IPTFS:
 	case XFRM_MODE_TUNNEL:
 		if (x->outer_mode.family == AF_INET)
 			return __xfrm_mode_tunnel_prep(x, skb,
diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c
index 4390c111410d..16c981ca61ca 100644
--- a/net/xfrm/xfrm_output.c
+++ b/net/xfrm/xfrm_output.c
@@ -680,6 +680,10 @@  static void xfrm_get_inner_ipproto(struct sk_buff *skb, struct xfrm_state *x)
 
 		return;
 	}
+	if (x->outer_mode.encap == XFRM_MODE_IPTFS) {
+		xo->inner_ipproto = IPPROTO_AGGFRAG;
+		return;
+	}
 
 	/* non-Tunnel Mode */
 	if (!skb->encapsulation)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 3220b01121f3..94e5889a77d6 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -2468,6 +2468,7 @@  xfrm_tmpl_resolve_one(struct xfrm_policy *policy, const struct flowi *fl,
 		struct xfrm_tmpl *tmpl = &policy->xfrm_vec[i];
 
 		if (tmpl->mode == XFRM_MODE_TUNNEL ||
+		    tmpl->mode == XFRM_MODE_IPTFS ||
 		    tmpl->mode == XFRM_MODE_BEET) {
 			remote = &tmpl->id.daddr;
 			local = &tmpl->saddr;
@@ -3252,7 +3253,8 @@  struct dst_entry *xfrm_lookup_with_ifid(struct net *net,
 ok:
 	xfrm_pols_put(pols, drop_pols);
 	if (dst && dst->xfrm &&
-	    dst->xfrm->props.mode == XFRM_MODE_TUNNEL)
+	    (dst->xfrm->props.mode == XFRM_MODE_TUNNEL ||
+	     dst->xfrm->props.mode == XFRM_MODE_IPTFS))
 		dst->flags |= DST_XFRM_TUNNEL;
 	return dst;
 
@@ -4353,6 +4355,7 @@  static int migrate_tmpl_match(const struct xfrm_migrate *m, const struct xfrm_tm
 		switch (t->mode) {
 		case XFRM_MODE_TUNNEL:
 		case XFRM_MODE_BEET:
+		case XFRM_MODE_IPTFS:
 			if (xfrm_addr_equal(&t->id.daddr, &m->old_daddr,
 					    m->old_family) &&
 			    xfrm_addr_equal(&t->saddr, &m->old_saddr,
@@ -4395,7 +4398,8 @@  static int xfrm_policy_migrate(struct xfrm_policy *pol,
 				continue;
 			n++;
 			if (pol->xfrm_vec[i].mode != XFRM_MODE_TUNNEL &&
-			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET)
+			    pol->xfrm_vec[i].mode != XFRM_MODE_BEET &&
+			    pol->xfrm_vec[i].mode != XFRM_MODE_IPTFS)
 				continue;
 			/* update endpoints */
 			memcpy(&pol->xfrm_vec[i].id.daddr, &mp->new_daddr,
diff --git a/net/xfrm/xfrm_proc.c b/net/xfrm/xfrm_proc.c
index fee9b5cf37a7..d92b1b760749 100644
--- a/net/xfrm/xfrm_proc.c
+++ b/net/xfrm/xfrm_proc.c
@@ -41,6 +41,8 @@  static const struct snmp_mib xfrm_mib_list[] = {
 	SNMP_MIB_ITEM("XfrmFwdHdrError", LINUX_MIB_XFRMFWDHDRERROR),
 	SNMP_MIB_ITEM("XfrmOutStateInvalid", LINUX_MIB_XFRMOUTSTATEINVALID),
 	SNMP_MIB_ITEM("XfrmAcquireError", LINUX_MIB_XFRMACQUIREERROR),
+	SNMP_MIB_ITEM("XfrmInIptfsError", LINUX_MIB_XFRMINIPTFSERROR),
+	SNMP_MIB_ITEM("XfrmOutNoQueueSpace", LINUX_MIB_XFRMOUTNOQSPACE),
 	SNMP_MIB_SENTINEL
 };
 
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index f5e1a17ebf74..786f3fc0d428 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -465,6 +465,11 @@  static const struct xfrm_mode xfrm4_mode_map[XFRM_MODE_MAX] = {
 		.flags = XFRM_MODE_FLAG_TUNNEL,
 		.family = AF_INET,
 	},
+	[XFRM_MODE_IPTFS] = {
+		.encap = XFRM_MODE_IPTFS,
+		.flags = XFRM_MODE_FLAG_TUNNEL,
+		.family = AF_INET,
+	},
 };
 
 static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = {
@@ -486,6 +491,11 @@  static const struct xfrm_mode xfrm6_mode_map[XFRM_MODE_MAX] = {
 		.flags = XFRM_MODE_FLAG_TUNNEL,
 		.family = AF_INET6,
 	},
+	[XFRM_MODE_IPTFS] = {
+		.encap = XFRM_MODE_IPTFS,
+		.flags = XFRM_MODE_FLAG_TUNNEL,
+		.family = AF_INET6,
+	},
 };
 
 static const struct xfrm_mode *xfrm_get_mode(unsigned int encap, int family)
@@ -2083,6 +2093,7 @@  static int __xfrm6_state_sort_cmp(const void *p)
 #endif
 	case XFRM_MODE_TUNNEL:
 	case XFRM_MODE_BEET:
+	case XFRM_MODE_IPTFS:
 		return 4;
 	}
 	return 5;
@@ -2109,6 +2120,7 @@  static int __xfrm6_tmpl_sort_cmp(const void *p)
 #endif
 	case XFRM_MODE_TUNNEL:
 	case XFRM_MODE_BEET:
+	case XFRM_MODE_IPTFS:
 		return 3;
 	}
 	return 4;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 8a504331e369..389656056326 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -353,6 +353,7 @@  static int verify_newsa_info(struct xfrm_usersa_info *p,
 	case XFRM_MODE_TUNNEL:
 	case XFRM_MODE_ROUTEOPTIMIZATION:
 	case XFRM_MODE_BEET:
+	case XFRM_MODE_IPTFS:
 		break;
 
 	default:
@@ -1830,6 +1831,8 @@  static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
 				return -EINVAL;
 			}
 			break;
+		case XFRM_MODE_IPTFS:
+			break;
 		default:
 			if (ut[i].family != prev_family) {
 				NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");