struct sock *sk);
 struct net_device *dev_get_by_index(struct net *net, int ifindex);
 struct net_device *__dev_get_by_index(struct net *net, int ifindex);
+struct net_device *netdev_get_by_index(struct net *net, int ifindex,
+                                      netdevice_tracker *tracker, gfp_t gfp);
+struct net_device *netdev_get_by_name(struct net *net, const char *name,
+                                     netdevice_tracker *tracker, gfp_t gfp);
 struct net_device *dev_get_by_index_rcu(struct net *net, int ifindex);
 struct net_device *dev_get_by_napi_id(unsigned int napi_id);
 int dev_restart(struct net_device *dev);
 
 }
 EXPORT_SYMBOL(dev_get_by_name_rcu);
 
+/* Deprecated for new users, call netdev_get_by_name() instead */
+struct net_device *dev_get_by_name(struct net *net, const char *name)
+{
+       struct net_device *dev;
+
+       rcu_read_lock();
+       dev = dev_get_by_name_rcu(net, name);
+       dev_hold(dev);
+       rcu_read_unlock();
+       return dev;
+}
+EXPORT_SYMBOL(dev_get_by_name);
+
 /**
- *     dev_get_by_name         - find a device by its name
+ *     netdev_get_by_name() - find a device by its name
  *     @net: the applicable net namespace
  *     @name: name to find
+ *     @tracker: tracking object for the acquired reference
+ *     @gfp: allocation flags for the tracker
  *
  *     Find an interface by name. This can be called from any
  *     context and does its own locking. The returned handle has
- *     the usage count incremented and the caller must use dev_put() to
+ *     the usage count incremented and the caller must use netdev_put() to
  *     release it when it is no longer needed. %NULL is returned if no
  *     matching device is found.
  */
-
-struct net_device *dev_get_by_name(struct net *net, const char *name)
+struct net_device *netdev_get_by_name(struct net *net, const char *name,
+                                     netdevice_tracker *tracker, gfp_t gfp)
 {
        struct net_device *dev;
 
-       rcu_read_lock();
-       dev = dev_get_by_name_rcu(net, name);
-       dev_hold(dev);
-       rcu_read_unlock();
+       dev = dev_get_by_name(net, name);
+       if (dev)
+               netdev_tracker_alloc(dev, tracker, gfp);
        return dev;
 }
-EXPORT_SYMBOL(dev_get_by_name);
+EXPORT_SYMBOL(netdev_get_by_name);
 
 /**
  *     __dev_get_by_index - find a device by its ifindex
 }
 EXPORT_SYMBOL(dev_get_by_index_rcu);
 
+/* Deprecated for new users, call netdev_get_by_index() instead */
+struct net_device *dev_get_by_index(struct net *net, int ifindex)
+{
+       struct net_device *dev;
+
+       rcu_read_lock();
+       dev = dev_get_by_index_rcu(net, ifindex);
+       dev_hold(dev);
+       rcu_read_unlock();
+       return dev;
+}
+EXPORT_SYMBOL(dev_get_by_index);
 
 /**
- *     dev_get_by_index - find a device by its ifindex
+ *     netdev_get_by_index() - find a device by its ifindex
  *     @net: the applicable net namespace
  *     @ifindex: index of device
+ *     @tracker: tracking object for the acquired reference
+ *     @gfp: allocation flags for the tracker
  *
  *     Search for an interface by index. Returns NULL if the device
  *     is not found or a pointer to the device. The device returned has
  *     had a reference added and the pointer is safe until the user calls
- *     dev_put to indicate they have finished with it.
+ *     netdev_put() to indicate they have finished with it.
  */
-
-struct net_device *dev_get_by_index(struct net *net, int ifindex)
+struct net_device *netdev_get_by_index(struct net *net, int ifindex,
+                                      netdevice_tracker *tracker, gfp_t gfp)
 {
        struct net_device *dev;
 
-       rcu_read_lock();
-       dev = dev_get_by_index_rcu(net, ifindex);
-       dev_hold(dev);
-       rcu_read_unlock();
+       dev = dev_get_by_index(net, ifindex);
+       if (dev)
+               netdev_tracker_alloc(dev, tracker, gfp);
        return dev;
 }
-EXPORT_SYMBOL(dev_get_by_index);
+EXPORT_SYMBOL(netdev_get_by_index);
 
 /**
  *     dev_get_by_napi_id - find a device by napi_id
 
        if (tb[ETHTOOL_A_HEADER_DEV_INDEX]) {
                u32 ifindex = nla_get_u32(tb[ETHTOOL_A_HEADER_DEV_INDEX]);
 
-               dev = dev_get_by_index(net, ifindex);
+               dev = netdev_get_by_index(net, ifindex, &req_info->dev_tracker,
+                                         GFP_KERNEL);
                if (!dev) {
                        NL_SET_ERR_MSG_ATTR(extack,
                                            tb[ETHTOOL_A_HEADER_DEV_INDEX],
                /* if both ifindex and ifname are passed, they must match */
                if (devname_attr &&
                    strncmp(dev->name, nla_data(devname_attr), IFNAMSIZ)) {
-                       dev_put(dev);
+                       netdev_put(dev, &req_info->dev_tracker);
                        NL_SET_ERR_MSG_ATTR(extack, header,
                                            "ifindex and name do not match");
                        return -ENODEV;
                }
        } else if (devname_attr) {
-               dev = dev_get_by_name(net, nla_data(devname_attr));
+               dev = netdev_get_by_name(net, nla_data(devname_attr),
+                                        &req_info->dev_tracker, GFP_KERNEL);
                if (!dev) {
                        NL_SET_ERR_MSG_ATTR(extack, devname_attr,
                                            "no device matches name");
        }
 
        req_info->dev = dev;
-       if (dev)
-               netdev_tracker_alloc(dev, &req_info->dev_tracker, GFP_KERNEL);
        req_info->flags = flags;
        return 0;
 }
 
                 struct fib6_config *cfg, gfp_t gfp_flags,
                 struct netlink_ext_ack *extack)
 {
+       netdevice_tracker *dev_tracker = &fib6_nh->fib_nh_dev_tracker;
        struct net_device *dev = NULL;
        struct inet6_dev *idev = NULL;
        int addr_type;
 
        err = -ENODEV;
        if (cfg->fc_ifindex) {
-               dev = dev_get_by_index(net, cfg->fc_ifindex);
+               dev = netdev_get_by_index(net, cfg->fc_ifindex,
+                                         dev_tracker, gfp_flags);
                if (!dev)
                        goto out;
                idev = in6_dev_get(dev);
                /* hold loopback dev/idev if we haven't done so. */
                if (dev != net->loopback_dev) {
                        if (dev) {
-                               dev_put(dev);
+                               netdev_put(dev, dev_tracker);
                                in6_dev_put(idev);
                        }
                        dev = net->loopback_dev;
-                       dev_hold(dev);
+                       netdev_hold(dev, dev_tracker, gfp_flags);
                        idev = in6_dev_get(dev);
                        if (!idev) {
                                err = -ENODEV;
        }
 
        fib6_nh->fib_nh_dev = dev;
-       netdev_tracker_alloc(dev, &fib6_nh->fib_nh_dev_tracker, gfp_flags);
-
        fib6_nh->fib_nh_oif = dev->ifindex;
        err = 0;
 out:
        if (err) {
                lwtstate_put(fib6_nh->fib_nh_lws);
                fib6_nh->fib_nh_lws = NULL;
-               dev_put(dev);
+               netdev_put(dev, dev_tracker);
        }
 
        return err;