xfrm: add netlink extack for state creation
Subsystems (3)
cover xfrm: add netlink extack for state creation
This is the second part of my work adding extended acks to XFRM, now taking care of state creation. Policies were handled in the previous series [1].
To keep this series at a reasonable size, x->type->init_state will be handled separately.
[1] https://lkml.kernel.org/r/[email protected]
Sabrina Dubroca (7):
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
include/net/xfrm.h | 10 +- net/xfrm/xfrm_device.c | 20 +++- net/xfrm/xfrm_replay.c | 10 +- net/xfrm/xfrm_state.c | 28 ++++-- net/xfrm/xfrm_user.c | 209 +++++++++++++++++++++++++++++------------ 5 files changed, 196 insertions(+), 81 deletions(-)
Signature · 1 line
2.37.3
PATCH 1/7 xfrm: add extack support to verify_newsa_info
--- net/xfrm/xfrm_user.c | 90 +++++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 21 deletions(-)
net/xfrm/xfrm_user.c +69 -21
@@ -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;
Signature · 1 line
2.37.3
Jakub Kicinski
maintainerRe: [PATCH ipsec-next 1/7] xfrm: add extack support to verify_newsa_info
net/xfrm/xfrm_user.c static int verify_newsa_info(struct xfrm_usersa_info *p, · line 258
Quoted 5 lines · On Wed, 14 Sep 2022 19:04:00 +0200 Sabrina Dubroca wrote:
net/xfrm/xfrm_user.c +4
-0case IPPROTO_COMP : +if (!attrs[XFRMA_ALG_COMP ]) { +NL_SET_ERR_MSG (extack,"Missing required attribute for COMP: COMP" ); + goto out; + }
Did NL_SET_ERR_ATTR_MISS() make it to the xfrm tree?
Re: [PATCH ipsec-next 1/7] xfrm: add extack support to verify_newsa_info
Quoted 8 lines · Jakub Kicinski
net/xfrm/xfrm_user.c static int verify_newsa_info(struct xfrm_usersa_info *p, · line 258
Quoted 5 lines · On Wed, 14 Sep 2022 19:04:00 +0200 Sabrina Dubroca wrote:
net/xfrm/xfrm_user.c +4
-0case IPPROTO_COMP : +if (!attrs[XFRMA_ALG_COMP ]) { +NL_SET_ERR_MSG (extack,"Missing required attribute for COMP: COMP" ); + goto out; + }Did
NL_SET_ERR_ATTR_MISS()make it to the xfrm tree?
No, it hasn't. Thanks for the note, I hadn't seen those patches.
It would only solve part of the problem here, since some cases need one of two possible attributes (AH needs AUTH or AUTH_TRUNC, ESP needs AEAD or CRYPT).
In this particular case, it's also a bit confusing because which attribute is required (or not allowed) depends on other parts of the configuration, so there isn't a way to express most of it outside of strings -- short of having netlink policies or extacks that can describe logical formulas, I guess.
Signature · 1 line
Sabrina
Jakub Kicinski
maintainerRe: [PATCH ipsec-next 1/7] xfrm: add extack support to verify_newsa_info
Quoted 11 lines · On Tue, 20 Sep 2022 17:55:28 +0200 Sabrina Dubroca wrote:
Quoted 8 lines · Jakub Kicinski
net/xfrm/xfrm_user.c static int verify_newsa_info(struct xfrm_usersa_info *p, · line 258
Quoted 5 lines · On Wed, 14 Sep 2022 19:04:00 +0200 Sabrina Dubroca wrote:
net/xfrm/xfrm_user.c +4
-0case IPPROTO_COMP : +if (!attrs[XFRMA_ALG_COMP ]) { +NL_SET_ERR_MSG (extack,"Missing required attribute for COMP: COMP" ); + goto out; + }Did
NL_SET_ERR_ATTR_MISS()make it to the xfrm tree?No, it hasn't. Thanks for the note, I hadn't seen those patches.
I figured you may not have seen them. Your call if using the new constructs makes sense.
Quoted 9 lines
It would only solve part of the problem here, since some cases need one of two possible attributes (AH needs AUTH or
AUTH_TRUNC, ESP needs AEAD or CRYPT).In this particular case, it's also a bit confusing because which attribute is required (or not allowed) depends on other parts of the configuration, so there isn't a way to express most of it outside of strings -- short of having netlink policies or extacks that can describe logical formulas, I guess.
I was considering adding "required" as part of policy validation, it would work in a couple of the simpler GENL cases. But I couldn't think of a clean way which wouldn't require at least one linear policy scan per message. Maybe the scan would not be a big deal, IDK.
PATCH 2/7 xfrm: add extack to verify_replay
In reply to Sabrina Dubroca--- net/xfrm/xfrm_user.c | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-)
net/xfrm/xfrm_user.c +22 -8
@@ -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 ;
Signature · 1 line
2.37.3
PATCH 3/7 xfrm: add extack to verify_one_alg, verify_auth_trunc, verify_aead
In reply to Sabrina Dubroca--- net/xfrm/xfrm_user.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-)
net/xfrm/xfrm_user.c +20 -11
@@ -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;
Signature · 1 line
2.37.3
PATCH 4/7 xfrm: add extack support to xfrm_dev_state_add
In reply to Sabrina Dubroca--- include/net/xfrm.h | 5 +++-- net/xfrm/xfrm_device.c | 20 +++++++++++++++----- net/xfrm/xfrm_user.c | 8 +++++--- 3 files changed, 23 insertions(+), 10 deletions(-)
include/net/xfrm.h +3 -2
@@ -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_feareturn 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 ; }
net/xfrm/xfrm_device.c +15 -5
@@ -207,7 +207,8 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featurEXPORT_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 ;
net/xfrm/xfrm_user.c +5 -3
@@ -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;
Signature · 1 line
2.37.3
PATCH 5/7 xfrm: add extack to attach_*
In reply to Sabrina Dubroca--- net/xfrm/xfrm_user.c | 46 +++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 16 deletions(-)
net/xfrm/xfrm_user.c +30 -16
@@ -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 ])
Signature · 1 line
2.37.3
PATCH 6/7 xfrm: add extack to __xfrm_init_state
In reply to Sabrina Dubroca--- include/net/xfrm.h | 3 ++- net/xfrm/xfrm_state.c | 26 +++++++++++++++++++------- net/xfrm/xfrm_user.c | 2 +- 3 files changed, 22 insertions(+), 9 deletions(-)
include/net/xfrm.h +2 -1
@@ -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);
net/xfrm/xfrm_state.c +19 -7
@@ -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 ;
net/xfrm/xfrm_user.c +1 -1
@@ -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;
Signature · 1 line
2.37.3
PATCH 7/7 xfrm: add extack support to xfrm_init_replay
In reply to Sabrina Dubroca--- 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(-)
include/net/xfrm.h +1 -1
@@ -1580,7 +1580,7 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_valivoid 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);
net/xfrm/xfrm_replay.c +7 -3
@@ -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 ;
net/xfrm/xfrm_state.c +1 -1
@@ -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; }
net/xfrm/xfrm_user.c +1 -1
@@ -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 */
Signature · 1 line
2.37.3
Steffen Klassert
maintainerQuoted 8 lines · Sabrina Dubroca
This is the second part of my work adding extended acks to XFRM, now taking care of state creation. Policies were handled in the previous series [1].
To keep this series at a reasonable size,x->type->init_statewill be handled separately.
Quoted 8 lines
Sabrina Dubroca (7):
xfrm: add extack support toverify_newsa_info
xfrm: add extack toverify_replay
xfrm: add extack toverify_one_alg,verify_auth_trunc,verify_aead
xfrm: add extack support toxfrm_dev_state_add
xfrm: add extack to attach_*
xfrm: add extack to__xfrm_init_state
xfrm: add extack support toxfrm_init_replay
Series applied, thanks Sabrina!