xfrm: add extack support to xfrm_dev_state_add
authorSabrina Dubroca <sd@queasysnail.net>
Wed, 14 Sep 2022 17:04:03 +0000 (19:04 +0200)
committerSteffen Klassert <steffen.klassert@secunet.com>
Thu, 22 Sep 2022 05:36:07 +0000 (07:36 +0200)
Signed-off-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
include/net/xfrm.h
net/xfrm/xfrm_device.c
net/xfrm/xfrm_user.c

index 28b988577ed2072912304570e771165ac0338591..9c1cccf85f12b96cadba24aa2429e9d94981b450 100644 (file)
@@ -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;
 }
index 637ca8838436861cbaf093cfd3914394d26e14d6..5f5aafd418af0e2537792dc642813f0dbed64c88 100644 (file)
@@ -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;
index 3c150e1f8a2a76cfced050e15e1b7c92f7f005fb..c56b9442dffe325d4acc4d18a8deecadf0a4c87f 100644 (file)
@@ -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;