Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/klassert/ipsec-next

Steffen Klassert says:

====================
ipsec-next 2022-11-26

1) Remove redundant variable in esp6.
   From Colin Ian King.

2) Update x->lastused for every packet. It was used only for
   outgoing mobile IPv6 packets, but showed to be usefull
   to check if the a SA is still in use in general.
   From Antony Antony.

3) Remove unused variable in xfrm_byidx_resize.
   From Leon Romanovsky.

4) Finalize extack support for xfrm.
   From Sabrina Dubroca.

* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next:
  xfrm: add extack to xfrm_set_spdinfo
  xfrm: add extack to xfrm_alloc_userspi
  xfrm: add extack to xfrm_do_migrate
  xfrm: add extack to xfrm_new_ae and xfrm_replay_verify_len
  xfrm: add extack to xfrm_del_sa
  xfrm: add extack to xfrm_add_sa_expire
  xfrm: a few coding style clean ups
  xfrm: Remove not-used total variable
  xfrm: update x->lastused for every packet
  esp6: remove redundant variable err
====================

Link: https://lore.kernel.org/r/20221126110303.1859238-1-steffen.klassert@secunet.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Nov 30, 2022
2 parents b2d7b6e + b198d7b commit 5cb0c51
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 49 deletions.
8 changes: 5 additions & 3 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -1681,8 +1681,9 @@ struct xfrm_policy *xfrm_policy_byid(struct net *net,
int xfrm_policy_flush(struct net *net, u8 type, bool task_valid);
void xfrm_policy_hash_rebuild(struct net *net);
u32 xfrm_get_acqseq(void);
int verify_spi_info(u8 proto, u32 min, u32 max);
int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi);
int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack);
int xfrm_alloc_spi(struct xfrm_state *x, u32 minspi, u32 maxspi,
struct netlink_ext_ack *extack);
struct xfrm_state *xfrm_find_acq(struct net *net, const struct xfrm_mark *mark,
u8 mode, u32 reqid, u32 if_id, u8 proto,
const xfrm_address_t *daddr,
Expand All @@ -1703,7 +1704,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
3 changes: 1 addition & 2 deletions net/ipv6/esp6_offload.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,11 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head,
__be32 seq;
__be32 spi;
int nhoff;
int err;

if (!pskb_pull(skb, offset))
return NULL;

if ((err = xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq)) != 0)
if (xfrm_parse_spi(skb, IPPROTO_ESP, &spi, &seq) != 0)
goto out;

xo = xfrm_offload(skb);
Expand Down
6 changes: 3 additions & 3 deletions net/key/af_key.c
Original file line number Diff line number Diff line change
Expand Up @@ -1377,13 +1377,13 @@ static int pfkey_getspi(struct sock *sk, struct sk_buff *skb, const struct sadb_
max_spi = range->sadb_spirange_max;
}

err = verify_spi_info(x->id.proto, min_spi, max_spi);
err = verify_spi_info(x->id.proto, min_spi, max_spi, NULL);
if (err) {
xfrm_state_put(x);
return err;
}

err = xfrm_alloc_spi(x, min_spi, max_spi);
err = xfrm_alloc_spi(x, min_spi, max_spi, NULL);
resp_skb = err ? ERR_PTR(err) : pfkey_xfrm_state2msg(x);

if (IS_ERR(resp_skb)) {
Expand Down 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
1 change: 1 addition & 0 deletions net/xfrm/xfrm_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -671,6 +671,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)

x->curlft.bytes += skb->len;
x->curlft.packets++;
x->lastused = ktime_get_real_seconds();

spin_unlock(&x->lock);

Expand Down
3 changes: 1 addition & 2 deletions net/xfrm/xfrm_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,8 +209,6 @@ static int xfrm6_ro_output(struct xfrm_state *x, struct sk_buff *skb)
__skb_pull(skb, hdr_len);
memmove(ipv6_hdr(skb), iph, hdr_len);

x->lastused = ktime_get_real_seconds();

return 0;
#else
WARN_ON_ONCE(1);
Expand Down Expand Up @@ -534,6 +532,7 @@ static int xfrm_output_one(struct sk_buff *skb, int err)

x->curlft.bytes += skb->len;
x->curlft.packets++;
x->lastused = ktime_get_real_seconds();

spin_unlock_bh(&x->lock);

Expand Down
37 changes: 26 additions & 11 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -605,7 +605,7 @@ static void xfrm_bydst_resize(struct net *net, int dir)
xfrm_hash_free(odst, (hmask + 1) * sizeof(struct hlist_head));
}

static void xfrm_byidx_resize(struct net *net, int total)
static void xfrm_byidx_resize(struct net *net)
{
unsigned int hmask = net->xfrm.policy_idx_hmask;
unsigned int nhashmask = xfrm_new_hash_mask(hmask);
Expand Down Expand Up @@ -683,7 +683,7 @@ static void xfrm_hash_resize(struct work_struct *work)
xfrm_bydst_resize(net, dir);
}
if (xfrm_byidx_should_resize(net, total))
xfrm_byidx_resize(net, total);
xfrm_byidx_resize(net);

mutex_unlock(&hash_resize_mutex);
}
Expand Down 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,16 +4424,20 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
struct xfrm_migrate *mp;

/* Stage 0 - sanity checks */
if ((err = xfrm_migrate_check(m, num_migrate)) < 0)
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 */
if ((pol = xfrm_migrate_policy_find(sel, dir, type, net, if_id)) == NULL) {
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 @@ -4445,7 +4459,8 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
}

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

/* Stage 4 - delete old state(s) */
Expand Down
21 changes: 16 additions & 5 deletions net/xfrm/xfrm_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -2017,7 +2017,7 @@ u32 xfrm_get_acqseq(void)
}
EXPORT_SYMBOL(xfrm_get_acqseq);

int verify_spi_info(u8 proto, u32 min, u32 max)
int verify_spi_info(u8 proto, u32 min, u32 max, struct netlink_ext_ack *extack)
{
switch (proto) {
case IPPROTO_AH:
Expand All @@ -2026,22 +2026,28 @@ int verify_spi_info(u8 proto, u32 min, u32 max)

case IPPROTO_COMP:
/* IPCOMP spi is 16-bits. */
if (max >= 0x10000)
if (max >= 0x10000) {
NL_SET_ERR_MSG(extack, "IPCOMP SPI must be <= 65535");
return -EINVAL;
}
break;

default:
NL_SET_ERR_MSG(extack, "Invalid protocol, must be one of AH, ESP, IPCOMP");
return -EINVAL;
}

if (min > max)
if (min > max) {
NL_SET_ERR_MSG(extack, "Invalid SPI range: min > max");
return -EINVAL;
}

return 0;
}
EXPORT_SYMBOL(verify_spi_info);

int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high,
struct netlink_ext_ack *extack)
{
struct net *net = xs_net(x);
unsigned int h;
Expand All @@ -2053,8 +2059,10 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
u32 mark = x->mark.v & x->mark.m;

spin_lock_bh(&x->lock);
if (x->km.state == XFRM_STATE_DEAD)
if (x->km.state == XFRM_STATE_DEAD) {
NL_SET_ERR_MSG(extack, "Target ACQUIRE is in DEAD state");
goto unlock;
}

err = 0;
if (x->id.spi)
Expand All @@ -2065,6 +2073,7 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
if (minspi == maxspi) {
x0 = xfrm_state_lookup(net, mark, &x->id.daddr, minspi, x->id.proto, x->props.family);
if (x0) {
NL_SET_ERR_MSG(extack, "Requested SPI is already in use");
xfrm_state_put(x0);
goto unlock;
}
Expand All @@ -2089,6 +2098,8 @@ int xfrm_alloc_spi(struct xfrm_state *x, u32 low, u32 high)
spin_unlock_bh(&net->xfrm.xfrm_state_lock);

err = 0;
} else {
NL_SET_ERR_MSG(extack, "No SPI available in the requested range");
}

unlock:
Expand Down
Loading

0 comments on commit 5cb0c51

Please sign in to comment.