(!idxattr || idxattr == attrid);
 }
 
-#define IFLA_OFFLOAD_XSTATS_FIRST (IFLA_OFFLOAD_XSTATS_UNSPEC + 1)
-static int rtnl_get_offload_stats_attr_size(int attr_id)
+static bool
+rtnl_offload_xstats_have_ndo(const struct net_device *dev, int attr_id)
 {
-       switch (attr_id) {
-       case IFLA_OFFLOAD_XSTATS_CPU_HIT:
-               return sizeof(struct rtnl_link_stats64);
-       }
+       return dev->netdev_ops &&
+              dev->netdev_ops->ndo_has_offload_stats &&
+              dev->netdev_ops->ndo_get_offload_stats &&
+              dev->netdev_ops->ndo_has_offload_stats(dev, attr_id);
+}
 
-       return 0;
+static unsigned int
+rtnl_offload_xstats_get_size_ndo(const struct net_device *dev, int attr_id)
+{
+       return rtnl_offload_xstats_have_ndo(dev, attr_id) ?
+              sizeof(struct rtnl_link_stats64) : 0;
 }
 
-static int rtnl_offload_xstats_fill(struct sk_buff *skb, struct net_device *dev,
-                                   int *prividx)
+static int
+rtnl_offload_xstats_fill_ndo(struct net_device *dev, int attr_id,
+                            struct sk_buff *skb)
 {
+       unsigned int size = rtnl_offload_xstats_get_size_ndo(dev, attr_id);
        struct nlattr *attr = NULL;
-       int attr_id, size;
        void *attr_data;
        int err;
 
-       if (!(dev->netdev_ops && dev->netdev_ops->ndo_has_offload_stats &&
-             dev->netdev_ops->ndo_get_offload_stats))
+       if (!size)
                return -ENODATA;
 
-       for (attr_id = IFLA_OFFLOAD_XSTATS_FIRST;
-            attr_id <= IFLA_OFFLOAD_XSTATS_MAX; attr_id++) {
-               if (attr_id < *prividx)
-                       continue;
+       attr = nla_reserve_64bit(skb, attr_id, size,
+                                IFLA_OFFLOAD_XSTATS_UNSPEC);
+       if (!attr)
+               return -EMSGSIZE;
 
-               size = rtnl_get_offload_stats_attr_size(attr_id);
-               if (!size)
-                       continue;
+       attr_data = nla_data(attr);
+       memset(attr_data, 0, size);
 
-               if (!dev->netdev_ops->ndo_has_offload_stats(dev, attr_id))
-                       continue;
+       err = dev->netdev_ops->ndo_get_offload_stats(attr_id, dev, attr_data);
+       if (err)
+               return err;
 
-               attr = nla_reserve_64bit(skb, attr_id, size,
-                                        IFLA_OFFLOAD_XSTATS_UNSPEC);
-               if (!attr)
-                       goto nla_put_failure;
+       return 0;
+}
 
-               attr_data = nla_data(attr);
-               memset(attr_data, 0, size);
-               err = dev->netdev_ops->ndo_get_offload_stats(attr_id, dev,
-                                                            attr_data);
-               if (err)
-                       goto get_offload_stats_failure;
+static int rtnl_offload_xstats_fill(struct sk_buff *skb, struct net_device *dev,
+                                   int *prividx)
+{
+       int attr_id_cpu_hit = IFLA_OFFLOAD_XSTATS_CPU_HIT;
+       bool have_data = false;
+       int err;
+
+       if (*prividx <= attr_id_cpu_hit) {
+               err = rtnl_offload_xstats_fill_ndo(dev, attr_id_cpu_hit, skb);
+               if (!err) {
+                       have_data = true;
+               } else if (err != -ENODATA) {
+                       *prividx = attr_id_cpu_hit;
+                       return err;
+               }
        }
 
-       if (!attr)
+       if (!have_data)
                return -ENODATA;
 
        *prividx = 0;
        return 0;
-
-nla_put_failure:
-       err = -EMSGSIZE;
-get_offload_stats_failure:
-       *prividx = attr_id;
-       return err;
 }
 
 static int rtnl_offload_xstats_get_size(const struct net_device *dev)
 {
+       int attr_id_cpu_hit = IFLA_OFFLOAD_XSTATS_CPU_HIT;
        int nla_size = 0;
-       int attr_id;
        int size;
 
-       if (!(dev->netdev_ops && dev->netdev_ops->ndo_has_offload_stats &&
-             dev->netdev_ops->ndo_get_offload_stats))
-               return 0;
-
-       for (attr_id = IFLA_OFFLOAD_XSTATS_FIRST;
-            attr_id <= IFLA_OFFLOAD_XSTATS_MAX; attr_id++) {
-               if (!dev->netdev_ops->ndo_has_offload_stats(dev, attr_id))
-                       continue;
-               size = rtnl_get_offload_stats_attr_size(attr_id);
-               nla_size += nla_total_size_64bit(size);
-       }
+       size = rtnl_offload_xstats_get_size_ndo(dev, attr_id_cpu_hit);
+       nla_size += nla_total_size_64bit(size);
 
        if (nla_size != 0)
                nla_size += nla_total_size(0);