In preparation for support of simultaneous driver and hardware XDP
support add per-mode attributes.  The catch-all IFLA_XDP_PROG_ID
will still be reported, but user space can now also access the
program ID in a new IFLA_XDP_<mode>_PROG_ID attribute.

Signed-off-by: Jakub Kicinski <jakub.kicin...@netronome.com>
Reviewed-by: Quentin Monnet <quentin.mon...@netronome.com>
---
 include/uapi/linux/if_link.h |  3 +++
 net/core/rtnetlink.c         | 30 ++++++++++++++++++++++++++----
 2 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h
index cf01b6824244..bc86c2b105ec 100644
--- a/include/uapi/linux/if_link.h
+++ b/include/uapi/linux/if_link.h
@@ -928,6 +928,9 @@ enum {
        IFLA_XDP_ATTACHED,
        IFLA_XDP_FLAGS,
        IFLA_XDP_PROG_ID,
+       IFLA_XDP_DRV_PROG_ID,
+       IFLA_XDP_SKB_PROG_ID,
+       IFLA_XDP_HW_PROG_ID,
        __IFLA_XDP_MAX,
 };
 
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index e3f743c141b3..8ab95de1114c 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -964,7 +964,8 @@ static size_t rtnl_xdp_size(void)
 {
        size_t xdp_size = nla_total_size(0) +   /* nest IFLA_XDP */
                          nla_total_size(1) +   /* XDP_ATTACHED */
-                         nla_total_size(4);    /* XDP_PROG_ID */
+                         nla_total_size(4) +   /* XDP_PROG_ID */
+                         nla_total_size(4);    /* XDP_<mode>_PROG_ID */
 
        return xdp_size;
 }
@@ -1378,16 +1379,17 @@ static u8 rtnl_xdp_attached_mode(struct net_device 
*dev, u32 *prog_id)
 
 static int rtnl_xdp_fill(struct sk_buff *skb, struct net_device *dev)
 {
+       u32 prog_attr, prog_id;
        struct nlattr *xdp;
-       u32 prog_id;
        int err;
+       u8 mode;
 
        xdp = nla_nest_start(skb, IFLA_XDP);
        if (!xdp)
                return -EMSGSIZE;
 
-       err = nla_put_u8(skb, IFLA_XDP_ATTACHED,
-                        rtnl_xdp_attached_mode(dev, &prog_id));
+       mode = rtnl_xdp_attached_mode(dev, &prog_id);
+       err = nla_put_u8(skb, IFLA_XDP_ATTACHED, mode);
        if (err)
                goto err_cancel;
 
@@ -1395,6 +1397,26 @@ static int rtnl_xdp_fill(struct sk_buff *skb, struct 
net_device *dev)
                err = nla_put_u32(skb, IFLA_XDP_PROG_ID, prog_id);
                if (err)
                        goto err_cancel;
+
+               switch (mode) {
+               case XDP_ATTACHED_DRV:
+                       prog_attr = IFLA_XDP_DRV_PROG_ID;
+                       break;
+               case XDP_ATTACHED_SKB:
+                       prog_attr = IFLA_XDP_SKB_PROG_ID;
+                       break;
+               case XDP_ATTACHED_HW:
+                       prog_attr = IFLA_XDP_HW_PROG_ID;
+                       break;
+               case XDP_ATTACHED_NONE:
+               default:
+                       err = -EINVAL;
+                       goto err_cancel;
+               }
+
+               err = nla_put_u32(skb, prog_attr, prog_id);
+               if (err)
+                       goto err_cancel;
        }
 
        nla_nest_end(skb, xdp);
-- 
2.17.1

Reply via email to