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 |
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
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 --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");