* [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02
@ 2022-10-02 8:16 Steffen Klassert
2022-10-02 8:16 ` [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs Steffen Klassert
` (23 more replies)
0 siblings, 24 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
1) Refactor selftests to use an array of structs in xfrm_fill_key().
From Gautam Menghani.
2) Drop an unused argument from xfrm_policy_match.
From Hongbin Wang.
3) Support collect metadata mode for xfrm interfaces.
From Eyal Birger.
4) Add netlink extack support to xfrm.
From Sabrina Dubroca.
Please note, there is a merge conflict in:
include/net/dst_metadata.h
between commit:
0a28bfd4971f ("net/macsec: Add MACsec skb_metadata_dst Tx Data path support")
from the net-next tree and commit:
5182a5d48c3d ("net: allow storing xfrm interface metadata in metadata_dst")
from the ipsec-next tree.
Can be solved as done in linux-next.
Please pull or let me know if there are problems.
Thanks!
The following changes since commit 7ebfc85e2cd7b08f518b526173e9a33b56b3913b:
Merge tag 'net-6.0-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/netdev/net (2022-08-11 13:45:37 -0700)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next.git master
for you to fetch changes up to c39596f6ad1bfe65fc2d926e0703cf26e3fae90a:
Merge branch 'xfrm: add netlink extack to all the ->init_stat' (2022-09-30 09:49:33 +0200)
----------------------------------------------------------------
Eyal Birger (3):
net: allow storing xfrm interface metadata in metadata_dst
xfrm: interface: support collect metadata mode
xfrm: lwtunnel: add lwtunnel support for xfrm interfaces in collect_md mode
Gautam Menghani (1):
selftests/net: Refactor xfrm_fill_key() to use array of structs
Hongbin Wang (1):
xfrm: Drop unused argument
Sabrina Dubroca (19):
xfrm: propagate extack to all netlink doit handlers
xfrm: add extack support to verify_newpolicy_info
xfrm: add extack to verify_policy_dir
xfrm: add extack to verify_policy_type
xfrm: add extack to validate_tmpl
xfrm: add extack to verify_sec_ctx_len
xfrm: add extack support to verify_newsa_info
xfrm: add extack to verify_replay
xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead
xfrm: add extack support to xfrm_dev_state_add
xfrm: add extack to attach_*
xfrm: add extack to __xfrm_init_state
xfrm: add extack support to xfrm_init_replay
xfrm: pass extack down to xfrm_type ->init_state
xfrm: ah: add extack to ah_init_state, ah6_init_state
xfrm: esp: add extack to esp_init_state, esp6_init_state
xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state
xfrm: ipcomp: add extack to ipcomp{4,6}_init_state
xfrm: mip6: add extack to mip6_destopt_init_state, mip6_rthdr_init_state
Steffen Klassert (3):
Merge remote-tracking branch 'xfrm: start adding netlink extack support'
Merge branch 'xfrm: add netlink extack for state creation'
Merge branch 'xfrm: add netlink extack to all the ->init_stat'
include/net/dst_metadata.h | 31 +++
include/net/ipcomp.h | 2 +-
include/net/xfrm.h | 24 ++-
include/uapi/linux/if_link.h | 1 +
include/uapi/linux/lwtunnel.h | 10 +
net/core/lwtunnel.c | 1 +
net/ipv4/ah4.c | 23 ++-
net/ipv4/esp4.c | 55 +++---
net/ipv4/ipcomp.c | 10 +-
net/ipv4/xfrm4_tunnel.c | 10 +-
net/ipv6/ah6.c | 23 ++-
net/ipv6/esp6.c | 55 +++---
net/ipv6/ipcomp6.c | 10 +-
net/ipv6/mip6.c | 14 +-
net/ipv6/xfrm6_tunnel.c | 10 +-
net/xfrm/xfrm_device.c | 20 +-
net/xfrm/xfrm_input.c | 7 +-
net/xfrm/xfrm_interface.c | 206 ++++++++++++++++++--
net/xfrm/xfrm_ipcomp.c | 10 +-
net/xfrm/xfrm_policy.c | 25 ++-
net/xfrm/xfrm_replay.c | 10 +-
net/xfrm/xfrm_state.c | 30 ++-
net/xfrm/xfrm_user.c | 370 ++++++++++++++++++++++++------------
tools/testing/selftests/net/ipsec.c | 104 +++++-----
24 files changed, 738 insertions(+), 323 deletions(-)
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-03 7:10 ` patchwork-bot+netdevbpf
2022-10-02 8:16 ` [PATCH 02/24] xfrm: Drop unused argument Steffen Klassert
` (22 subsequent siblings)
23 siblings, 1 reply; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Gautam Menghani <gautammenghani201@gmail•com>
A TODO in net/ipsec.c asks to refactor the code in xfrm_fill_key() to
use set/map to avoid manually comparing each algorithm with the "name"
parameter passed to the function as an argument. This patch refactors
the code to create an array of structs where each struct contains the
algorithm name and its corresponding key length.
Signed-off-by: Gautam Menghani <gautammenghani201@gmail•com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
tools/testing/selftests/net/ipsec.c | 104 ++++++++++++----------------
1 file changed, 45 insertions(+), 59 deletions(-)
diff --git a/tools/testing/selftests/net/ipsec.c b/tools/testing/selftests/net/ipsec.c
index cc10c10c5ed9..9a8229abfa02 100644
--- a/tools/testing/selftests/net/ipsec.c
+++ b/tools/testing/selftests/net/ipsec.c
@@ -58,6 +58,8 @@
#define VETH_FMT "ktst-%d"
#define VETH_LEN 12
+#define XFRM_ALGO_NR_KEYS 29
+
static int nsfd_parent = -1;
static int nsfd_childa = -1;
static int nsfd_childb = -1;
@@ -75,6 +77,43 @@ const unsigned int ping_timeout = 300;
const unsigned int ping_count = 100;
const unsigned int ping_success = 80;
+struct xfrm_key_entry {
+ char algo_name[35];
+ int key_len;
+};
+
+struct xfrm_key_entry xfrm_key_entries[] = {
+ {"digest_null", 0},
+ {"ecb(cipher_null)", 0},
+ {"cbc(des)", 64},
+ {"hmac(md5)", 128},
+ {"cmac(aes)", 128},
+ {"xcbc(aes)", 128},
+ {"cbc(cast5)", 128},
+ {"cbc(serpent)", 128},
+ {"hmac(sha1)", 160},
+ {"hmac(rmd160)", 160},
+ {"cbc(des3_ede)", 192},
+ {"hmac(sha256)", 256},
+ {"cbc(aes)", 256},
+ {"cbc(camellia)", 256},
+ {"cbc(twofish)", 256},
+ {"rfc3686(ctr(aes))", 288},
+ {"hmac(sha384)", 384},
+ {"cbc(blowfish)", 448},
+ {"hmac(sha512)", 512},
+ {"rfc4106(gcm(aes))-128", 160},
+ {"rfc4543(gcm(aes))-128", 160},
+ {"rfc4309(ccm(aes))-128", 152},
+ {"rfc4106(gcm(aes))-192", 224},
+ {"rfc4543(gcm(aes))-192", 224},
+ {"rfc4309(ccm(aes))-192", 216},
+ {"rfc4106(gcm(aes))-256", 288},
+ {"rfc4543(gcm(aes))-256", 288},
+ {"rfc4309(ccm(aes))-256", 280},
+ {"rfc7539(chacha20,poly1305)-128", 0}
+};
+
static void randomize_buffer(void *buf, size_t buflen)
{
int *p = (int *)buf;
@@ -767,65 +806,12 @@ static int do_ping(int cmd_fd, char *buf, size_t buf_len, struct in_addr from,
static int xfrm_fill_key(char *name, char *buf,
size_t buf_len, unsigned int *key_len)
{
- /* TODO: use set/map instead */
- if (strncmp(name, "digest_null", ALGO_LEN) == 0)
- *key_len = 0;
- else if (strncmp(name, "ecb(cipher_null)", ALGO_LEN) == 0)
- *key_len = 0;
- else if (strncmp(name, "cbc(des)", ALGO_LEN) == 0)
- *key_len = 64;
- else if (strncmp(name, "hmac(md5)", ALGO_LEN) == 0)
- *key_len = 128;
- else if (strncmp(name, "cmac(aes)", ALGO_LEN) == 0)
- *key_len = 128;
- else if (strncmp(name, "xcbc(aes)", ALGO_LEN) == 0)
- *key_len = 128;
- else if (strncmp(name, "cbc(cast5)", ALGO_LEN) == 0)
- *key_len = 128;
- else if (strncmp(name, "cbc(serpent)", ALGO_LEN) == 0)
- *key_len = 128;
- else if (strncmp(name, "hmac(sha1)", ALGO_LEN) == 0)
- *key_len = 160;
- else if (strncmp(name, "hmac(rmd160)", ALGO_LEN) == 0)
- *key_len = 160;
- else if (strncmp(name, "cbc(des3_ede)", ALGO_LEN) == 0)
- *key_len = 192;
- else if (strncmp(name, "hmac(sha256)", ALGO_LEN) == 0)
- *key_len = 256;
- else if (strncmp(name, "cbc(aes)", ALGO_LEN) == 0)
- *key_len = 256;
- else if (strncmp(name, "cbc(camellia)", ALGO_LEN) == 0)
- *key_len = 256;
- else if (strncmp(name, "cbc(twofish)", ALGO_LEN) == 0)
- *key_len = 256;
- else if (strncmp(name, "rfc3686(ctr(aes))", ALGO_LEN) == 0)
- *key_len = 288;
- else if (strncmp(name, "hmac(sha384)", ALGO_LEN) == 0)
- *key_len = 384;
- else if (strncmp(name, "cbc(blowfish)", ALGO_LEN) == 0)
- *key_len = 448;
- else if (strncmp(name, "hmac(sha512)", ALGO_LEN) == 0)
- *key_len = 512;
- else if (strncmp(name, "rfc4106(gcm(aes))-128", ALGO_LEN) == 0)
- *key_len = 160;
- else if (strncmp(name, "rfc4543(gcm(aes))-128", ALGO_LEN) == 0)
- *key_len = 160;
- else if (strncmp(name, "rfc4309(ccm(aes))-128", ALGO_LEN) == 0)
- *key_len = 152;
- else if (strncmp(name, "rfc4106(gcm(aes))-192", ALGO_LEN) == 0)
- *key_len = 224;
- else if (strncmp(name, "rfc4543(gcm(aes))-192", ALGO_LEN) == 0)
- *key_len = 224;
- else if (strncmp(name, "rfc4309(ccm(aes))-192", ALGO_LEN) == 0)
- *key_len = 216;
- else if (strncmp(name, "rfc4106(gcm(aes))-256", ALGO_LEN) == 0)
- *key_len = 288;
- else if (strncmp(name, "rfc4543(gcm(aes))-256", ALGO_LEN) == 0)
- *key_len = 288;
- else if (strncmp(name, "rfc4309(ccm(aes))-256", ALGO_LEN) == 0)
- *key_len = 280;
- else if (strncmp(name, "rfc7539(chacha20,poly1305)-128", ALGO_LEN) == 0)
- *key_len = 0;
+ int i;
+
+ for (i = 0; i < XFRM_ALGO_NR_KEYS; i++) {
+ if (strncmp(name, xfrm_key_entries[i].algo_name, ALGO_LEN) == 0)
+ *key_len = xfrm_key_entries[i].key_len;
+ }
if (*key_len > buf_len) {
printk("Can't pack a key - too big for buffer");
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 02/24] xfrm: Drop unused argument
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
2022-10-02 8:16 ` [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 03/24] net: allow storing xfrm interface metadata in metadata_dst Steffen Klassert
` (21 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Hongbin Wang <wh_bin@126•com>
Drop unused argument from xfrm_policy_match,
__xfrm_policy_eval_candidates and xfrm_policy_eval_candidates.
No functional changes intended.
Signed-off-by: Hongbin Wang <wh_bin@126•com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_policy.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index f1a0bab920a5..6264680b1f08 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1889,7 +1889,7 @@ EXPORT_SYMBOL(xfrm_policy_walk_done);
*/
static int xfrm_policy_match(const struct xfrm_policy *pol,
const struct flowi *fl,
- u8 type, u16 family, int dir, u32 if_id)
+ u8 type, u16 family, u32 if_id)
{
const struct xfrm_selector *sel = &pol->selector;
int ret = -ESRCH;
@@ -2014,7 +2014,7 @@ static struct xfrm_policy *
__xfrm_policy_eval_candidates(struct hlist_head *chain,
struct xfrm_policy *prefer,
const struct flowi *fl,
- u8 type, u16 family, int dir, u32 if_id)
+ u8 type, u16 family, u32 if_id)
{
u32 priority = prefer ? prefer->priority : ~0u;
struct xfrm_policy *pol;
@@ -2028,7 +2028,7 @@ __xfrm_policy_eval_candidates(struct hlist_head *chain,
if (pol->priority > priority)
break;
- err = xfrm_policy_match(pol, fl, type, family, dir, if_id);
+ err = xfrm_policy_match(pol, fl, type, family, if_id);
if (err) {
if (err != -ESRCH)
return ERR_PTR(err);
@@ -2053,7 +2053,7 @@ static struct xfrm_policy *
xfrm_policy_eval_candidates(struct xfrm_pol_inexact_candidates *cand,
struct xfrm_policy *prefer,
const struct flowi *fl,
- u8 type, u16 family, int dir, u32 if_id)
+ u8 type, u16 family, u32 if_id)
{
struct xfrm_policy *tmp;
int i;
@@ -2061,8 +2061,7 @@ xfrm_policy_eval_candidates(struct xfrm_pol_inexact_candidates *cand,
for (i = 0; i < ARRAY_SIZE(cand->res); i++) {
tmp = __xfrm_policy_eval_candidates(cand->res[i],
prefer,
- fl, type, family, dir,
- if_id);
+ fl, type, family, if_id);
if (!tmp)
continue;
@@ -2101,7 +2100,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
ret = NULL;
hlist_for_each_entry_rcu(pol, chain, bydst) {
- err = xfrm_policy_match(pol, fl, type, family, dir, if_id);
+ err = xfrm_policy_match(pol, fl, type, family, if_id);
if (err) {
if (err == -ESRCH)
continue;
@@ -2120,7 +2119,7 @@ static struct xfrm_policy *xfrm_policy_lookup_bytype(struct net *net, u8 type,
goto skip_inexact;
pol = xfrm_policy_eval_candidates(&cand, ret, fl, type,
- family, dir, if_id);
+ family, if_id);
if (pol) {
ret = pol;
if (IS_ERR(pol))
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 03/24] net: allow storing xfrm interface metadata in metadata_dst
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
2022-10-02 8:16 ` [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs Steffen Klassert
2022-10-02 8:16 ` [PATCH 02/24] xfrm: Drop unused argument Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 04/24] xfrm: interface: support collect metadata mode Steffen Klassert
` (20 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Eyal Birger <eyal.birger@gmail•com>
XFRM interfaces provide the association of various XFRM transformations
to a netdevice using an 'if_id' identifier common to both the XFRM data
structures (polcies, states) and the interface. The if_id is configured by
the controlling entity (usually the IKE daemon) and can be used by the
administrator to define logical relations between different connections.
For example, different connections can share the if_id identifier so
that they pass through the same interface, . However, currently it is
not possible for connections using a different if_id to use the same
interface while retaining the logical separation between them, without
using additional criteria such as skb marks or different traffic
selectors.
When having a large number of connections, it is useful to have a the
logical separation offered by the if_id identifier but use a single
network interface. Similar to the way collect_md mode is used in IP
tunnels.
This patch attempts to enable different configuration mechanisms - such
as ebpf programs, LWT encapsulations, and TC - to attach metadata
to skbs which would carry the if_id. This way a single xfrm interface in
collect_md mode can demux traffic based on this configuration on tx and
provide this metadata on rx.
The XFRM metadata is somewhat similar to ip tunnel metadata in that it
has an "id", and shares similar configuration entities (bpf, tc, ...),
however, it does not necessarily represent an IP tunnel or use other
ip tunnel information, and also has an optional "link" property which
can be used for affecting underlying routing decisions.
Additional xfrm related criteria may also be added in the future.
Therefore, a new metadata type is introduced, to be used in subsequent
patches in the xfrm interface and configuration entities.
Reviewed-by: Nikolay Aleksandrov <razor@blackwall•org>
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind•com>
Signed-off-by: Eyal Birger <eyal.birger@gmail•com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/dst_metadata.h | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index adab27ba1ecb..e4b059908cc7 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -9,6 +9,7 @@
enum metadata_type {
METADATA_IP_TUNNEL,
METADATA_HW_PORT_MUX,
+ METADATA_XFRM,
};
struct hw_port_info {
@@ -16,12 +17,18 @@ struct hw_port_info {
u32 port_id;
};
+struct xfrm_md_info {
+ u32 if_id;
+ int link;
+};
+
struct metadata_dst {
struct dst_entry dst;
enum metadata_type type;
union {
struct ip_tunnel_info tun_info;
struct hw_port_info port_info;
+ struct xfrm_md_info xfrm_info;
} u;
};
@@ -53,6 +60,16 @@ skb_tunnel_info(const struct sk_buff *skb)
return NULL;
}
+static inline struct xfrm_md_info *skb_xfrm_md_info(const struct sk_buff *skb)
+{
+ struct metadata_dst *md_dst = skb_metadata_dst(skb);
+
+ if (md_dst && md_dst->type == METADATA_XFRM)
+ return &md_dst->u.xfrm_info;
+
+ return NULL;
+}
+
static inline bool skb_valid_dst(const struct sk_buff *skb)
{
struct dst_entry *dst = skb_dst(skb);
@@ -82,6 +99,9 @@ static inline int skb_metadata_dst_cmp(const struct sk_buff *skb_a,
return memcmp(&a->u.tun_info, &b->u.tun_info,
sizeof(a->u.tun_info) +
a->u.tun_info.options_len);
+ case METADATA_XFRM:
+ return memcmp(&a->u.xfrm_info, &b->u.xfrm_info,
+ sizeof(a->u.xfrm_info));
default:
return 1;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 04/24] xfrm: interface: support collect metadata mode
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (2 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 03/24] net: allow storing xfrm interface metadata in metadata_dst Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 05/24] xfrm: lwtunnel: add lwtunnel support for xfrm interfaces in collect_md mode Steffen Klassert
` (19 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Eyal Birger <eyal.birger@gmail•com>
This commit adds support for 'collect_md' mode on xfrm interfaces.
Each net can have one collect_md device, created by providing the
IFLA_XFRM_COLLECT_METADATA flag at creation. This device cannot be
altered and has no if_id or link device attributes.
On transmit to this device, the if_id is fetched from the attached dst
metadata on the skb. If exists, the link property is also fetched from
the metadata. The dst metadata type used is METADATA_XFRM which holds
these properties.
On the receive side, xfrmi_rcv_cb() populates a dst metadata for each
packet received and attaches it to the skb. The if_id used in this case is
fetched from the xfrm state, and the link is fetched from the incoming
device. This information can later be used by upper layers such as tc,
ebpf, and ip rules.
Because the skb is scrubed in xfrmi_rcv_cb(), the attachment of the dst
metadata is postponed until after scrubing. Similarly, xfrm_input() is
adapted to avoid dropping metadata dsts by only dropping 'valid'
(skb_valid_dst(skb) == true) dsts.
Policy matching on packets arriving from collect_md xfrmi devices is
done by using the xfrm state existing in the skb's sec_path.
The xfrm_if_cb.decode_cb() interface implemented by xfrmi_decode_session()
is changed to keep the details of the if_id extraction tucked away
in xfrm_interface.c.
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind•com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall•org>
Signed-off-by: Eyal Birger <eyal.birger@gmail•com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/xfrm.h | 11 +++-
include/uapi/linux/if_link.h | 1 +
net/xfrm/xfrm_input.c | 7 +-
net/xfrm/xfrm_interface.c | 121 +++++++++++++++++++++++++++++------
net/xfrm/xfrm_policy.c | 10 +--
5 files changed, 121 insertions(+), 29 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 6e8fa98f786f..28b988577ed2 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -312,9 +312,15 @@ struct km_event {
struct net *net;
};
+struct xfrm_if_decode_session_result {
+ struct net *net;
+ u32 if_id;
+};
+
struct xfrm_if_cb {
- struct xfrm_if *(*decode_session)(struct sk_buff *skb,
- unsigned short family);
+ bool (*decode_session)(struct sk_buff *skb,
+ unsigned short family,
+ struct xfrm_if_decode_session_result *res);
};
void xfrm_if_register_cb(const struct xfrm_if_cb *ifcb);
@@ -985,6 +991,7 @@ void xfrm_dst_ifdown(struct dst_entry *dst, struct net_device *dev);
struct xfrm_if_parms {
int link; /* ifindex of underlying L2 interface */
u32 if_id; /* interface identifyer */
+ bool collect_md;
};
struct xfrm_if {
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index e36d9d2c65a7..d96f13a42589 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -694,6 +694,7 @@ enum {
IFLA_XFRM_UNSPEC,
IFLA_XFRM_LINK,
IFLA_XFRM_IF_ID,
+ IFLA_XFRM_COLLECT_METADATA,
__IFLA_XFRM_MAX
};
diff --git a/net/xfrm/xfrm_input.c b/net/xfrm/xfrm_input.c
index 144238a50f3d..25e822fb5771 100644
--- a/net/xfrm/xfrm_input.c
+++ b/net/xfrm/xfrm_input.c
@@ -20,6 +20,7 @@
#include <net/xfrm.h>
#include <net/ip_tunnels.h>
#include <net/ip6_tunnel.h>
+#include <net/dst_metadata.h>
#include "xfrm_inout.h"
@@ -720,7 +721,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
sp = skb_sec_path(skb);
if (sp)
sp->olen = 0;
- skb_dst_drop(skb);
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
gro_cells_receive(&gro_cells, skb);
return 0;
} else {
@@ -738,7 +740,8 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
sp = skb_sec_path(skb);
if (sp)
sp->olen = 0;
- skb_dst_drop(skb);
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
gro_cells_receive(&gro_cells, skb);
return err;
}
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c
index 5113fa0fbcee..e9a355047468 100644
--- a/net/xfrm/xfrm_interface.c
+++ b/net/xfrm/xfrm_interface.c
@@ -41,6 +41,7 @@
#include <net/addrconf.h>
#include <net/xfrm.h>
#include <net/net_namespace.h>
+#include <net/dst_metadata.h>
#include <net/netns/generic.h>
#include <linux/etherdevice.h>
@@ -56,6 +57,7 @@ static const struct net_device_ops xfrmi_netdev_ops;
struct xfrmi_net {
/* lists for storing interfaces in use */
struct xfrm_if __rcu *xfrmi[XFRMI_HASH_SIZE];
+ struct xfrm_if __rcu *collect_md_xfrmi;
};
#define for_each_xfrmi_rcu(start, xi) \
@@ -77,17 +79,23 @@ static struct xfrm_if *xfrmi_lookup(struct net *net, struct xfrm_state *x)
return xi;
}
+ xi = rcu_dereference(xfrmn->collect_md_xfrmi);
+ if (xi && (xi->dev->flags & IFF_UP))
+ return xi;
+
return NULL;
}
-static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb,
- unsigned short family)
+static bool xfrmi_decode_session(struct sk_buff *skb,
+ unsigned short family,
+ struct xfrm_if_decode_session_result *res)
{
struct net_device *dev;
+ struct xfrm_if *xi;
int ifindex = 0;
if (!secpath_exists(skb) || !skb->dev)
- return NULL;
+ return false;
switch (family) {
case AF_INET6:
@@ -107,11 +115,18 @@ static struct xfrm_if *xfrmi_decode_session(struct sk_buff *skb,
}
if (!dev || !(dev->flags & IFF_UP))
- return NULL;
+ return false;
if (dev->netdev_ops != &xfrmi_netdev_ops)
- return NULL;
+ return false;
- return netdev_priv(dev);
+ xi = netdev_priv(dev);
+ res->net = xi->net;
+
+ if (xi->p.collect_md)
+ res->if_id = xfrm_input_state(skb)->if_id;
+ else
+ res->if_id = xi->p.if_id;
+ return true;
}
static void xfrmi_link(struct xfrmi_net *xfrmn, struct xfrm_if *xi)
@@ -157,7 +172,10 @@ static int xfrmi_create(struct net_device *dev)
if (err < 0)
goto out;
- xfrmi_link(xfrmn, xi);
+ if (xi->p.collect_md)
+ rcu_assign_pointer(xfrmn->collect_md_xfrmi, xi);
+ else
+ xfrmi_link(xfrmn, xi);
return 0;
@@ -185,7 +203,10 @@ static void xfrmi_dev_uninit(struct net_device *dev)
struct xfrm_if *xi = netdev_priv(dev);
struct xfrmi_net *xfrmn = net_generic(xi->net, xfrmi_net_id);
- xfrmi_unlink(xfrmn, xi);
+ if (xi->p.collect_md)
+ RCU_INIT_POINTER(xfrmn->collect_md_xfrmi, NULL);
+ else
+ xfrmi_unlink(xfrmn, xi);
}
static void xfrmi_scrub_packet(struct sk_buff *skb, bool xnet)
@@ -214,6 +235,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
struct xfrm_state *x;
struct xfrm_if *xi;
bool xnet;
+ int link;
if (err && !secpath_exists(skb))
return 0;
@@ -224,6 +246,7 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
if (!xi)
return 1;
+ link = skb->dev->ifindex;
dev = xi->dev;
skb->dev = dev;
@@ -254,6 +277,17 @@ static int xfrmi_rcv_cb(struct sk_buff *skb, int err)
}
xfrmi_scrub_packet(skb, xnet);
+ if (xi->p.collect_md) {
+ struct metadata_dst *md_dst;
+
+ md_dst = metadata_dst_alloc(0, METADATA_XFRM, GFP_ATOMIC);
+ if (!md_dst)
+ return -ENOMEM;
+
+ md_dst->u.xfrm_info.if_id = x->if_id;
+ md_dst->u.xfrm_info.link = link;
+ skb_dst_set(skb, (struct dst_entry *)md_dst);
+ }
dev_sw_netstats_rx_add(dev, skb->len);
return 0;
@@ -269,10 +303,23 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
struct net_device *tdev;
struct xfrm_state *x;
int err = -1;
+ u32 if_id;
int mtu;
+ if (xi->p.collect_md) {
+ struct xfrm_md_info *md_info = skb_xfrm_md_info(skb);
+
+ if (unlikely(!md_info))
+ return -EINVAL;
+
+ if_id = md_info->if_id;
+ fl->flowi_oif = md_info->link;
+ } else {
+ if_id = xi->p.if_id;
+ }
+
dst_hold(dst);
- dst = xfrm_lookup_with_ifid(xi->net, dst, fl, NULL, 0, xi->p.if_id);
+ dst = xfrm_lookup_with_ifid(xi->net, dst, fl, NULL, 0, if_id);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
dst = NULL;
@@ -283,7 +330,7 @@ xfrmi_xmit2(struct sk_buff *skb, struct net_device *dev, struct flowi *fl)
if (!x)
goto tx_err_link_failure;
- if (x->if_id != xi->p.if_id)
+ if (x->if_id != if_id)
goto tx_err_link_failure;
tdev = dst->dev;
@@ -633,6 +680,9 @@ static void xfrmi_netlink_parms(struct nlattr *data[],
if (data[IFLA_XFRM_IF_ID])
parms->if_id = nla_get_u32(data[IFLA_XFRM_IF_ID]);
+
+ if (data[IFLA_XFRM_COLLECT_METADATA])
+ parms->collect_md = true;
}
static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
@@ -645,14 +695,27 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev,
int err;
xfrmi_netlink_parms(data, &p);
- if (!p.if_id) {
- NL_SET_ERR_MSG(extack, "if_id must be non zero");
- return -EINVAL;
- }
+ if (p.collect_md) {
+ struct xfrmi_net *xfrmn = net_generic(net, xfrmi_net_id);
- xi = xfrmi_locate(net, &p);
- if (xi)
- return -EEXIST;
+ if (p.link || p.if_id) {
+ NL_SET_ERR_MSG(extack, "link and if_id must be zero");
+ return -EINVAL;
+ }
+
+ if (rtnl_dereference(xfrmn->collect_md_xfrmi))
+ return -EEXIST;
+
+ } else {
+ if (!p.if_id) {
+ NL_SET_ERR_MSG(extack, "if_id must be non zero");
+ return -EINVAL;
+ }
+
+ xi = xfrmi_locate(net, &p);
+ if (xi)
+ return -EEXIST;
+ }
xi = netdev_priv(dev);
xi->p = p;
@@ -682,12 +745,22 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[],
return -EINVAL;
}
+ if (p.collect_md) {
+ NL_SET_ERR_MSG(extack, "collect_md can't be changed");
+ return -EINVAL;
+ }
+
xi = xfrmi_locate(net, &p);
if (!xi) {
xi = netdev_priv(dev);
} else {
if (xi->dev != dev)
return -EEXIST;
+ if (xi->p.collect_md) {
+ NL_SET_ERR_MSG(extack,
+ "device can't be changed to collect_md");
+ return -EINVAL;
+ }
}
return xfrmi_update(xi, &p);
@@ -700,6 +773,8 @@ static size_t xfrmi_get_size(const struct net_device *dev)
nla_total_size(4) +
/* IFLA_XFRM_IF_ID */
nla_total_size(4) +
+ /* IFLA_XFRM_COLLECT_METADATA */
+ nla_total_size(0) +
0;
}
@@ -709,7 +784,8 @@ static int xfrmi_fill_info(struct sk_buff *skb, const struct net_device *dev)
struct xfrm_if_parms *parm = &xi->p;
if (nla_put_u32(skb, IFLA_XFRM_LINK, parm->link) ||
- nla_put_u32(skb, IFLA_XFRM_IF_ID, parm->if_id))
+ nla_put_u32(skb, IFLA_XFRM_IF_ID, parm->if_id) ||
+ (xi->p.collect_md && nla_put_flag(skb, IFLA_XFRM_COLLECT_METADATA)))
goto nla_put_failure;
return 0;
@@ -725,8 +801,10 @@ static struct net *xfrmi_get_link_net(const struct net_device *dev)
}
static const struct nla_policy xfrmi_policy[IFLA_XFRM_MAX + 1] = {
- [IFLA_XFRM_LINK] = { .type = NLA_U32 },
- [IFLA_XFRM_IF_ID] = { .type = NLA_U32 },
+ [IFLA_XFRM_UNSPEC] = { .strict_start_type = IFLA_XFRM_COLLECT_METADATA },
+ [IFLA_XFRM_LINK] = { .type = NLA_U32 },
+ [IFLA_XFRM_IF_ID] = { .type = NLA_U32 },
+ [IFLA_XFRM_COLLECT_METADATA] = { .type = NLA_FLAG },
};
static struct rtnl_link_ops xfrmi_link_ops __read_mostly = {
@@ -762,6 +840,9 @@ static void __net_exit xfrmi_exit_batch_net(struct list_head *net_exit_list)
xip = &xi->next)
unregister_netdevice_queue(xi->dev, &list);
}
+ xi = rtnl_dereference(xfrmn->collect_md_xfrmi);
+ if (xi)
+ unregister_netdevice_queue(xi->dev, &list);
}
unregister_netdevice_many(&list);
rtnl_unlock();
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index 6264680b1f08..3c65059a508a 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -3515,17 +3515,17 @@ int __xfrm_policy_check(struct sock *sk, int dir, struct sk_buff *skb,
int xerr_idx = -1;
const struct xfrm_if_cb *ifcb;
struct sec_path *sp;
- struct xfrm_if *xi;
u32 if_id = 0;
rcu_read_lock();
ifcb = xfrm_if_get_cb();
if (ifcb) {
- xi = ifcb->decode_session(skb, family);
- if (xi) {
- if_id = xi->p.if_id;
- net = xi->net;
+ struct xfrm_if_decode_session_result r;
+
+ if (ifcb->decode_session(skb, family, &r)) {
+ if_id = r.if_id;
+ net = r.net;
}
}
rcu_read_unlock();
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 05/24] xfrm: lwtunnel: add lwtunnel support for xfrm interfaces in collect_md mode
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (3 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 04/24] xfrm: interface: support collect metadata mode Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 06/24] xfrm: propagate extack to all netlink doit handlers Steffen Klassert
` (18 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Eyal Birger <eyal.birger@gmail•com>
Allow specifying the xfrm interface if_id and link as part of a route
metadata using the lwtunnel infrastructure.
This allows for example using a single xfrm interface in collect_md
mode as the target of multiple routes each specifying a different if_id.
With the appropriate changes to iproute2, considering an xfrm device
ipsec1 in collect_md mode one can for example add a route specifying
an if_id like so:
ip route add <SUBNET> dev ipsec1 encap xfrm if_id 1
In which case traffic routed to the device via this route would use
if_id in the xfrm interface policy lookup.
Or in the context of vrf, one can also specify the "link" property:
ip route add <SUBNET> dev ipsec1 encap xfrm if_id 1 link_dev eth15
Note: LWT_XFRM_LINK uses NLA_U32 similar to IFLA_XFRM_LINK even though
internally "link" is signed. This is consistent with other _LINK
attributes in other devices as well as in bpf and should not have an
effect as device indexes can't be negative.
Reviewed-by: Nicolas Dichtel <nicolas.dichtel@6wind•com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall•org>
Signed-off-by: Eyal Birger <eyal.birger@gmail•com>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/dst_metadata.h | 11 +++++
include/uapi/linux/lwtunnel.h | 10 +++++
net/core/lwtunnel.c | 1 +
net/xfrm/xfrm_interface.c | 85 +++++++++++++++++++++++++++++++++++
4 files changed, 107 insertions(+)
diff --git a/include/net/dst_metadata.h b/include/net/dst_metadata.h
index e4b059908cc7..57f75960fa28 100644
--- a/include/net/dst_metadata.h
+++ b/include/net/dst_metadata.h
@@ -60,13 +60,24 @@ skb_tunnel_info(const struct sk_buff *skb)
return NULL;
}
+static inline struct xfrm_md_info *lwt_xfrm_info(struct lwtunnel_state *lwt)
+{
+ return (struct xfrm_md_info *)lwt->data;
+}
+
static inline struct xfrm_md_info *skb_xfrm_md_info(const struct sk_buff *skb)
{
struct metadata_dst *md_dst = skb_metadata_dst(skb);
+ struct dst_entry *dst;
if (md_dst && md_dst->type == METADATA_XFRM)
return &md_dst->u.xfrm_info;
+ dst = skb_dst(skb);
+ if (dst && dst->lwtstate &&
+ dst->lwtstate->type == LWTUNNEL_ENCAP_XFRM)
+ return lwt_xfrm_info(dst->lwtstate);
+
return NULL;
}
diff --git a/include/uapi/linux/lwtunnel.h b/include/uapi/linux/lwtunnel.h
index 2e206919125c..229655ef792f 100644
--- a/include/uapi/linux/lwtunnel.h
+++ b/include/uapi/linux/lwtunnel.h
@@ -15,6 +15,7 @@ enum lwtunnel_encap_types {
LWTUNNEL_ENCAP_SEG6_LOCAL,
LWTUNNEL_ENCAP_RPL,
LWTUNNEL_ENCAP_IOAM6,
+ LWTUNNEL_ENCAP_XFRM,
__LWTUNNEL_ENCAP_MAX,
};
@@ -111,4 +112,13 @@ enum {
#define LWT_BPF_MAX_HEADROOM 256
+enum {
+ LWT_XFRM_UNSPEC,
+ LWT_XFRM_IF_ID,
+ LWT_XFRM_LINK,
+ __LWT_XFRM_MAX,
+};
+
+#define LWT_XFRM_MAX (__LWT_XFRM_MAX - 1)
+
#endif /* _UAPI_LWTUNNEL_H_ */
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index 9ccd64e8a666..6fac2f0ef074 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -50,6 +50,7 @@ static const char *lwtunnel_encap_str(enum lwtunnel_encap_types encap_type)
return "IOAM6";
case LWTUNNEL_ENCAP_IP6:
case LWTUNNEL_ENCAP_IP:
+ case LWTUNNEL_ENCAP_XFRM:
case LWTUNNEL_ENCAP_NONE:
case __LWTUNNEL_ENCAP_MAX:
/* should not have got here */
diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c
index e9a355047468..5a67b120c4db 100644
--- a/net/xfrm/xfrm_interface.c
+++ b/net/xfrm/xfrm_interface.c
@@ -60,6 +60,88 @@ struct xfrmi_net {
struct xfrm_if __rcu *collect_md_xfrmi;
};
+static const struct nla_policy xfrm_lwt_policy[LWT_XFRM_MAX + 1] = {
+ [LWT_XFRM_IF_ID] = NLA_POLICY_MIN(NLA_U32, 1),
+ [LWT_XFRM_LINK] = NLA_POLICY_MIN(NLA_U32, 1),
+};
+
+static void xfrmi_destroy_state(struct lwtunnel_state *lwt)
+{
+}
+
+static int xfrmi_build_state(struct net *net, struct nlattr *nla,
+ unsigned int family, const void *cfg,
+ struct lwtunnel_state **ts,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *tb[LWT_XFRM_MAX + 1];
+ struct lwtunnel_state *new_state;
+ struct xfrm_md_info *info;
+ int ret;
+
+ ret = nla_parse_nested(tb, LWT_XFRM_MAX, nla, xfrm_lwt_policy, extack);
+ if (ret < 0)
+ return ret;
+
+ if (!tb[LWT_XFRM_IF_ID]) {
+ NL_SET_ERR_MSG(extack, "if_id must be set");
+ return -EINVAL;
+ }
+
+ new_state = lwtunnel_state_alloc(sizeof(*info));
+ if (!new_state) {
+ NL_SET_ERR_MSG(extack, "failed to create encap info");
+ return -ENOMEM;
+ }
+
+ new_state->type = LWTUNNEL_ENCAP_XFRM;
+
+ info = lwt_xfrm_info(new_state);
+
+ info->if_id = nla_get_u32(tb[LWT_XFRM_IF_ID]);
+
+ if (tb[LWT_XFRM_LINK])
+ info->link = nla_get_u32(tb[LWT_XFRM_LINK]);
+
+ *ts = new_state;
+ return 0;
+}
+
+static int xfrmi_fill_encap_info(struct sk_buff *skb,
+ struct lwtunnel_state *lwt)
+{
+ struct xfrm_md_info *info = lwt_xfrm_info(lwt);
+
+ if (nla_put_u32(skb, LWT_XFRM_IF_ID, info->if_id) ||
+ (info->link && nla_put_u32(skb, LWT_XFRM_LINK, info->link)))
+ return -EMSGSIZE;
+
+ return 0;
+}
+
+static int xfrmi_encap_nlsize(struct lwtunnel_state *lwtstate)
+{
+ return nla_total_size(sizeof(u32)) + /* LWT_XFRM_IF_ID */
+ nla_total_size(sizeof(u32)); /* LWT_XFRM_LINK */
+}
+
+static int xfrmi_encap_cmp(struct lwtunnel_state *a, struct lwtunnel_state *b)
+{
+ struct xfrm_md_info *a_info = lwt_xfrm_info(a);
+ struct xfrm_md_info *b_info = lwt_xfrm_info(b);
+
+ return memcmp(a_info, b_info, sizeof(*a_info));
+}
+
+static const struct lwtunnel_encap_ops xfrmi_encap_ops = {
+ .build_state = xfrmi_build_state,
+ .destroy_state = xfrmi_destroy_state,
+ .fill_encap = xfrmi_fill_encap_info,
+ .get_encap_size = xfrmi_encap_nlsize,
+ .cmp_encap = xfrmi_encap_cmp,
+ .owner = THIS_MODULE,
+};
+
#define for_each_xfrmi_rcu(start, xi) \
for (xi = rcu_dereference(start); xi; xi = rcu_dereference(xi->next))
@@ -1080,6 +1162,8 @@ static int __init xfrmi_init(void)
if (err < 0)
goto rtnl_link_failed;
+ lwtunnel_encap_add_ops(&xfrmi_encap_ops, LWTUNNEL_ENCAP_XFRM);
+
xfrm_if_register_cb(&xfrm_if_cb);
return err;
@@ -1098,6 +1182,7 @@ static int __init xfrmi_init(void)
static void __exit xfrmi_fini(void)
{
xfrm_if_unregister_cb();
+ lwtunnel_encap_del_ops(&xfrmi_encap_ops, LWTUNNEL_ENCAP_XFRM);
rtnl_link_unregister(&xfrmi_link_ops);
xfrmi4_fini();
xfrmi6_fini();
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 06/24] xfrm: propagate extack to all netlink doit handlers
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (4 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 05/24] xfrm: lwtunnel: add lwtunnel support for xfrm interfaces in collect_md mode Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 07/24] xfrm: add extack support to verify_newpolicy_info Steffen Klassert
` (17 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
xfrm_user_rcv_msg() already handles extack, we just need to pass it down.
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 56 +++++++++++++++++++++++++++-----------------
1 file changed, 34 insertions(+), 22 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2ff017117730..cfa35d76fb7e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -678,7 +678,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
}
static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_usersa_info *p = nlmsg_data(nlh);
@@ -757,7 +757,7 @@ static struct xfrm_state *xfrm_user_state_lookup(struct net *net,
}
static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_state *x;
@@ -1254,7 +1254,8 @@ static int build_spdinfo(struct sk_buff *skb, struct net *net,
}
static int xfrm_set_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrmu_spdhthresh *thresh4 = NULL;
@@ -1299,7 +1300,8 @@ static int xfrm_set_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_get_spdinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct sk_buff *r_skb;
@@ -1358,7 +1360,8 @@ static int build_sadinfo(struct sk_buff *skb, struct net *net,
}
static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct sk_buff *r_skb;
@@ -1378,7 +1381,7 @@ static int xfrm_get_sadinfo(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_usersa_id *p = nlmsg_data(nlh);
@@ -1402,7 +1405,8 @@ static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_state *x;
@@ -1754,7 +1758,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
}
static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_userpolicy_info *p = nlmsg_data(nlh);
@@ -2015,7 +2020,7 @@ static bool xfrm_userpolicy_is_valid(__u8 policy)
}
static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_userpolicy_default *up = nlmsg_data(nlh);
@@ -2036,7 +2041,7 @@ static int xfrm_set_default(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct sk_buff *r_skb;
struct nlmsghdr *r_nlh;
@@ -2066,7 +2071,8 @@ static int xfrm_get_default(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_policy *xp;
@@ -2149,7 +2155,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct km_event c;
@@ -2249,7 +2256,7 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, const struct
}
static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_state *x;
@@ -2293,7 +2300,7 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_state *x;
@@ -2344,7 +2351,8 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct km_event c;
@@ -2372,7 +2380,8 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_policy *xp;
@@ -2438,7 +2447,8 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_state *x;
@@ -2472,7 +2482,8 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
}
static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct net *net = sock_net(skb->sk);
struct xfrm_policy *xp;
@@ -2577,7 +2588,7 @@ static int copy_from_user_migrate(struct xfrm_migrate *ma,
}
static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct xfrm_userpolicy_id *pi = nlmsg_data(nlh);
struct xfrm_migrate m[XFRM_MAX_DEPTH];
@@ -2623,7 +2634,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
}
#else
static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
- struct nlattr **attrs)
+ struct nlattr **attrs, struct netlink_ext_ack *extack)
{
return -ENOPROTOOPT;
}
@@ -2819,7 +2830,8 @@ static const struct nla_policy xfrma_spd_policy[XFRMA_SPD_MAX+1] = {
};
static const struct xfrm_link {
- int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **);
+ int (*doit)(struct sk_buff *, struct nlmsghdr *, struct nlattr **,
+ struct netlink_ext_ack *);
int (*start)(struct netlink_callback *);
int (*dump)(struct sk_buff *, struct netlink_callback *);
int (*done)(struct netlink_callback *);
@@ -2921,7 +2933,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
goto err;
}
- err = link->doit(skb, nlh, attrs);
+ err = link->doit(skb, nlh, attrs, extack);
/* We need to free skb allocated in xfrm_alloc_compat() before
* returning from this function, because consume_skb() won't take
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 07/24] xfrm: add extack support to verify_newpolicy_info
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (5 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 06/24] xfrm: propagate extack to all netlink doit handlers Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 08/24] xfrm: add extack to verify_policy_dir Steffen Klassert
` (16 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 25 ++++++++++++++++++-------
1 file changed, 18 insertions(+), 7 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index cfa35d76fb7e..fa6024b2c88b 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1512,7 +1512,8 @@ static int verify_policy_type(u8 type)
return 0;
}
-static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
+static int verify_newpolicy_info(struct xfrm_userpolicy_info *p,
+ struct netlink_ext_ack *extack)
{
int ret;
@@ -1524,6 +1525,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
break;
default:
+ NL_SET_ERR_MSG(extack, "Invalid policy share");
return -EINVAL;
}
@@ -1533,35 +1535,44 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p)
break;
default:
+ NL_SET_ERR_MSG(extack, "Invalid policy action");
return -EINVAL;
}
switch (p->sel.family) {
case AF_INET:
- if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+ if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32) {
+ NL_SET_ERR_MSG(extack, "Invalid prefix length in selector (must be <= 32 for IPv4)");
return -EINVAL;
+ }
break;
case AF_INET6:
#if IS_ENABLED(CONFIG_IPV6)
- if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+ if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128) {
+ NL_SET_ERR_MSG(extack, "Invalid prefix length in selector (must be <= 128 for IPv6)");
return -EINVAL;
+ }
break;
#else
+ NL_SET_ERR_MSG(extack, "IPv6 support disabled");
return -EAFNOSUPPORT;
#endif
default:
+ NL_SET_ERR_MSG(extack, "Invalid selector family");
return -EINVAL;
}
ret = verify_policy_dir(p->dir);
if (ret)
return ret;
- if (p->index && (xfrm_policy_id2dir(p->index) != p->dir))
+ if (p->index && (xfrm_policy_id2dir(p->index) != p->dir)) {
+ NL_SET_ERR_MSG(extack, "Policy index doesn't match direction");
return -EINVAL;
+ }
return 0;
}
@@ -1768,7 +1779,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
int err;
int excl;
- err = verify_newpolicy_info(p);
+ err = verify_newpolicy_info(p, extack);
if (err)
return err;
err = verify_sec_ctx_len(attrs);
@@ -2501,7 +2512,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
xfrm_mark_get(attrs, &mark);
- err = verify_newpolicy_info(&ua->policy);
+ err = verify_newpolicy_info(&ua->policy, extack);
if (err)
goto free_state;
err = verify_sec_ctx_len(attrs);
@@ -3284,7 +3295,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
*dir = -EINVAL;
if (len < sizeof(*p) ||
- verify_newpolicy_info(p))
+ verify_newpolicy_info(p, NULL))
return NULL;
nr = ((len - sizeof(*p)) / sizeof(*ut));
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 08/24] xfrm: add extack to verify_policy_dir
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (6 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 07/24] xfrm: add extack support to verify_newpolicy_info Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 09/24] xfrm: add extack to verify_policy_type Steffen Klassert
` (15 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index fa6024b2c88b..0042b77337bd 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1481,7 +1481,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
}
-static int verify_policy_dir(u8 dir)
+static int verify_policy_dir(u8 dir, struct netlink_ext_ack *extack)
{
switch (dir) {
case XFRM_POLICY_IN:
@@ -1490,6 +1490,7 @@ static int verify_policy_dir(u8 dir)
break;
default:
+ NL_SET_ERR_MSG(extack, "Invalid policy direction");
return -EINVAL;
}
@@ -1566,7 +1567,7 @@ static int verify_newpolicy_info(struct xfrm_userpolicy_info *p,
return -EINVAL;
}
- ret = verify_policy_dir(p->dir);
+ ret = verify_policy_dir(p->dir, extack);
if (ret)
return ret;
if (p->index && (xfrm_policy_id2dir(p->index) != p->dir)) {
@@ -2102,7 +2103,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
return err;
- err = verify_policy_dir(p->dir);
+ err = verify_policy_dir(p->dir, extack);
if (err)
return err;
@@ -2407,7 +2408,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
return err;
- err = verify_policy_dir(p->dir);
+ err = verify_policy_dir(p->dir, extack);
if (err)
return err;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 09/24] xfrm: add extack to verify_policy_type
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (7 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 08/24] xfrm: add extack to verify_policy_dir Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 10/24] xfrm: add extack to validate_tmpl Steffen Klassert
` (14 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 28 +++++++++++++++++-----------
1 file changed, 17 insertions(+), 11 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0042b77337bd..0f2a2aa1e289 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1497,7 +1497,7 @@ static int verify_policy_dir(u8 dir, struct netlink_ext_ack *extack)
return 0;
}
-static int verify_policy_type(u8 type)
+static int verify_policy_type(u8 type, struct netlink_ext_ack *extack)
{
switch (type) {
case XFRM_POLICY_TYPE_MAIN:
@@ -1507,6 +1507,7 @@ static int verify_policy_type(u8 type)
break;
default:
+ NL_SET_ERR_MSG(extack, "Invalid policy type");
return -EINVAL;
}
@@ -1688,7 +1689,8 @@ static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs)
return 0;
}
-static int copy_from_user_policy_type(u8 *tp, struct nlattr **attrs)
+static int copy_from_user_policy_type(u8 *tp, struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_POLICY_TYPE];
struct xfrm_userpolicy_type *upt;
@@ -1700,7 +1702,7 @@ static int copy_from_user_policy_type(u8 *tp, struct nlattr **attrs)
type = upt->type;
}
- err = verify_policy_type(type);
+ err = verify_policy_type(type, extack);
if (err)
return err;
@@ -1735,7 +1737,11 @@ static void copy_to_user_policy(struct xfrm_policy *xp, struct xfrm_userpolicy_i
p->share = XFRM_SHARE_ANY; /* XXX xp->share */
}
-static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_userpolicy_info *p, struct nlattr **attrs, int *errp)
+static struct xfrm_policy *xfrm_policy_construct(struct net *net,
+ struct xfrm_userpolicy_info *p,
+ struct nlattr **attrs,
+ int *errp,
+ struct netlink_ext_ack *extack)
{
struct xfrm_policy *xp = xfrm_policy_alloc(net, GFP_KERNEL);
int err;
@@ -1747,7 +1753,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us
copy_from_user_policy(xp, p);
- err = copy_from_user_policy_type(&xp->type, attrs);
+ err = copy_from_user_policy_type(&xp->type, attrs, extack);
if (err)
goto error;
@@ -1787,7 +1793,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
return err;
- xp = xfrm_policy_construct(net, p, attrs, &err);
+ xp = xfrm_policy_construct(net, p, attrs, &err, extack);
if (!xp)
return err;
@@ -2099,7 +2105,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
p = nlmsg_data(nlh);
delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
- err = copy_from_user_policy_type(&type, attrs);
+ err = copy_from_user_policy_type(&type, attrs, extack);
if (err)
return err;
@@ -2371,7 +2377,7 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
u8 type = XFRM_POLICY_TYPE_MAIN;
int err;
- err = copy_from_user_policy_type(&type, attrs);
+ err = copy_from_user_policy_type(&type, attrs, extack);
if (err)
return err;
@@ -2404,7 +2410,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct xfrm_mark m;
u32 if_id = 0;
- err = copy_from_user_policy_type(&type, attrs);
+ err = copy_from_user_policy_type(&type, attrs, extack);
if (err)
return err;
@@ -2521,7 +2527,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
goto free_state;
/* build an XP */
- xp = xfrm_policy_construct(net, &ua->policy, attrs, &err);
+ xp = xfrm_policy_construct(net, &ua->policy, attrs, &err, extack);
if (!xp)
goto free_state;
@@ -2617,7 +2623,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
kmp = attrs[XFRMA_KMADDRESS] ? &km : NULL;
- err = copy_from_user_policy_type(&type, attrs);
+ err = copy_from_user_policy_type(&type, attrs, extack);
if (err)
return err;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 10/24] xfrm: add extack to validate_tmpl
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (8 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 09/24] xfrm: add extack to verify_policy_type Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:16 ` [PATCH 11/24] xfrm: add extack to verify_sec_ctx_len Steffen Klassert
` (13 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 29 ++++++++++++++++++++---------
1 file changed, 20 insertions(+), 9 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 0f2a2aa1e289..9fd30914f1ff 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -1616,13 +1616,16 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
}
}
-static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
+static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family,
+ struct netlink_ext_ack *extack)
{
u16 prev_family;
int i;
- if (nr > XFRM_MAX_DEPTH)
+ if (nr > XFRM_MAX_DEPTH) {
+ NL_SET_ERR_MSG(extack, "Template count must be <= XFRM_MAX_DEPTH (" __stringify(XFRM_MAX_DEPTH) ")");
return -EINVAL;
+ }
prev_family = family;
@@ -1642,12 +1645,16 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
case XFRM_MODE_BEET:
break;
default:
- if (ut[i].family != prev_family)
+ if (ut[i].family != prev_family) {
+ NL_SET_ERR_MSG(extack, "Mode in template doesn't support a family change");
return -EINVAL;
+ }
break;
}
- if (ut[i].mode >= XFRM_MODE_MAX)
+ if (ut[i].mode >= XFRM_MODE_MAX) {
+ NL_SET_ERR_MSG(extack, "Mode in template must be < XFRM_MODE_MAX (" __stringify(XFRM_MODE_MAX) ")");
return -EINVAL;
+ }
prev_family = ut[i].family;
@@ -1659,17 +1666,21 @@ static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
break;
#endif
default:
+ NL_SET_ERR_MSG(extack, "Invalid family in template");
return -EINVAL;
}
- if (!xfrm_id_proto_valid(ut[i].id.proto))
+ if (!xfrm_id_proto_valid(ut[i].id.proto)) {
+ NL_SET_ERR_MSG(extack, "Invalid XFRM protocol in template");
return -EINVAL;
+ }
}
return 0;
}
-static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs)
+static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_TMPL];
@@ -1680,7 +1691,7 @@ static int copy_from_user_tmpl(struct xfrm_policy *pol, struct nlattr **attrs)
int nr = nla_len(rt) / sizeof(*utmpl);
int err;
- err = validate_tmpl(nr, utmpl, pol->family);
+ err = validate_tmpl(nr, utmpl, pol->family, extack);
if (err)
return err;
@@ -1757,7 +1768,7 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net,
if (err)
goto error;
- if (!(err = copy_from_user_tmpl(xp, attrs)))
+ if (!(err = copy_from_user_tmpl(xp, attrs, extack)))
err = copy_from_user_sec_ctx(xp, attrs);
if (err)
goto error;
@@ -3306,7 +3317,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
return NULL;
nr = ((len - sizeof(*p)) / sizeof(*ut));
- if (validate_tmpl(nr, ut, p->sel.family))
+ if (validate_tmpl(nr, ut, p->sel.family, NULL))
return NULL;
if (p->dir > XFRM_POLICY_OUT)
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 11/24] xfrm: add extack to verify_sec_ctx_len
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (9 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 10/24] xfrm: add extack to validate_tmpl Steffen Klassert
@ 2022-10-02 8:16 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 12/24] xfrm: add extack support to verify_newsa_info Steffen Klassert
` (12 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:16 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 9fd30914f1ff..772a051feedb 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -102,7 +102,7 @@ static void verify_one_addr(struct nlattr **attrs, enum xfrm_attr_type_t type,
*addrp = nla_data(rt);
}
-static inline int verify_sec_ctx_len(struct nlattr **attrs)
+static inline int verify_sec_ctx_len(struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_SEC_CTX];
struct xfrm_user_sec_ctx *uctx;
@@ -112,8 +112,10 @@ static inline int verify_sec_ctx_len(struct nlattr **attrs)
uctx = nla_data(rt);
if (uctx->len > nla_len(rt) ||
- uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len))
+ uctx->len != (sizeof(struct xfrm_user_sec_ctx) + uctx->ctx_len)) {
+ NL_SET_ERR_MSG(extack, "Invalid security context length");
return -EINVAL;
+ }
return 0;
}
@@ -264,7 +266,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
if ((err = verify_one_alg(attrs, XFRMA_ALG_COMP)))
goto out;
- if ((err = verify_sec_ctx_len(attrs)))
+ if ((err = verify_sec_ctx_len(attrs, NULL)))
goto out;
if ((err = verify_replay(p, attrs)))
goto out;
@@ -1800,7 +1802,7 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
err = verify_newpolicy_info(p, extack);
if (err)
return err;
- err = verify_sec_ctx_len(attrs);
+ err = verify_sec_ctx_len(attrs, extack);
if (err)
return err;
@@ -2136,7 +2138,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
struct nlattr *rt = attrs[XFRMA_SEC_CTX];
struct xfrm_sec_ctx *ctx;
- err = verify_sec_ctx_len(attrs);
+ err = verify_sec_ctx_len(attrs, extack);
if (err)
return err;
@@ -2441,7 +2443,7 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
struct nlattr *rt = attrs[XFRMA_SEC_CTX];
struct xfrm_sec_ctx *ctx;
- err = verify_sec_ctx_len(attrs);
+ err = verify_sec_ctx_len(attrs, extack);
if (err)
return err;
@@ -2533,7 +2535,7 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
err = verify_newpolicy_info(&ua->policy, extack);
if (err)
goto free_state;
- err = verify_sec_ctx_len(attrs);
+ err = verify_sec_ctx_len(attrs, extack);
if (err)
goto free_state;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 12/24] xfrm: add extack support to verify_newsa_info
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (10 preceding siblings ...)
2022-10-02 8:16 ` [PATCH 11/24] xfrm: add extack to verify_sec_ctx_len Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 13/24] xfrm: add extack to verify_replay Steffen Klassert
` (11 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 90 +++++++++++++++++++++++++++++++++-----------
1 file changed, 69 insertions(+), 21 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 772a051feedb..4167c189d35b 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -149,7 +149,8 @@ static inline int verify_replay(struct xfrm_usersa_info *p,
}
static int verify_newsa_info(struct xfrm_usersa_info *p,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
int err;
@@ -163,10 +164,12 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
break;
#else
err = -EAFNOSUPPORT;
+ NL_SET_ERR_MSG(extack, "IPv6 support disabled");
goto out;
#endif
default:
+ NL_SET_ERR_MSG(extack, "Invalid address family");
goto out;
}
@@ -175,65 +178,98 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
break;
case AF_INET:
- if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32)
+ if (p->sel.prefixlen_d > 32 || p->sel.prefixlen_s > 32) {
+ NL_SET_ERR_MSG(extack, "Invalid prefix length in selector (must be <= 32 for IPv4)");
goto out;
+ }
break;
case AF_INET6:
#if IS_ENABLED(CONFIG_IPV6)
- if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128)
+ if (p->sel.prefixlen_d > 128 || p->sel.prefixlen_s > 128) {
+ NL_SET_ERR_MSG(extack, "Invalid prefix length in selector (must be <= 128 for IPv6)");
goto out;
+ }
break;
#else
+ NL_SET_ERR_MSG(extack, "IPv6 support disabled");
err = -EAFNOSUPPORT;
goto out;
#endif
default:
+ NL_SET_ERR_MSG(extack, "Invalid address family in selector");
goto out;
}
err = -EINVAL;
switch (p->id.proto) {
case IPPROTO_AH:
- if ((!attrs[XFRMA_ALG_AUTH] &&
- !attrs[XFRMA_ALG_AUTH_TRUNC]) ||
- attrs[XFRMA_ALG_AEAD] ||
+ if (!attrs[XFRMA_ALG_AUTH] &&
+ !attrs[XFRMA_ALG_AUTH_TRUNC]) {
+ NL_SET_ERR_MSG(extack, "Missing required attribute for AH: AUTH_TRUNC or AUTH");
+ goto out;
+ }
+
+ if (attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_CRYPT] ||
attrs[XFRMA_ALG_COMP] ||
- attrs[XFRMA_TFCPAD])
+ attrs[XFRMA_TFCPAD]) {
+ NL_SET_ERR_MSG(extack, "Invalid attributes for AH: AEAD, CRYPT, COMP, TFCPAD");
goto out;
+ }
break;
case IPPROTO_ESP:
- if (attrs[XFRMA_ALG_COMP])
+ if (attrs[XFRMA_ALG_COMP]) {
+ NL_SET_ERR_MSG(extack, "Invalid attribute for ESP: COMP");
goto out;
+ }
+
if (!attrs[XFRMA_ALG_AUTH] &&
!attrs[XFRMA_ALG_AUTH_TRUNC] &&
!attrs[XFRMA_ALG_CRYPT] &&
- !attrs[XFRMA_ALG_AEAD])
+ !attrs[XFRMA_ALG_AEAD]) {
+ NL_SET_ERR_MSG(extack, "Missing required attribute for ESP: at least one of AUTH, AUTH_TRUNC, CRYPT, AEAD");
goto out;
+ }
+
if ((attrs[XFRMA_ALG_AUTH] ||
attrs[XFRMA_ALG_AUTH_TRUNC] ||
attrs[XFRMA_ALG_CRYPT]) &&
- attrs[XFRMA_ALG_AEAD])
+ attrs[XFRMA_ALG_AEAD]) {
+ NL_SET_ERR_MSG(extack, "Invalid attribute combination for ESP: AEAD can't be used with AUTH, AUTH_TRUNC, CRYPT");
goto out;
+ }
+
if (attrs[XFRMA_TFCPAD] &&
- p->mode != XFRM_MODE_TUNNEL)
+ p->mode != XFRM_MODE_TUNNEL) {
+ NL_SET_ERR_MSG(extack, "TFC padding can only be used in tunnel mode");
goto out;
+ }
break;
case IPPROTO_COMP:
- if (!attrs[XFRMA_ALG_COMP] ||
- attrs[XFRMA_ALG_AEAD] ||
+ if (!attrs[XFRMA_ALG_COMP]) {
+ NL_SET_ERR_MSG(extack, "Missing required attribute for COMP: COMP");
+ goto out;
+ }
+
+ if (attrs[XFRMA_ALG_AEAD] ||
attrs[XFRMA_ALG_AUTH] ||
attrs[XFRMA_ALG_AUTH_TRUNC] ||
attrs[XFRMA_ALG_CRYPT] ||
- attrs[XFRMA_TFCPAD] ||
- (ntohl(p->id.spi) >= 0x10000))
+ attrs[XFRMA_TFCPAD]) {
+ NL_SET_ERR_MSG(extack, "Invalid attributes for COMP: AEAD, AUTH, AUTH_TRUNC, CRYPT, TFCPAD");
+ goto out;
+ }
+
+ if (ntohl(p->id.spi) >= 0x10000) {
+ NL_SET_ERR_MSG(extack, "SPI is too large for COMP (must be < 0x10000)");
goto out;
+ }
break;
#if IS_ENABLED(CONFIG_IPV6)
@@ -246,13 +282,20 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
attrs[XFRMA_ALG_CRYPT] ||
attrs[XFRMA_ENCAP] ||
attrs[XFRMA_SEC_CTX] ||
- attrs[XFRMA_TFCPAD] ||
- !attrs[XFRMA_COADDR])
+ attrs[XFRMA_TFCPAD]) {
+ NL_SET_ERR_MSG(extack, "Invalid attributes for DSTOPTS/ROUTING");
+ goto out;
+ }
+
+ if (!attrs[XFRMA_COADDR]) {
+ NL_SET_ERR_MSG(extack, "Missing required COADDR attribute for DSTOPTS/ROUTING");
goto out;
+ }
break;
#endif
default:
+ NL_SET_ERR_MSG(extack, "Unsupported protocol");
goto out;
}
@@ -266,7 +309,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
if ((err = verify_one_alg(attrs, XFRMA_ALG_COMP)))
goto out;
- if ((err = verify_sec_ctx_len(attrs, NULL)))
+ if ((err = verify_sec_ctx_len(attrs, extack)))
goto out;
if ((err = verify_replay(p, attrs)))
goto out;
@@ -280,14 +323,19 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
break;
default:
+ NL_SET_ERR_MSG(extack, "Unsupported mode");
goto out;
}
err = 0;
- if (attrs[XFRMA_MTIMER_THRESH])
- if (!attrs[XFRMA_ENCAP])
+ if (attrs[XFRMA_MTIMER_THRESH]) {
+ if (!attrs[XFRMA_ENCAP]) {
+ NL_SET_ERR_MSG(extack, "MTIMER_THRESH attribute can only be set on ENCAP states");
err = -EINVAL;
+ goto out;
+ }
+ }
out:
return err;
@@ -688,7 +736,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
int err;
struct km_event c;
- err = verify_newsa_info(p, attrs);
+ err = verify_newsa_info(p, attrs, extack);
if (err)
return err;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 13/24] xfrm: add extack to verify_replay
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (11 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 12/24] xfrm: add extack support to verify_newsa_info Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 14/24] xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead Steffen Klassert
` (10 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 30 ++++++++++++++++++++++--------
1 file changed, 22 insertions(+), 8 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 4167c189d35b..048c1e150b4e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -121,29 +121,43 @@ static inline int verify_sec_ctx_len(struct nlattr **attrs, struct netlink_ext_a
}
static inline int verify_replay(struct xfrm_usersa_info *p,
- struct nlattr **attrs)
+ struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_REPLAY_ESN_VAL];
struct xfrm_replay_state_esn *rs;
- if (!rt)
- return (p->flags & XFRM_STATE_ESN) ? -EINVAL : 0;
+ if (!rt) {
+ if (p->flags & XFRM_STATE_ESN) {
+ NL_SET_ERR_MSG(extack, "Missing required attribute for ESN");
+ return -EINVAL;
+ }
+ return 0;
+ }
rs = nla_data(rt);
- if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8)
+ if (rs->bmp_len > XFRMA_REPLAY_ESN_MAX / sizeof(rs->bmp[0]) / 8) {
+ NL_SET_ERR_MSG(extack, "ESN bitmap length must be <= 128");
return -EINVAL;
+ }
if (nla_len(rt) < (int)xfrm_replay_state_esn_len(rs) &&
- nla_len(rt) != sizeof(*rs))
+ nla_len(rt) != sizeof(*rs)) {
+ NL_SET_ERR_MSG(extack, "ESN attribute is too short to fit the full bitmap length");
return -EINVAL;
+ }
/* As only ESP and AH support ESN feature. */
- if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH))
+ if ((p->id.proto != IPPROTO_ESP) && (p->id.proto != IPPROTO_AH)) {
+ NL_SET_ERR_MSG(extack, "ESN only supported for ESP and AH");
return -EINVAL;
+ }
- if (p->replay_window != 0)
+ if (p->replay_window != 0) {
+ NL_SET_ERR_MSG(extack, "ESN not compatible with legacy replay_window");
return -EINVAL;
+ }
return 0;
}
@@ -311,7 +325,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
if ((err = verify_sec_ctx_len(attrs, extack)))
goto out;
- if ((err = verify_replay(p, attrs)))
+ if ((err = verify_replay(p, attrs, extack)))
goto out;
err = -EINVAL;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 14/24] xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (12 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 13/24] xfrm: add extack to verify_replay Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 15/24] xfrm: add extack support to xfrm_dev_state_add Steffen Klassert
` (9 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 31 ++++++++++++++++++++-----------
1 file changed, 20 insertions(+), 11 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 048c1e150b4e..3c150e1f8a2a 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -35,7 +35,8 @@
#endif
#include <asm/unaligned.h>
-static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
+static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type,
+ struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[type];
struct xfrm_algo *algp;
@@ -44,8 +45,10 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
return 0;
algp = nla_data(rt);
- if (nla_len(rt) < (int)xfrm_alg_len(algp))
+ if (nla_len(rt) < (int)xfrm_alg_len(algp)) {
+ NL_SET_ERR_MSG(extack, "Invalid AUTH/CRYPT/COMP attribute length");
return -EINVAL;
+ }
switch (type) {
case XFRMA_ALG_AUTH:
@@ -54,6 +57,7 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
break;
default:
+ NL_SET_ERR_MSG(extack, "Invalid algorithm attribute type");
return -EINVAL;
}
@@ -61,7 +65,8 @@ static int verify_one_alg(struct nlattr **attrs, enum xfrm_attr_type_t type)
return 0;
}
-static int verify_auth_trunc(struct nlattr **attrs)
+static int verify_auth_trunc(struct nlattr **attrs,
+ struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_ALG_AUTH_TRUNC];
struct xfrm_algo_auth *algp;
@@ -70,14 +75,16 @@ static int verify_auth_trunc(struct nlattr **attrs)
return 0;
algp = nla_data(rt);
- if (nla_len(rt) < (int)xfrm_alg_auth_len(algp))
+ if (nla_len(rt) < (int)xfrm_alg_auth_len(algp)) {
+ NL_SET_ERR_MSG(extack, "Invalid AUTH_TRUNC attribute length");
return -EINVAL;
+ }
algp->alg_name[sizeof(algp->alg_name) - 1] = '\0';
return 0;
}
-static int verify_aead(struct nlattr **attrs)
+static int verify_aead(struct nlattr **attrs, struct netlink_ext_ack *extack)
{
struct nlattr *rt = attrs[XFRMA_ALG_AEAD];
struct xfrm_algo_aead *algp;
@@ -86,8 +93,10 @@ static int verify_aead(struct nlattr **attrs)
return 0;
algp = nla_data(rt);
- if (nla_len(rt) < (int)aead_len(algp))
+ if (nla_len(rt) < (int)aead_len(algp)) {
+ NL_SET_ERR_MSG(extack, "Invalid AEAD attribute length");
return -EINVAL;
+ }
algp->alg_name[sizeof(algp->alg_name) - 1] = '\0';
return 0;
@@ -313,15 +322,15 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
goto out;
}
- if ((err = verify_aead(attrs)))
+ if ((err = verify_aead(attrs, extack)))
goto out;
- if ((err = verify_auth_trunc(attrs)))
+ if ((err = verify_auth_trunc(attrs, extack)))
goto out;
- if ((err = verify_one_alg(attrs, XFRMA_ALG_AUTH)))
+ if ((err = verify_one_alg(attrs, XFRMA_ALG_AUTH, extack)))
goto out;
- if ((err = verify_one_alg(attrs, XFRMA_ALG_CRYPT)))
+ if ((err = verify_one_alg(attrs, XFRMA_ALG_CRYPT, extack)))
goto out;
- if ((err = verify_one_alg(attrs, XFRMA_ALG_COMP)))
+ if ((err = verify_one_alg(attrs, XFRMA_ALG_COMP, extack)))
goto out;
if ((err = verify_sec_ctx_len(attrs, extack)))
goto out;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 15/24] xfrm: add extack support to xfrm_dev_state_add
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (13 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 14/24] xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 16/24] xfrm: add extack to attach_* Steffen Klassert
` (8 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/xfrm.h | 5 +++--
net/xfrm/xfrm_device.c | 20 +++++++++++++++-----
net/xfrm/xfrm_user.c | 8 +++++---
3 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 28b988577ed2..9c1cccf85f12 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1886,7 +1886,8 @@ void xfrm_dev_resume(struct sk_buff *skb);
void xfrm_dev_backlog(struct softnet_data *sd);
struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t features, bool *again);
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
- struct xfrm_user_offload *xuo);
+ struct xfrm_user_offload *xuo,
+ struct netlink_ext_ack *extack);
bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x);
static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x)
@@ -1949,7 +1950,7 @@ static inline struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_fea
return skb;
}
-static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo)
+static inline int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, struct xfrm_user_offload *xuo, struct netlink_ext_ack *extack)
{
return 0;
}
diff --git a/net/xfrm/xfrm_device.c b/net/xfrm/xfrm_device.c
index 637ca8838436..5f5aafd418af 100644
--- a/net/xfrm/xfrm_device.c
+++ b/net/xfrm/xfrm_device.c
@@ -207,7 +207,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur
EXPORT_SYMBOL_GPL(validate_xmit_xfrm);
int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
- struct xfrm_user_offload *xuo)
+ struct xfrm_user_offload *xuo,
+ struct netlink_ext_ack *extack)
{
int err;
struct dst_entry *dst;
@@ -216,15 +217,21 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
xfrm_address_t *saddr;
xfrm_address_t *daddr;
- if (!x->type_offload)
+ if (!x->type_offload) {
+ NL_SET_ERR_MSG(extack, "Type doesn't support offload");
return -EINVAL;
+ }
/* We don't yet support UDP encapsulation and TFC padding. */
- if (x->encap || x->tfcpad)
+ if (x->encap || x->tfcpad) {
+ NL_SET_ERR_MSG(extack, "Encapsulation and TFC padding can't be offloaded");
return -EINVAL;
+ }
- if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND))
+ if (xuo->flags & ~(XFRM_OFFLOAD_IPV6 | XFRM_OFFLOAD_INBOUND)) {
+ NL_SET_ERR_MSG(extack, "Unrecognized flags in offload request");
return -EINVAL;
+ }
dev = dev_get_by_index(net, xuo->ifindex);
if (!dev) {
@@ -256,6 +263,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
if (x->props.flags & XFRM_STATE_ESN &&
!dev->xfrmdev_ops->xdo_dev_state_advance_esn) {
+ NL_SET_ERR_MSG(extack, "Device doesn't support offload with ESN");
xso->dev = NULL;
dev_put(dev);
return -EINVAL;
@@ -277,8 +285,10 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x,
xso->real_dev = NULL;
netdev_put(dev, &xso->dev_tracker);
- if (err != -EOPNOTSUPP)
+ if (err != -EOPNOTSUPP) {
+ NL_SET_ERR_MSG(extack, "Device failed to offload this state");
return err;
+ }
}
return 0;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 3c150e1f8a2a..c56b9442dffe 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -652,7 +652,8 @@ static void xfrm_smark_init(struct nlattr **attrs, struct xfrm_mark *m)
static struct xfrm_state *xfrm_state_construct(struct net *net,
struct xfrm_usersa_info *p,
struct nlattr **attrs,
- int *errp)
+ int *errp,
+ struct netlink_ext_ack *extack)
{
struct xfrm_state *x = xfrm_state_alloc(net);
int err = -ENOMEM;
@@ -735,7 +736,8 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
/* configure the hardware if offload is requested */
if (attrs[XFRMA_OFFLOAD_DEV]) {
err = xfrm_dev_state_add(net, x,
- nla_data(attrs[XFRMA_OFFLOAD_DEV]));
+ nla_data(attrs[XFRMA_OFFLOAD_DEV]),
+ extack);
if (err)
goto error;
}
@@ -763,7 +765,7 @@ static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
if (err)
return err;
- x = xfrm_state_construct(net, p, attrs, &err);
+ x = xfrm_state_construct(net, p, attrs, &err, extack);
if (!x)
return err;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 16/24] xfrm: add extack to attach_*
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (14 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 15/24] xfrm: add extack support to xfrm_dev_state_add Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 17/24] xfrm: add extack to __xfrm_init_state Steffen Klassert
` (7 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/xfrm/xfrm_user.c | 46 +++++++++++++++++++++++++++++---------------
1 file changed, 30 insertions(+), 16 deletions(-)
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index c56b9442dffe..2cf5956b562e 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -366,7 +366,7 @@ static int verify_newsa_info(struct xfrm_usersa_info *p,
static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
struct xfrm_algo_desc *(*get_byname)(const char *, int),
- struct nlattr *rta)
+ struct nlattr *rta, struct netlink_ext_ack *extack)
{
struct xfrm_algo *p, *ualg;
struct xfrm_algo_desc *algo;
@@ -377,8 +377,10 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
ualg = nla_data(rta);
algo = get_byname(ualg->alg_name, 1);
- if (!algo)
+ if (!algo) {
+ NL_SET_ERR_MSG(extack, "Requested COMP algorithm not found");
return -ENOSYS;
+ }
*props = algo->desc.sadb_alg_id;
p = kmemdup(ualg, xfrm_alg_len(ualg), GFP_KERNEL);
@@ -390,7 +392,8 @@ static int attach_one_algo(struct xfrm_algo **algpp, u8 *props,
return 0;
}
-static int attach_crypt(struct xfrm_state *x, struct nlattr *rta)
+static int attach_crypt(struct xfrm_state *x, struct nlattr *rta,
+ struct netlink_ext_ack *extack)
{
struct xfrm_algo *p, *ualg;
struct xfrm_algo_desc *algo;
@@ -401,8 +404,10 @@ static int attach_crypt(struct xfrm_state *x, struct nlattr *rta)
ualg = nla_data(rta);
algo = xfrm_ealg_get_byname(ualg->alg_name, 1);
- if (!algo)
+ if (!algo) {
+ NL_SET_ERR_MSG(extack, "Requested CRYPT algorithm not found");
return -ENOSYS;
+ }
x->props.ealgo = algo->desc.sadb_alg_id;
p = kmemdup(ualg, xfrm_alg_len(ualg), GFP_KERNEL);
@@ -416,7 +421,7 @@ static int attach_crypt(struct xfrm_state *x, struct nlattr *rta)
}
static int attach_auth(struct xfrm_algo_auth **algpp, u8 *props,
- struct nlattr *rta)
+ struct nlattr *rta, struct netlink_ext_ack *extack)
{
struct xfrm_algo *ualg;
struct xfrm_algo_auth *p;
@@ -428,8 +433,10 @@ static int attach_auth(struct xfrm_algo_auth **algpp, u8 *props,
ualg = nla_data(rta);
algo = xfrm_aalg_get_byname(ualg->alg_name, 1);
- if (!algo)
+ if (!algo) {
+ NL_SET_ERR_MSG(extack, "Requested AUTH algorithm not found");
return -ENOSYS;
+ }
*props = algo->desc.sadb_alg_id;
p = kmalloc(sizeof(*p) + (ualg->alg_key_len + 7) / 8, GFP_KERNEL);
@@ -446,7 +453,7 @@ static int attach_auth(struct xfrm_algo_auth **algpp, u8 *props,
}
static int attach_auth_trunc(struct xfrm_algo_auth **algpp, u8 *props,
- struct nlattr *rta)
+ struct nlattr *rta, struct netlink_ext_ack *extack)
{
struct xfrm_algo_auth *p, *ualg;
struct xfrm_algo_desc *algo;
@@ -457,10 +464,14 @@ static int attach_auth_trunc(struct xfrm_algo_auth **algpp, u8 *props,
ualg = nla_data(rta);
algo = xfrm_aalg_get_byname(ualg->alg_name, 1);
- if (!algo)
+ if (!algo) {
+ NL_SET_ERR_MSG(extack, "Requested AUTH_TRUNC algorithm not found");
return -ENOSYS;
- if (ualg->alg_trunc_len > algo->uinfo.auth.icv_fullbits)
+ }
+ if (ualg->alg_trunc_len > algo->uinfo.auth.icv_fullbits) {
+ NL_SET_ERR_MSG(extack, "Invalid length requested for truncated ICV");
return -EINVAL;
+ }
*props = algo->desc.sadb_alg_id;
p = kmemdup(ualg, xfrm_alg_auth_len(ualg), GFP_KERNEL);
@@ -475,7 +486,8 @@ static int attach_auth_trunc(struct xfrm_algo_auth **algpp, u8 *props,
return 0;
}
-static int attach_aead(struct xfrm_state *x, struct nlattr *rta)
+static int attach_aead(struct xfrm_state *x, struct nlattr *rta,
+ struct netlink_ext_ack *extack)
{
struct xfrm_algo_aead *p, *ualg;
struct xfrm_algo_desc *algo;
@@ -486,8 +498,10 @@ static int attach_aead(struct xfrm_state *x, struct nlattr *rta)
ualg = nla_data(rta);
algo = xfrm_aead_get_byname(ualg->alg_name, ualg->alg_icv_len, 1);
- if (!algo)
+ if (!algo) {
+ NL_SET_ERR_MSG(extack, "Requested AEAD algorithm not found");
return -ENOSYS;
+ }
x->props.ealgo = algo->desc.sadb_alg_id;
p = kmemdup(ualg, aead_len(ualg), GFP_KERNEL);
@@ -680,21 +694,21 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
if (attrs[XFRMA_SA_EXTRA_FLAGS])
x->props.extra_flags = nla_get_u32(attrs[XFRMA_SA_EXTRA_FLAGS]);
- if ((err = attach_aead(x, attrs[XFRMA_ALG_AEAD])))
+ if ((err = attach_aead(x, attrs[XFRMA_ALG_AEAD], extack)))
goto error;
if ((err = attach_auth_trunc(&x->aalg, &x->props.aalgo,
- attrs[XFRMA_ALG_AUTH_TRUNC])))
+ attrs[XFRMA_ALG_AUTH_TRUNC], extack)))
goto error;
if (!x->props.aalgo) {
if ((err = attach_auth(&x->aalg, &x->props.aalgo,
- attrs[XFRMA_ALG_AUTH])))
+ attrs[XFRMA_ALG_AUTH], extack)))
goto error;
}
- if ((err = attach_crypt(x, attrs[XFRMA_ALG_CRYPT])))
+ if ((err = attach_crypt(x, attrs[XFRMA_ALG_CRYPT], extack)))
goto error;
if ((err = attach_one_algo(&x->calg, &x->props.calgo,
xfrm_calg_get_byname,
- attrs[XFRMA_ALG_COMP])))
+ attrs[XFRMA_ALG_COMP], extack)))
goto error;
if (attrs[XFRMA_TFCPAD])
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 17/24] xfrm: add extack to __xfrm_init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (15 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 16/24] xfrm: add extack to attach_* Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 18/24] xfrm: add extack support to xfrm_init_replay Steffen Klassert
` (6 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/xfrm.h | 3 ++-
net/xfrm/xfrm_state.c | 26 +++++++++++++++++++-------
net/xfrm/xfrm_user.c | 2 +-
3 files changed, 22 insertions(+), 9 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 9c1cccf85f12..f427a74d571b 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1582,7 +1582,8 @@ void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
int xfrm_init_replay(struct xfrm_state *x);
u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
-int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload);
+int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
+ struct netlink_ext_ack *extack);
int xfrm_init_state(struct xfrm_state *x);
int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type);
int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 52e60e607f8a..7470d2474796 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2610,7 +2610,8 @@ u32 xfrm_state_mtu(struct xfrm_state *x, int mtu)
}
EXPORT_SYMBOL_GPL(xfrm_state_mtu);
-int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
+int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
+ struct netlink_ext_ack *extack)
{
const struct xfrm_mode *inner_mode;
const struct xfrm_mode *outer_mode;
@@ -2625,12 +2626,16 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
if (x->sel.family != AF_UNSPEC) {
inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
- if (inner_mode == NULL)
+ if (inner_mode == NULL) {
+ NL_SET_ERR_MSG(extack, "Requested mode not found");
goto error;
+ }
if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
- family != x->sel.family)
+ family != x->sel.family) {
+ NL_SET_ERR_MSG(extack, "Only tunnel modes can accommodate a change of family");
goto error;
+ }
x->inner_mode = *inner_mode;
} else {
@@ -2638,11 +2643,15 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
int iafamily = AF_INET;
inner_mode = xfrm_get_mode(x->props.mode, x->props.family);
- if (inner_mode == NULL)
+ if (inner_mode == NULL) {
+ NL_SET_ERR_MSG(extack, "Requested mode not found");
goto error;
+ }
- if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL))
+ if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) {
+ NL_SET_ERR_MSG(extack, "Only tunnel modes can accommodate an AF_UNSPEC selector");
goto error;
+ }
x->inner_mode = *inner_mode;
@@ -2657,8 +2666,10 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
}
x->type = xfrm_get_type(x->id.proto, family);
- if (x->type == NULL)
+ if (x->type == NULL) {
+ NL_SET_ERR_MSG(extack, "Requested type not found");
goto error;
+ }
x->type_offload = xfrm_get_type_offload(x->id.proto, family, offload);
@@ -2668,6 +2679,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload)
outer_mode = xfrm_get_mode(x->props.mode, family);
if (!outer_mode) {
+ NL_SET_ERR_MSG(extack, "Requested mode not found");
err = -EPROTONOSUPPORT;
goto error;
}
@@ -2689,7 +2701,7 @@ int xfrm_init_state(struct xfrm_state *x)
{
int err;
- err = __xfrm_init_state(x, true, false);
+ err = __xfrm_init_state(x, true, false, NULL);
if (!err)
x->km.state = XFRM_STATE_VALID;
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 2cf5956b562e..14e9b84f9dad 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -721,7 +721,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
if (attrs[XFRMA_IF_ID])
x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
- err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]);
+ err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV], extack);
if (err)
goto error;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 18/24] xfrm: add extack support to xfrm_init_replay
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (16 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 17/24] xfrm: add extack to __xfrm_init_state Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 19/24] xfrm: pass extack down to xfrm_type ->init_state Steffen Klassert
` (5 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/xfrm.h | 2 +-
net/xfrm/xfrm_replay.c | 10 +++++++---
net/xfrm/xfrm_state.c | 2 +-
net/xfrm/xfrm_user.c | 2 +-
4 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index f427a74d571b..c504d07bcb7c 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -1580,7 +1580,7 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali
void xfrm_sad_getinfo(struct net *net, struct xfrmk_sadinfo *si);
void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);
u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);
-int xfrm_init_replay(struct xfrm_state *x);
+int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack);
u32 xfrm_state_mtu(struct xfrm_state *x, int mtu);
int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
struct netlink_ext_ack *extack);
diff --git a/net/xfrm/xfrm_replay.c b/net/xfrm/xfrm_replay.c
index 9277d81b344c..9f4d42eb090f 100644
--- a/net/xfrm/xfrm_replay.c
+++ b/net/xfrm/xfrm_replay.c
@@ -766,18 +766,22 @@ int xfrm_replay_overflow(struct xfrm_state *x, struct sk_buff *skb)
}
#endif
-int xfrm_init_replay(struct xfrm_state *x)
+int xfrm_init_replay(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
struct xfrm_replay_state_esn *replay_esn = x->replay_esn;
if (replay_esn) {
if (replay_esn->replay_window >
- replay_esn->bmp_len * sizeof(__u32) * 8)
+ replay_esn->bmp_len * sizeof(__u32) * 8) {
+ NL_SET_ERR_MSG(extack, "ESN replay window is too large for the chosen bitmap size");
return -EINVAL;
+ }
if (x->props.flags & XFRM_STATE_ESN) {
- if (replay_esn->replay_window == 0)
+ if (replay_esn->replay_window == 0) {
+ NL_SET_ERR_MSG(extack, "ESN replay window must be > 0");
return -EINVAL;
+ }
x->repl_mode = XFRM_REPLAY_MODE_ESN;
} else {
x->repl_mode = XFRM_REPLAY_MODE_BMP;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 7470d2474796..0b59ff7985e6 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2686,7 +2686,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
x->outer_mode = *outer_mode;
if (init_replay) {
- err = xfrm_init_replay(x);
+ err = xfrm_init_replay(x, extack);
if (err)
goto error;
}
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 14e9b84f9dad..e73f9efc54c1 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -741,7 +741,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,
/* sysctl_xfrm_aevent_etime is in 100ms units */
x->replay_maxage = (net->xfrm.sysctl_aevent_etime*HZ)/XFRM_AE_ETH_M;
- if ((err = xfrm_init_replay(x)))
+ if ((err = xfrm_init_replay(x, extack)))
goto error;
/* override default values from above */
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 19/24] xfrm: pass extack down to xfrm_type ->init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (17 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 18/24] xfrm: add extack support to xfrm_init_replay Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 20/24] xfrm: ah: add extack to ah_init_state, ah6_init_state Steffen Klassert
` (4 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/xfrm.h | 3 ++-
net/ipv4/ah4.c | 2 +-
net/ipv4/esp4.c | 2 +-
net/ipv4/ipcomp.c | 3 ++-
net/ipv4/xfrm4_tunnel.c | 2 +-
net/ipv6/ah6.c | 2 +-
net/ipv6/esp6.c | 2 +-
net/ipv6/ipcomp6.c | 3 ++-
net/ipv6/mip6.c | 4 ++--
net/ipv6/xfrm6_tunnel.c | 2 +-
net/xfrm/xfrm_state.c | 2 +-
11 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index c504d07bcb7c..dbc81f5eb553 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -405,7 +405,8 @@ struct xfrm_type {
#define XFRM_TYPE_LOCAL_COADDR 4
#define XFRM_TYPE_REMOTE_COADDR 8
- int (*init_state)(struct xfrm_state *x);
+ int (*init_state)(struct xfrm_state *x,
+ struct netlink_ext_ack *extack);
void (*destructor)(struct xfrm_state *);
int (*input)(struct xfrm_state *, struct sk_buff *skb);
int (*output)(struct xfrm_state *, struct sk_buff *pskb);
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index f8ad04470d3a..babefff15de3 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -471,7 +471,7 @@ static int ah4_err(struct sk_buff *skb, u32 info)
return 0;
}
-static int ah_init_state(struct xfrm_state *x)
+static int ah_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
struct ah_data *ahp = NULL;
struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index 5c03eba787e5..bc2b2c5717b5 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -1131,7 +1131,7 @@ static int esp_init_authenc(struct xfrm_state *x)
return err;
}
-static int esp_init_state(struct xfrm_state *x)
+static int esp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
struct crypto_aead *aead;
u32 align;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 366094c1ce6c..230d1120874f 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -117,7 +117,8 @@ static int ipcomp_tunnel_attach(struct xfrm_state *x)
return err;
}
-static int ipcomp4_init_state(struct xfrm_state *x)
+static int ipcomp4_init_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
int err = -EINVAL;
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 9d4f418f1bf8..08826e0d7962 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -22,7 +22,7 @@ static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
return ip_hdr(skb)->protocol;
}
-static int ipip_init_state(struct xfrm_state *x)
+static int ipip_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
if (x->props.mode != XFRM_MODE_TUNNEL)
return -EINVAL;
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index b5995c1f4d7a..f5bc0d4b37ad 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -666,7 +666,7 @@ static int ah6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return 0;
}
-static int ah6_init_state(struct xfrm_state *x)
+static int ah6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
struct ah_data *ahp = NULL;
struct xfrm_algo_desc *aalg_desc;
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 8220923a12f7..2ca9b7b7e500 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -1174,7 +1174,7 @@ static int esp_init_authenc(struct xfrm_state *x)
return err;
}
-static int esp6_init_state(struct xfrm_state *x)
+static int esp6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
struct crypto_aead *aead;
u32 align;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 15f984be3570..7e47009739e9 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -136,7 +136,8 @@ static int ipcomp6_tunnel_attach(struct xfrm_state *x)
return err;
}
-static int ipcomp6_init_state(struct xfrm_state *x)
+static int ipcomp6_init_state(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
int err = -EINVAL;
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index aeb35d26e474..3d87ae88ebfd 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -247,7 +247,7 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
return err;
}
-static int mip6_destopt_init_state(struct xfrm_state *x)
+static int mip6_destopt_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
if (x->id.spi) {
pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi);
@@ -333,7 +333,7 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
return 0;
}
-static int mip6_rthdr_init_state(struct xfrm_state *x)
+static int mip6_rthdr_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
if (x->id.spi) {
pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index 2b31112c0856..dda44b0671ac 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -270,7 +270,7 @@ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
return 0;
}
-static int xfrm6_tunnel_init_state(struct xfrm_state *x)
+static int xfrm6_tunnel_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
if (x->props.mode != XFRM_MODE_TUNNEL)
return -EINVAL;
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 0b59ff7985e6..82c571d07836 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -2673,7 +2673,7 @@ int __xfrm_init_state(struct xfrm_state *x, bool init_replay, bool offload,
x->type_offload = xfrm_get_type_offload(x->id.proto, family, offload);
- err = x->type->init_state(x);
+ err = x->type->init_state(x, extack);
if (err)
goto error;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 20/24] xfrm: ah: add extack to ah_init_state, ah6_init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (18 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 19/24] xfrm: pass extack down to xfrm_type ->init_state Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 21/24] xfrm: esp: add extack to esp_init_state, esp6_init_state Steffen Klassert
` (3 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/ipv4/ah4.c | 21 +++++++++++++--------
net/ipv6/ah6.c | 21 ++++++++++++++-------
2 files changed, 27 insertions(+), 15 deletions(-)
diff --git a/net/ipv4/ah4.c b/net/ipv4/ah4.c
index babefff15de3..ee4e578c7f20 100644
--- a/net/ipv4/ah4.c
+++ b/net/ipv4/ah4.c
@@ -477,24 +477,32 @@ static int ah_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
struct xfrm_algo_desc *aalg_desc;
struct crypto_ahash *ahash;
- if (!x->aalg)
+ if (!x->aalg) {
+ NL_SET_ERR_MSG(extack, "AH requires a state with an AUTH algorithm");
goto error;
+ }
- if (x->encap)
+ if (x->encap) {
+ NL_SET_ERR_MSG(extack, "AH is not compatible with encapsulation");
goto error;
+ }
ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);
if (!ahp)
return -ENOMEM;
ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);
- if (IS_ERR(ahash))
+ if (IS_ERR(ahash)) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
+ }
ahp->ahash = ahash;
if (crypto_ahash_setkey(ahash, x->aalg->alg_key,
- (x->aalg->alg_key_len + 7) / 8))
+ (x->aalg->alg_key_len + 7) / 8)) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
+ }
/*
* Lookup the algorithm description maintained by xfrm_algo,
@@ -507,10 +515,7 @@ static int ah_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
crypto_ahash_digestsize(ahash)) {
- pr_info("%s: %s digestsize %u != %u\n",
- __func__, x->aalg->alg_name,
- crypto_ahash_digestsize(ahash),
- aalg_desc->uinfo.auth.icv_fullbits / 8);
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
}
diff --git a/net/ipv6/ah6.c b/net/ipv6/ah6.c
index f5bc0d4b37ad..5228d2716289 100644
--- a/net/ipv6/ah6.c
+++ b/net/ipv6/ah6.c
@@ -672,24 +672,32 @@ static int ah6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
struct xfrm_algo_desc *aalg_desc;
struct crypto_ahash *ahash;
- if (!x->aalg)
+ if (!x->aalg) {
+ NL_SET_ERR_MSG(extack, "AH requires a state with an AUTH algorithm");
goto error;
+ }
- if (x->encap)
+ if (x->encap) {
+ NL_SET_ERR_MSG(extack, "AH is not compatible with encapsulation");
goto error;
+ }
ahp = kzalloc(sizeof(*ahp), GFP_KERNEL);
if (!ahp)
return -ENOMEM;
ahash = crypto_alloc_ahash(x->aalg->alg_name, 0, 0);
- if (IS_ERR(ahash))
+ if (IS_ERR(ahash)) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
+ }
ahp->ahash = ahash;
if (crypto_ahash_setkey(ahash, x->aalg->alg_key,
- (x->aalg->alg_key_len + 7) / 8))
+ (x->aalg->alg_key_len + 7) / 8)) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
+ }
/*
* Lookup the algorithm description maintained by xfrm_algo,
@@ -702,9 +710,7 @@ static int ah6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
if (aalg_desc->uinfo.auth.icv_fullbits/8 !=
crypto_ahash_digestsize(ahash)) {
- pr_info("AH: %s digestsize %u != %u\n",
- x->aalg->alg_name, crypto_ahash_digestsize(ahash),
- aalg_desc->uinfo.auth.icv_fullbits/8);
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
}
@@ -721,6 +727,7 @@ static int ah6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
x->props.header_len += sizeof(struct ipv6hdr);
break;
default:
+ NL_SET_ERR_MSG(extack, "Invalid mode requested for AH, must be one of TRANSPORT, TUNNEL, BEET");
goto error;
}
x->data = ahp;
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 21/24] xfrm: esp: add extack to esp_init_state, esp6_init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (19 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 20/24] xfrm: ah: add extack to ah_init_state, ah6_init_state Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 22/24] xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state Steffen Klassert
` (2 subsequent siblings)
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/ipv4/esp4.c | 53 +++++++++++++++++++++++++++++--------------------
net/ipv6/esp6.c | 53 +++++++++++++++++++++++++++++--------------------
2 files changed, 64 insertions(+), 42 deletions(-)
diff --git a/net/ipv4/esp4.c b/net/ipv4/esp4.c
index bc2b2c5717b5..751a05276f48 100644
--- a/net/ipv4/esp4.c
+++ b/net/ipv4/esp4.c
@@ -1007,16 +1007,17 @@ static void esp_destroy(struct xfrm_state *x)
crypto_free_aead(aead);
}
-static int esp_init_aead(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
char aead_name[CRYPTO_MAX_ALG_NAME];
struct crypto_aead *aead;
int err;
- err = -ENAMETOOLONG;
if (snprintf(aead_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
- x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME)
- goto error;
+ x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME) {
+ NL_SET_ERR_MSG(extack, "Algorithm name is too long");
+ return -ENAMETOOLONG;
+ }
aead = crypto_alloc_aead(aead_name, 0, 0);
err = PTR_ERR(aead);
@@ -1034,11 +1035,15 @@ static int esp_init_aead(struct xfrm_state *x)
if (err)
goto error;
+ return 0;
+
error:
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
return err;
}
-static int esp_init_authenc(struct xfrm_state *x)
+static int esp_init_authenc(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
struct crypto_aead *aead;
struct crypto_authenc_key_param *param;
@@ -1049,10 +1054,6 @@ static int esp_init_authenc(struct xfrm_state *x)
unsigned int keylen;
int err;
- err = -EINVAL;
- if (!x->ealg)
- goto error;
-
err = -ENAMETOOLONG;
if ((x->props.flags & XFRM_STATE_ESN)) {
@@ -1061,22 +1062,28 @@ static int esp_init_authenc(struct xfrm_state *x)
x->geniv ?: "", x->geniv ? "(" : "",
x->aalg ? x->aalg->alg_name : "digest_null",
x->ealg->alg_name,
- x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME)
+ x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) {
+ NL_SET_ERR_MSG(extack, "Algorithm name is too long");
goto error;
+ }
} else {
if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME,
"%s%sauthenc(%s,%s)%s",
x->geniv ?: "", x->geniv ? "(" : "",
x->aalg ? x->aalg->alg_name : "digest_null",
x->ealg->alg_name,
- x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME)
+ x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) {
+ NL_SET_ERR_MSG(extack, "Algorithm name is too long");
goto error;
+ }
}
aead = crypto_alloc_aead(authenc_name, 0, 0);
err = PTR_ERR(aead);
- if (IS_ERR(aead))
+ if (IS_ERR(aead)) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
+ }
x->data = aead;
@@ -1106,17 +1113,16 @@ static int esp_init_authenc(struct xfrm_state *x)
err = -EINVAL;
if (aalg_desc->uinfo.auth.icv_fullbits / 8 !=
crypto_aead_authsize(aead)) {
- pr_info("ESP: %s digestsize %u != %u\n",
- x->aalg->alg_name,
- crypto_aead_authsize(aead),
- aalg_desc->uinfo.auth.icv_fullbits / 8);
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto free_key;
}
err = crypto_aead_setauthsize(
aead, x->aalg->alg_trunc_len / 8);
- if (err)
+ if (err) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto free_key;
+ }
}
param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
@@ -1139,10 +1145,14 @@ static int esp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
x->data = NULL;
- if (x->aead)
- err = esp_init_aead(x);
- else
- err = esp_init_authenc(x);
+ if (x->aead) {
+ err = esp_init_aead(x, extack);
+ } else if (x->ealg) {
+ err = esp_init_authenc(x, extack);
+ } else {
+ NL_SET_ERR_MSG(extack, "ESP: AEAD or CRYPT must be provided");
+ err = -EINVAL;
+ }
if (err)
goto error;
@@ -1160,6 +1170,7 @@ static int esp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
switch (encap->encap_type) {
default:
+ NL_SET_ERR_MSG(extack, "Unsupported encapsulation type for ESP");
err = -EINVAL;
goto error;
case UDP_ENCAP_ESPINUDP:
diff --git a/net/ipv6/esp6.c b/net/ipv6/esp6.c
index 2ca9b7b7e500..e7a16f9643e5 100644
--- a/net/ipv6/esp6.c
+++ b/net/ipv6/esp6.c
@@ -1050,16 +1050,17 @@ static void esp6_destroy(struct xfrm_state *x)
crypto_free_aead(aead);
}
-static int esp_init_aead(struct xfrm_state *x)
+static int esp_init_aead(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
char aead_name[CRYPTO_MAX_ALG_NAME];
struct crypto_aead *aead;
int err;
- err = -ENAMETOOLONG;
if (snprintf(aead_name, CRYPTO_MAX_ALG_NAME, "%s(%s)",
- x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME)
- goto error;
+ x->geniv, x->aead->alg_name) >= CRYPTO_MAX_ALG_NAME) {
+ NL_SET_ERR_MSG(extack, "Algorithm name is too long");
+ return -ENAMETOOLONG;
+ }
aead = crypto_alloc_aead(aead_name, 0, 0);
err = PTR_ERR(aead);
@@ -1077,11 +1078,15 @@ static int esp_init_aead(struct xfrm_state *x)
if (err)
goto error;
+ return 0;
+
error:
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
return err;
}
-static int esp_init_authenc(struct xfrm_state *x)
+static int esp_init_authenc(struct xfrm_state *x,
+ struct netlink_ext_ack *extack)
{
struct crypto_aead *aead;
struct crypto_authenc_key_param *param;
@@ -1092,10 +1097,6 @@ static int esp_init_authenc(struct xfrm_state *x)
unsigned int keylen;
int err;
- err = -EINVAL;
- if (!x->ealg)
- goto error;
-
err = -ENAMETOOLONG;
if ((x->props.flags & XFRM_STATE_ESN)) {
@@ -1104,22 +1105,28 @@ static int esp_init_authenc(struct xfrm_state *x)
x->geniv ?: "", x->geniv ? "(" : "",
x->aalg ? x->aalg->alg_name : "digest_null",
x->ealg->alg_name,
- x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME)
+ x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) {
+ NL_SET_ERR_MSG(extack, "Algorithm name is too long");
goto error;
+ }
} else {
if (snprintf(authenc_name, CRYPTO_MAX_ALG_NAME,
"%s%sauthenc(%s,%s)%s",
x->geniv ?: "", x->geniv ? "(" : "",
x->aalg ? x->aalg->alg_name : "digest_null",
x->ealg->alg_name,
- x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME)
+ x->geniv ? ")" : "") >= CRYPTO_MAX_ALG_NAME) {
+ NL_SET_ERR_MSG(extack, "Algorithm name is too long");
goto error;
+ }
}
aead = crypto_alloc_aead(authenc_name, 0, 0);
err = PTR_ERR(aead);
- if (IS_ERR(aead))
+ if (IS_ERR(aead)) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto error;
+ }
x->data = aead;
@@ -1149,17 +1156,16 @@ static int esp_init_authenc(struct xfrm_state *x)
err = -EINVAL;
if (aalg_desc->uinfo.auth.icv_fullbits / 8 !=
crypto_aead_authsize(aead)) {
- pr_info("ESP: %s digestsize %u != %u\n",
- x->aalg->alg_name,
- crypto_aead_authsize(aead),
- aalg_desc->uinfo.auth.icv_fullbits / 8);
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto free_key;
}
err = crypto_aead_setauthsize(
aead, x->aalg->alg_trunc_len / 8);
- if (err)
+ if (err) {
+ NL_SET_ERR_MSG(extack, "Kernel was unable to initialize cryptographic operations");
goto free_key;
+ }
}
param->enckeylen = cpu_to_be32((x->ealg->alg_key_len + 7) / 8);
@@ -1182,10 +1188,14 @@ static int esp6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
x->data = NULL;
- if (x->aead)
- err = esp_init_aead(x);
- else
- err = esp_init_authenc(x);
+ if (x->aead) {
+ err = esp_init_aead(x, extack);
+ } else if (x->ealg) {
+ err = esp_init_authenc(x, extack);
+ } else {
+ NL_SET_ERR_MSG(extack, "ESP: AEAD or CRYPT must be provided");
+ err = -EINVAL;
+ }
if (err)
goto error;
@@ -1213,6 +1223,7 @@ static int esp6_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
switch (encap->encap_type) {
default:
+ NL_SET_ERR_MSG(extack, "Unsupported encapsulation type for ESP");
err = -EINVAL;
goto error;
case UDP_ENCAP_ESPINUDP:
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 22/24] xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (20 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 21/24] xfrm: esp: add extack to esp_init_state, esp6_init_state Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 23/24] xfrm: ipcomp: add extack to ipcomp{4,6}_init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 24/24] xfrm: mip6: add extack to mip6_destopt_init_state, mip6_rthdr_init_state Steffen Klassert
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/ipv4/xfrm4_tunnel.c | 8 ++++++--
net/ipv6/xfrm6_tunnel.c | 8 ++++++--
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c
index 08826e0d7962..8489fa106583 100644
--- a/net/ipv4/xfrm4_tunnel.c
+++ b/net/ipv4/xfrm4_tunnel.c
@@ -24,11 +24,15 @@ static int ipip_xfrm_rcv(struct xfrm_state *x, struct sk_buff *skb)
static int ipip_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
- if (x->props.mode != XFRM_MODE_TUNNEL)
+ if (x->props.mode != XFRM_MODE_TUNNEL) {
+ NL_SET_ERR_MSG(extack, "IPv4 tunnel can only be used with tunnel mode");
return -EINVAL;
+ }
- if (x->encap)
+ if (x->encap) {
+ NL_SET_ERR_MSG(extack, "IPv4 tunnel is not compatible with encapsulation");
return -EINVAL;
+ }
x->props.header_len = sizeof(struct iphdr);
diff --git a/net/ipv6/xfrm6_tunnel.c b/net/ipv6/xfrm6_tunnel.c
index dda44b0671ac..1323f2f6928e 100644
--- a/net/ipv6/xfrm6_tunnel.c
+++ b/net/ipv6/xfrm6_tunnel.c
@@ -272,11 +272,15 @@ static int xfrm6_tunnel_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
static int xfrm6_tunnel_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
- if (x->props.mode != XFRM_MODE_TUNNEL)
+ if (x->props.mode != XFRM_MODE_TUNNEL) {
+ NL_SET_ERR_MSG(extack, "IPv6 tunnel can only be used with tunnel mode");
return -EINVAL;
+ }
- if (x->encap)
+ if (x->encap) {
+ NL_SET_ERR_MSG(extack, "IPv6 tunnel is not compatible with encapsulation");
return -EINVAL;
+ }
x->props.header_len = sizeof(struct ipv6hdr);
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 23/24] xfrm: ipcomp: add extack to ipcomp{4,6}_init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (21 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 22/24] xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
2022-10-02 8:17 ` [PATCH 24/24] xfrm: mip6: add extack to mip6_destopt_init_state, mip6_rthdr_init_state Steffen Klassert
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
And the shared helper ipcomp_init_state.
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
include/net/ipcomp.h | 2 +-
net/ipv4/ipcomp.c | 7 +++++--
net/ipv6/ipcomp6.c | 7 +++++--
net/xfrm/xfrm_ipcomp.c | 10 +++++++---
4 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/include/net/ipcomp.h b/include/net/ipcomp.h
index c31108295079..8660a2a6d1fc 100644
--- a/include/net/ipcomp.h
+++ b/include/net/ipcomp.h
@@ -22,7 +22,7 @@ struct xfrm_state;
int ipcomp_input(struct xfrm_state *x, struct sk_buff *skb);
int ipcomp_output(struct xfrm_state *x, struct sk_buff *skb);
void ipcomp_destroy(struct xfrm_state *x);
-int ipcomp_init_state(struct xfrm_state *x);
+int ipcomp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack);
static inline struct ip_comp_hdr *ip_comp_hdr(const struct sk_buff *skb)
{
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 230d1120874f..5a4fb2539b08 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -130,17 +130,20 @@ static int ipcomp4_init_state(struct xfrm_state *x,
x->props.header_len += sizeof(struct iphdr);
break;
default:
+ NL_SET_ERR_MSG(extack, "Unsupported XFRM mode for IPcomp");
goto out;
}
- err = ipcomp_init_state(x);
+ err = ipcomp_init_state(x, extack);
if (err)
goto out;
if (x->props.mode == XFRM_MODE_TUNNEL) {
err = ipcomp_tunnel_attach(x);
- if (err)
+ if (err) {
+ NL_SET_ERR_MSG(extack, "Kernel error: failed to initialize the associated state");
goto out;
+ }
}
err = 0;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 7e47009739e9..72d4858dec18 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -149,17 +149,20 @@ static int ipcomp6_init_state(struct xfrm_state *x,
x->props.header_len += sizeof(struct ipv6hdr);
break;
default:
+ NL_SET_ERR_MSG(extack, "Unsupported XFRM mode for IPcomp");
goto out;
}
- err = ipcomp_init_state(x);
+ err = ipcomp_init_state(x, extack);
if (err)
goto out;
if (x->props.mode == XFRM_MODE_TUNNEL) {
err = ipcomp6_tunnel_attach(x);
- if (err)
+ if (err) {
+ NL_SET_ERR_MSG(extack, "Kernel error: failed to initialize the associated state");
goto out;
+ }
}
err = 0;
diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index cb40ff0ff28d..656045a87606 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -325,18 +325,22 @@ void ipcomp_destroy(struct xfrm_state *x)
}
EXPORT_SYMBOL_GPL(ipcomp_destroy);
-int ipcomp_init_state(struct xfrm_state *x)
+int ipcomp_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
int err;
struct ipcomp_data *ipcd;
struct xfrm_algo_desc *calg_desc;
err = -EINVAL;
- if (!x->calg)
+ if (!x->calg) {
+ NL_SET_ERR_MSG(extack, "Missing required compression algorithm");
goto out;
+ }
- if (x->encap)
+ if (x->encap) {
+ NL_SET_ERR_MSG(extack, "IPComp is not compatible with encapsulation");
goto out;
+ }
err = -ENOMEM;
ipcd = kzalloc(sizeof(*ipcd), GFP_KERNEL);
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 24/24] xfrm: mip6: add extack to mip6_destopt_init_state, mip6_rthdr_init_state
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
` (22 preceding siblings ...)
2022-10-02 8:17 ` [PATCH 23/24] xfrm: ipcomp: add extack to ipcomp{4,6}_init_state Steffen Klassert
@ 2022-10-02 8:17 ` Steffen Klassert
23 siblings, 0 replies; 26+ messages in thread
From: Steffen Klassert @ 2022-10-02 8:17 UTC (permalink / raw)
To: David Miller, Jakub Kicinski; +Cc: Herbert Xu, Steffen Klassert, netdev
From: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Sabrina Dubroca <sd@queasysnail•net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet•com>
---
net/ipv6/mip6.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 3d87ae88ebfd..83d2a8be263f 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -250,12 +250,11 @@ static int mip6_destopt_reject(struct xfrm_state *x, struct sk_buff *skb,
static int mip6_destopt_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
if (x->id.spi) {
- pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi);
+ NL_SET_ERR_MSG(extack, "SPI must be 0");
return -EINVAL;
}
if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
- pr_info("%s: state's mode is not %u: %u\n",
- __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
+ NL_SET_ERR_MSG(extack, "XFRM mode must be XFRM_MODE_ROUTEOPTIMIZATION");
return -EINVAL;
}
@@ -336,12 +335,11 @@ static int mip6_rthdr_output(struct xfrm_state *x, struct sk_buff *skb)
static int mip6_rthdr_init_state(struct xfrm_state *x, struct netlink_ext_ack *extack)
{
if (x->id.spi) {
- pr_info("%s: spi is not 0: %u\n", __func__, x->id.spi);
+ NL_SET_ERR_MSG(extack, "SPI must be 0");
return -EINVAL;
}
if (x->props.mode != XFRM_MODE_ROUTEOPTIMIZATION) {
- pr_info("%s: state's mode is not %u: %u\n",
- __func__, XFRM_MODE_ROUTEOPTIMIZATION, x->props.mode);
+ NL_SET_ERR_MSG(extack, "XFRM mode must be XFRM_MODE_ROUTEOPTIMIZATION");
return -EINVAL;
}
--
2.25.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs
2022-10-02 8:16 ` [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs Steffen Klassert
@ 2022-10-03 7:10 ` patchwork-bot+netdevbpf
0 siblings, 0 replies; 26+ messages in thread
From: patchwork-bot+netdevbpf @ 2022-10-03 7:10 UTC (permalink / raw)
To: Steffen Klassert; +Cc: davem, kuba, herbert, netdev
Hello:
This series was applied to netdev/net-next.git (master)
by Steffen Klassert <steffen.klassert@secunet•com>:
On Sun, 2 Oct 2022 10:16:49 +0200 you wrote:
> From: Gautam Menghani <gautammenghani201@gmail•com>
>
> A TODO in net/ipsec.c asks to refactor the code in xfrm_fill_key() to
> use set/map to avoid manually comparing each algorithm with the "name"
> parameter passed to the function as an argument. This patch refactors
> the code to create an array of structs where each struct contains the
> algorithm name and its corresponding key length.
>
> [...]
Here is the summary with links:
- [01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs
https://git.kernel.org/netdev/net-next/c/93d7c52a6eb9
- [02/24] xfrm: Drop unused argument
https://git.kernel.org/netdev/net-next/c/0de1978852df
- [03/24] net: allow storing xfrm interface metadata in metadata_dst
https://git.kernel.org/netdev/net-next/c/5182a5d48c3d
- [04/24] xfrm: interface: support collect metadata mode
https://git.kernel.org/netdev/net-next/c/abc340b38ba2
- [05/24] xfrm: lwtunnel: add lwtunnel support for xfrm interfaces in collect_md mode
https://git.kernel.org/netdev/net-next/c/2c2493b9da91
- [06/24] xfrm: propagate extack to all netlink doit handlers
https://git.kernel.org/netdev/net-next/c/3bec6c3e83b5
- [07/24] xfrm: add extack support to verify_newpolicy_info
https://git.kernel.org/netdev/net-next/c/ec2b4f01536d
- [08/24] xfrm: add extack to verify_policy_dir
https://git.kernel.org/netdev/net-next/c/24fc544fb525
- [09/24] xfrm: add extack to verify_policy_type
https://git.kernel.org/netdev/net-next/c/fb7deaba40cf
- [10/24] xfrm: add extack to validate_tmpl
https://git.kernel.org/netdev/net-next/c/d37bed89f082
- [11/24] xfrm: add extack to verify_sec_ctx_len
https://git.kernel.org/netdev/net-next/c/08a717e48037
- [12/24] xfrm: add extack support to verify_newsa_info
https://git.kernel.org/netdev/net-next/c/6999aae17a7b
- [13/24] xfrm: add extack to verify_replay
https://git.kernel.org/netdev/net-next/c/785b87b22085
- [14/24] xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead
https://git.kernel.org/netdev/net-next/c/1fc8fde55391
- [15/24] xfrm: add extack support to xfrm_dev_state_add
https://git.kernel.org/netdev/net-next/c/adb5c33e4d4c
- [16/24] xfrm: add extack to attach_*
https://git.kernel.org/netdev/net-next/c/2b9168266d15
- [17/24] xfrm: add extack to __xfrm_init_state
https://git.kernel.org/netdev/net-next/c/741f9a106498
- [18/24] xfrm: add extack support to xfrm_init_replay
https://git.kernel.org/netdev/net-next/c/1cf9a3ae3e2d
- [19/24] xfrm: pass extack down to xfrm_type ->init_state
https://git.kernel.org/netdev/net-next/c/e1e10b44cf28
- [20/24] xfrm: ah: add extack to ah_init_state, ah6_init_state
https://git.kernel.org/netdev/net-next/c/ef87a4f84b10
- [21/24] xfrm: esp: add extack to esp_init_state, esp6_init_state
https://git.kernel.org/netdev/net-next/c/67c44f93c951
- [22/24] xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state
https://git.kernel.org/netdev/net-next/c/25ec92cd042a
- [23/24] xfrm: ipcomp: add extack to ipcomp{4,6}_init_state
https://git.kernel.org/netdev/net-next/c/6ee55320520e
- [24/24] xfrm: mip6: add extack to mip6_destopt_init_state, mip6_rthdr_init_state
https://git.kernel.org/netdev/net-next/c/28b5dbd5dcf7
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2022-10-03 7:10 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-10-02 8:16 [PATCH 0/24] pull request (net-next): ipsec-next 2022-10-02 Steffen Klassert
2022-10-02 8:16 ` [PATCH 01/24] selftests/net: Refactor xfrm_fill_key() to use array of structs Steffen Klassert
2022-10-03 7:10 ` patchwork-bot+netdevbpf
2022-10-02 8:16 ` [PATCH 02/24] xfrm: Drop unused argument Steffen Klassert
2022-10-02 8:16 ` [PATCH 03/24] net: allow storing xfrm interface metadata in metadata_dst Steffen Klassert
2022-10-02 8:16 ` [PATCH 04/24] xfrm: interface: support collect metadata mode Steffen Klassert
2022-10-02 8:16 ` [PATCH 05/24] xfrm: lwtunnel: add lwtunnel support for xfrm interfaces in collect_md mode Steffen Klassert
2022-10-02 8:16 ` [PATCH 06/24] xfrm: propagate extack to all netlink doit handlers Steffen Klassert
2022-10-02 8:16 ` [PATCH 07/24] xfrm: add extack support to verify_newpolicy_info Steffen Klassert
2022-10-02 8:16 ` [PATCH 08/24] xfrm: add extack to verify_policy_dir Steffen Klassert
2022-10-02 8:16 ` [PATCH 09/24] xfrm: add extack to verify_policy_type Steffen Klassert
2022-10-02 8:16 ` [PATCH 10/24] xfrm: add extack to validate_tmpl Steffen Klassert
2022-10-02 8:16 ` [PATCH 11/24] xfrm: add extack to verify_sec_ctx_len Steffen Klassert
2022-10-02 8:17 ` [PATCH 12/24] xfrm: add extack support to verify_newsa_info Steffen Klassert
2022-10-02 8:17 ` [PATCH 13/24] xfrm: add extack to verify_replay Steffen Klassert
2022-10-02 8:17 ` [PATCH 14/24] xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead Steffen Klassert
2022-10-02 8:17 ` [PATCH 15/24] xfrm: add extack support to xfrm_dev_state_add Steffen Klassert
2022-10-02 8:17 ` [PATCH 16/24] xfrm: add extack to attach_* Steffen Klassert
2022-10-02 8:17 ` [PATCH 17/24] xfrm: add extack to __xfrm_init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 18/24] xfrm: add extack support to xfrm_init_replay Steffen Klassert
2022-10-02 8:17 ` [PATCH 19/24] xfrm: pass extack down to xfrm_type ->init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 20/24] xfrm: ah: add extack to ah_init_state, ah6_init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 21/24] xfrm: esp: add extack to esp_init_state, esp6_init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 22/24] xfrm: tunnel: add extack to ipip_init_state, xfrm6_tunnel_init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 23/24] xfrm: ipcomp: add extack to ipcomp{4,6}_init_state Steffen Klassert
2022-10-02 8:17 ` [PATCH 24/24] xfrm: mip6: add extack to mip6_destopt_init_state, mip6_rthdr_init_state Steffen Klassert
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox