XDP_QUERY_PROG,
 };
 
+struct netlink_ext_ack;
+
 struct netdev_xdp {
        enum xdp_netdev_command command;
        union {
                /* XDP_SETUP_PROG */
-               struct bpf_prog *prog;
+               struct {
+                       struct bpf_prog *prog;
+                       struct netlink_ext_ack *extack;
+               };
                /* XDP_QUERY_PROG */
                bool prog_attached;
        };
 int dev_get_phys_port_name(struct net_device *dev,
                           char *name, size_t len);
 int dev_change_proto_down(struct net_device *dev, bool proto_down);
-int dev_change_xdp_fd(struct net_device *dev, int fd, u32 flags);
+int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
+                     int fd, u32 flags);
 struct sk_buff *validate_xmit_skb_list(struct sk_buff *skb, struct net_device *dev);
 struct sk_buff *dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
                                    struct netdev_queue *txq, int *ret);
 
 /**
  *     dev_change_xdp_fd - set or clear a bpf program for a device rx path
  *     @dev: device
+ *     @extact: netlink extended ack
  *     @fd: new program fd or negative value to clear
  *     @flags: xdp-related flags
  *
  *     Set or clear a bpf program for a device
  */
-int dev_change_xdp_fd(struct net_device *dev, int fd, u32 flags)
+int dev_change_xdp_fd(struct net_device *dev, struct netlink_ext_ack *extack,
+                     int fd, u32 flags)
 {
        int (*xdp_op)(struct net_device *dev, struct netdev_xdp *xdp);
        const struct net_device_ops *ops = dev->netdev_ops;
 
        memset(&xdp, 0, sizeof(xdp));
        xdp.command = XDP_SETUP_PROG;
+       xdp.extack = extack;
        xdp.prog = prog;
 
        err = xdp_op(dev, &xdp);
 
 #define DO_SETLINK_NOTIFY      0x03
 static int do_setlink(const struct sk_buff *skb,
                      struct net_device *dev, struct ifinfomsg *ifm,
+                     struct netlink_ext_ack *extack,
                      struct nlattr **tb, char *ifname, int status)
 {
        const struct net_device_ops *ops = dev->netdev_ops;
                }
 
                if (xdp[IFLA_XDP_FD]) {
-                       err = dev_change_xdp_fd(dev,
+                       err = dev_change_xdp_fd(dev, extack,
                                                nla_get_s32(xdp[IFLA_XDP_FD]),
                                                xdp_flags);
                        if (err)
        if (err < 0)
                goto errout;
 
-       err = do_setlink(skb, dev, ifm, tb, ifname, 0);
+       err = do_setlink(skb, dev, ifm, extack, tb, ifname, 0);
 errout:
        return err;
 }
 static int rtnl_group_changelink(const struct sk_buff *skb,
                struct net *net, int group,
                struct ifinfomsg *ifm,
+               struct netlink_ext_ack *extack,
                struct nlattr **tb)
 {
        struct net_device *dev, *aux;
 
        for_each_netdev_safe(net, dev, aux) {
                if (dev->group == group) {
-                       err = do_setlink(skb, dev, ifm, tb, NULL, 0);
+                       err = do_setlink(skb, dev, ifm, extack, tb, NULL, 0);
                        if (err < 0)
                                return err;
                }
                                status |= DO_SETLINK_NOTIFY;
                        }
 
-                       return do_setlink(skb, dev, ifm, tb, ifname, status);
+                       return do_setlink(skb, dev, ifm, extack, tb, ifname,
+                                         status);
                }
 
                if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
                        if (ifm->ifi_index == 0 && tb[IFLA_GROUP])
                                return rtnl_group_changelink(skb, net,
                                                nla_get_u32(tb[IFLA_GROUP]),
-                                               ifm, tb);
+                                               ifm, extack, tb);
                        return -ENODEV;
                }