Skip to content

Commit

Permalink
xfrm: add extack to xfrm_do_migrate
Browse files Browse the repository at this point in the history
Signed-off-by: Sabrina Dubroca <[email protected]>
Signed-off-by: Steffen Klassert <[email protected]>
  • Loading branch information
qsn authored and klassert committed Nov 25, 2022
1 parent 643bc1a commit bd12240
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 15 deletions.
3 changes: 2 additions & 1 deletion include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1703,7 +1703,8 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_migrate *m, int num_bundles,
struct xfrm_kmaddress *k, struct net *net,
struct xfrm_encap_tmpl *encap, u32 if_id);
struct xfrm_encap_tmpl *encap, u32 if_id,
struct netlink_ext_ack *extack);
#endif

int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);
Expand Down
2 changes: 1 addition & 1 deletion net/key/af_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -2626,7 +2626,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
}

return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
kma ? &k : NULL, net, NULL, 0);
kma ? &k : NULL, net, NULL, 0, NULL);

out:
return err;
Expand Down
28 changes: 20 additions & 8 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -4333,14 +4333,16 @@ static int migrate_tmpl_match(const struct xfrm_migrate *m, const struct xfrm_tm

/* update endpoint address(es) of template(s) */
static int xfrm_policy_migrate(struct xfrm_policy *pol,
struct xfrm_migrate *m, int num_migrate)
struct xfrm_migrate *m, int num_migrate,
struct netlink_ext_ack *extack)
{
struct xfrm_migrate *mp;
int i, j, n = 0;

write_lock_bh(&pol->lock);
if (unlikely(pol->walk.dead)) {
/* target policy has been deleted */
NL_SET_ERR_MSG(extack, "Target policy not found");
write_unlock_bh(&pol->lock);
return -ENOENT;
}
Expand Down Expand Up @@ -4372,17 +4374,22 @@ static int xfrm_policy_migrate(struct xfrm_policy *pol,
return 0;
}

static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate,
struct netlink_ext_ack *extack)
{
int i, j;

if (num_migrate < 1 || num_migrate > XFRM_MAX_DEPTH)
if (num_migrate < 1 || num_migrate > XFRM_MAX_DEPTH) {
NL_SET_ERR_MSG(extack, "Invalid number of SAs to migrate, must be 0 < num <= XFRM_MAX_DEPTH (6)");
return -EINVAL;
}

for (i = 0; i < num_migrate; i++) {
if (xfrm_addr_any(&m[i].new_daddr, m[i].new_family) ||
xfrm_addr_any(&m[i].new_saddr, m[i].new_family))
xfrm_addr_any(&m[i].new_saddr, m[i].new_family)) {
NL_SET_ERR_MSG(extack, "Addresses in the MIGRATE attribute's list cannot be null");
return -EINVAL;
}

/* check if there is any duplicated entry */
for (j = i + 1; j < num_migrate; j++) {
Expand All @@ -4393,8 +4400,10 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
m[i].proto == m[j].proto &&
m[i].mode == m[j].mode &&
m[i].reqid == m[j].reqid &&
m[i].old_family == m[j].old_family)
m[i].old_family == m[j].old_family) {
NL_SET_ERR_MSG(extack, "Entries in the MIGRATE attribute's list must be unique");
return -EINVAL;
}
}
}

Expand All @@ -4404,7 +4413,8 @@ static int xfrm_migrate_check(const struct xfrm_migrate *m, int num_migrate)
int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_migrate *m, int num_migrate,
struct xfrm_kmaddress *k, struct net *net,
struct xfrm_encap_tmpl *encap, u32 if_id)
struct xfrm_encap_tmpl *encap, u32 if_id,
struct netlink_ext_ack *extack)
{
int i, err, nx_cur = 0, nx_new = 0;
struct xfrm_policy *pol = NULL;
Expand All @@ -4414,18 +4424,20 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_migrate *mp;

/* Stage 0 - sanity checks */
err = xfrm_migrate_check(m, num_migrate);
err = xfrm_migrate_check(m, num_migrate, extack);
if (err < 0)
goto out;

if (dir >= XFRM_POLICY_MAX) {
NL_SET_ERR_MSG(extack, "Invalid policy direction");
err = -EINVAL;
goto out;
}

/* Stage 1 - find policy */
pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id);
if (!pol) {
NL_SET_ERR_MSG(extack, "Target policy not found");
err = -ENOENT;
goto out;
}
Expand All @@ -4447,7 +4459,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
}

/* Stage 3 - update policy */
err = xfrm_policy_migrate(pol, m, num_migrate);
err = xfrm_policy_migrate(pol, m, num_migrate, extack);
if (err < 0)
goto restore_state;

Expand Down
16 changes: 11 additions & 5 deletions net/xfrm/xfrm_user.c
Original file line number Diff line number Diff line change
Expand Up @@ -2687,7 +2687,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
#ifdef CONFIG_XFRM_MIGRATE
static int copy_from_user_migrate(struct xfrm_migrate *ma,
struct xfrm_kmaddress *k,
struct nlattr **attrs, int *num)
struct nlattr **attrs, int *num,
struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_MIGRATE];
struct xfrm_user_migrate *um;
Expand All @@ -2706,8 +2707,10 @@ static int copy_from_user_migrate(struct xfrm_migrate *ma,
um = nla_data(rt);
num_migrate = nla_len(rt) / sizeof(*um);

if (num_migrate <= 0 || num_migrate > XFRM_MAX_DEPTH)
if (num_migrate <= 0 || num_migrate > XFRM_MAX_DEPTH) {
NL_SET_ERR_MSG(extack, "Invalid number of SAs to migrate, must be 0 < num <= XFRM_MAX_DEPTH (6)");
return -EINVAL;
}

for (i = 0; i < num_migrate; i++, um++, ma++) {
memcpy(&ma->old_daddr, &um->old_daddr, sizeof(ma->old_daddr));
Expand Down Expand Up @@ -2740,16 +2743,18 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_encap_tmpl *encap = NULL;
u32 if_id = 0;

if (!attrs[XFRMA_MIGRATE])
if (!attrs[XFRMA_MIGRATE]) {
NL_SET_ERR_MSG(extack, "Missing required MIGRATE attribute");
return -EINVAL;
}

kmp = attrs[XFRMA_KMADDRESS] ? &km : NULL;

err = copy_from_user_policy_type(&type, attrs, extack);
if (err)
return err;

err = copy_from_user_migrate(m, kmp, attrs, &n);
err = copy_from_user_migrate(m, kmp, attrs, &n, extack);
if (err)
return err;

Expand All @@ -2766,7 +2771,8 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
if (attrs[XFRMA_IF_ID])
if_id = nla_get_u32(attrs[XFRMA_IF_ID]);

err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap, if_id);
err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap,
if_id, extack);

kfree(encap);

Expand Down

0 comments on commit bd12240

Please sign in to comment.