xfrm: split xfrm_state_migrate into create and install functions

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>
This commit is contained in:
Antony Antony 2026-05-26 21:07:30 +02:00 committed by Steffen Klassert
parent e2e92714d0
commit 8de53883a4
2 changed files with 65 additions and 21 deletions

View 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,

View 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,25 +2145,58 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
if (xuo && xfrm_dev_state_add(net, xc, xuo, extack))
goto error;
/* add state */
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 */
xfrm_state_insert(xc);
} else {
if (xfrm_state_add(xc) < 0)
goto error_add;
}
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_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)) {
/*
* 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) {
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;
}
EXPORT_SYMBOL(xfrm_state_migrate);
#endif