]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
xfrm: add generic iptfs defines and functionality
authorChristian Hopps <chopps@labn.net>
Thu, 14 Nov 2024 07:07:02 +0000 (02:07 -0500)
committerSteffen Klassert <steffen.klassert@secunet.com>
Thu, 5 Dec 2024 09:01:28 +0000 (10:01 +0100)
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>
Tested-by: Antony Antony <antony.antony@secunet.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
12 files changed:
include/net/xfrm.h
include/uapi/linux/ipsec.h
include/uapi/linux/snmp.h
net/ipv4/esp4.c
net/ipv6/esp6.c
net/netfilter/nft_xfrm.c
net/xfrm/xfrm_device.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_policy.c
net/xfrm/xfrm_proc.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c

index 1ebc09cde6278e999bec0c4b99abe43d1922f007..4b0677e481900a84c12171f94cbf8242583b37f6 100644 (file)
@@ -38,6 +38,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
 
index 50d8ee1791e2a69a72ad90738debe593fd85238f..696b790f43462048958757d5b1d22e91508162e3 100644 (file)
@@ -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 {
index adf5fd78dd50301889a08ffedc1a59000970174b..5a2553511190aab6a2d22297cf7514ae24657dd8 100644 (file)
@@ -339,6 +339,8 @@ enum
        LINUX_MIB_XFRMACQUIREERROR,             /* XfrmAcquireError */
        LINUX_MIB_XFRMOUTSTATEDIRERROR,         /* XfrmOutStateDirError */
        LINUX_MIB_XFRMINSTATEDIRERROR,          /* XfrmInStateDirError */
+       LINUX_MIB_XFRMINIPTFSERROR,             /* XfrmInIptfsError */
+       LINUX_MIB_XFRMOUTNOQSPACE,              /* XfrmOutNoQueueSpace */
        __LINUX_MIB_XFRMMAX
 };
 
index f3281312eb5eba53110e8276184703eab6bc81e8..b0fbf804bbbae09de83aaab4a1ae34712c502472 100644 (file)
@@ -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);
index b2400c226a32582641407e7ed7beecb681d05a9e..5f3d0cc1555a94f5b5c5f3413818b80ba479951e 100644 (file)
@@ -859,7 +859,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);
index 8a07b46cc8fb73d51c50b0fb7b18e42915af63b7..3210cfc966ab24d97d177301fd96d3a7ee730953 100644 (file)
@@ -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,
index 1fe1b07d879d275967a3ccae0c081e4abb6befb5..d1fa94e52ceae4bf24b792fec4ad10b30c4420b6 100644 (file)
@@ -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,
index ef81359e403830a5e18991bc031193292cf7a395..b5025cf6136e9954153ecb27f6c7d06e7133b996 100644 (file)
@@ -677,6 +677,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)
index c04014ee623fbe17723d08263bf681c0186cea89..9e510021ee91ab05d2e49958dcd21aee516be44f 100644 (file)
@@ -2497,6 +2497,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;
@@ -3294,7 +3295,8 @@ no_transform:
 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;
 
@@ -4523,6 +4525,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,
@@ -4565,7 +4568,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,
index eeb984be03a7968d0fb08def9ee06a8c62606d9c..8e07dd614b0bbe6ed4679f53b85c04e2aa53453f 100644 (file)
@@ -43,6 +43,8 @@ static const struct snmp_mib xfrm_mib_list[] = {
        SNMP_MIB_ITEM("XfrmAcquireError", LINUX_MIB_XFRMACQUIREERROR),
        SNMP_MIB_ITEM("XfrmOutStateDirError", LINUX_MIB_XFRMOUTSTATEDIRERROR),
        SNMP_MIB_ITEM("XfrmInStateDirError", LINUX_MIB_XFRMINSTATEDIRERROR),
+       SNMP_MIB_ITEM("XfrmInIptfsError", LINUX_MIB_XFRMINIPTFSERROR),
+       SNMP_MIB_ITEM("XfrmOutNoQueueSpace", LINUX_MIB_XFRMOUTNOQSPACE),
        SNMP_MIB_SENTINEL
 };
 
index cf68ba891729f5fb23121666fb4d1e8f741fb5f6..34067cb8a4795262053ec7e7386de4447663607f 100644 (file)
@@ -467,6 +467,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] = {
@@ -488,6 +493,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)
@@ -2334,6 +2344,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;
@@ -2360,6 +2371,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;
index 71b452fff8dbd4f50c462dd4bf0b85e2f1770214..08c6d6f0179fbf4753b7d2ee39bd45228baa9b55 100644 (file)
@@ -383,6 +383,16 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
        case XFRM_MODE_ROUTEOPTIMIZATION:
        case XFRM_MODE_BEET:
                break;
+       case XFRM_MODE_IPTFS:
+               if (p->id.proto != IPPROTO_ESP) {
+                       NL_SET_ERR_MSG(extack, "IP-TFS mode only supported with ESP");
+                       goto out;
+               }
+               if (sa_dir == 0) {
+                       NL_SET_ERR_MSG(extack, "IP-TFS mode requires in or out direction attribute");
+                       goto out;
+               }
+               break;
 
        default:
                NL_SET_ERR_MSG(extack, "Unsupported mode");
@@ -2014,6 +2024,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");