]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
xfrm: split xfrm_state_migrate into create and install functions
authorAntony Antony <antony.antony@secunet.com>
Tue, 26 May 2026 19:07:30 +0000 (21:07 +0200)
committerSteffen Klassert <steffen.klassert@secunet.com>
Thu, 4 Jun 2026 10:22:39 +0000 (12:22 +0200)
To prepare for subsequent patches, split
xfrm_state_migrate() into two functions:
- xfrm_state_migrate_create(): creates the migrated state
- xfrm_state_migrate_install(): installs it into the state table

splitting will help to avoid SN/IV reuse when migrating AEAD SA.

And add const whenever possible.
No functional change.

Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Antony Antony <antony.antony@secunet.com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
include/net/xfrm.h
net/xfrm/xfrm_state.c

index 368b1dc22e5cc376cbe96a7f6fb8cddc2e1cec87..4137986f15e241bf0bda2003be1da8deb5a58f0c 100644 (file)
@@ -1895,6 +1895,17 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
               const struct xfrm_encap_tmpl *encap);
 struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *net,
                                                u32 if_id);
+struct xfrm_state *xfrm_state_migrate_create(struct xfrm_state *x,
+                                            const struct xfrm_migrate *m,
+                                            const struct xfrm_encap_tmpl *encap,
+                                            struct net *net,
+                                            struct xfrm_user_offload *xuo,
+                                            struct netlink_ext_ack *extack);
+int xfrm_state_migrate_install(const struct xfrm_state *x,
+                              struct xfrm_state *xc,
+                              const struct xfrm_migrate *m,
+                              struct xfrm_user_offload *xuo,
+                              struct netlink_ext_ack *extack);
 struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
                                      struct xfrm_migrate *m,
                                      struct xfrm_encap_tmpl *encap,
index 5424f2becbafbc6ed4a5e4fa2a2ab5ed9e3b404d..85fd80520184f46dcc9a7bf350be467b0b083134 100644 (file)
@@ -1966,8 +1966,8 @@ static inline int clone_security(struct xfrm_state *x, struct xfrm_sec_ctx *secu
 }
 
 static struct xfrm_state *xfrm_state_clone_and_setup(struct xfrm_state *orig,
-                                          struct xfrm_encap_tmpl *encap,
-                                          struct xfrm_migrate *m)
+                                          const struct xfrm_encap_tmpl *encap,
+                                          const struct xfrm_migrate *m)
 {
        struct net *net = xs_net(orig);
        struct xfrm_state *x = xfrm_state_alloc(net);
@@ -2125,12 +2125,12 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
 }
 EXPORT_SYMBOL(xfrm_migrate_state_find);
 
-struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
-                                     struct xfrm_migrate *m,
-                                     struct xfrm_encap_tmpl *encap,
-                                     struct net *net,
-                                     struct xfrm_user_offload *xuo,
-                                     struct netlink_ext_ack *extack)
+struct xfrm_state *xfrm_state_migrate_create(struct xfrm_state *x,
+                                            const struct xfrm_migrate *m,
+                                            const struct xfrm_encap_tmpl *encap,
+                                            struct net *net,
+                                            struct xfrm_user_offload *xuo,
+                                            struct netlink_ext_ack *extack)
 {
        struct xfrm_state *xc;
 
@@ -2145,24 +2145,57 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
        if (xuo && xfrm_dev_state_add(net, xc, xuo, extack))
                goto error;
 
-       /* add state */
+       return xc;
+error:
+       xc->km.state = XFRM_STATE_DEAD;
+       xfrm_state_put(xc);
+       return NULL;
+}
+EXPORT_SYMBOL(xfrm_state_migrate_create);
+
+int xfrm_state_migrate_install(const struct xfrm_state *x,
+                              struct xfrm_state *xc,
+                              const struct xfrm_migrate *m,
+                              struct xfrm_user_offload *xuo,
+                              struct netlink_ext_ack *extack)
+{
        if (xfrm_addr_equal(&x->id.daddr, &m->new_daddr, m->new_family)) {
-               /* a care is needed when the destination address of the
-                  state is to be updated as it is a part of triplet */
+               /*
+                * Care is needed when the destination address
+                * of the state is to be updated as it is a part of triplet.
+                */
                xfrm_state_insert(xc);
        } else {
-               if (xfrm_state_add(xc) < 0)
-                       goto error_add;
+               if (xfrm_state_add(xc) < 0) {
+                       if (xuo)
+                               xfrm_dev_state_delete(xc);
+                       xc->km.state = XFRM_STATE_DEAD;
+                       xfrm_state_put(xc);
+                       return -EEXIST;
+               }
        }
 
+       return 0;
+}
+EXPORT_SYMBOL(xfrm_state_migrate_install);
+
+struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
+                                     struct xfrm_migrate *m,
+                                     struct xfrm_encap_tmpl *encap,
+                                     struct net *net,
+                                     struct xfrm_user_offload *xuo,
+                                     struct netlink_ext_ack *extack)
+{
+       struct xfrm_state *xc;
+
+       xc = xfrm_state_migrate_create(x, m, encap, net, xuo, extack);
+       if (!xc)
+               return NULL;
+
+       if (xfrm_state_migrate_install(x, xc, m, xuo, extack) < 0)
+               return NULL;
+
        return xc;
-error_add:
-       if (xuo)
-               xfrm_dev_state_delete(xc);
-error:
-       xc->km.state = XFRM_STATE_DEAD;
-       xfrm_state_put(xc);
-       return NULL;
 }
 EXPORT_SYMBOL(xfrm_state_migrate);
 #endif