Skip to content

Commit ab2f8e2

Browse files
leitaojfvogel
authored andcommitted
net: Add non-RCU dev_getbyhwaddr() helper
[ Upstream commit 4b5a28b ] Add dedicated helper for finding devices by hardware address when holding rtnl_lock, similar to existing dev_getbyhwaddr_rcu(). This prevents PROVE_LOCKING warnings when rtnl_lock is held but RCU read lock is not. Extract common address comparison logic into dev_addr_cmp(). The context about this change could be found in the following discussion: Link: https://lore.kernel.org/all/20250206-scarlet-ermine-of-improvement-1fcac5@leitao/ Cc: [email protected] Cc: [email protected] Suggested-by: Eric Dumazet <[email protected]> Signed-off-by: Breno Leitao <[email protected]> Reviewed-by: Kuniyuki Iwashima <[email protected]> Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Stable-dep-of: 4eae0ee ("arp: switch to dev_getbyhwaddr() in arp_req_set_public()") Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit 36d5616bc5ee6e891eaeb103fe42332ce7a5bcc6) Signed-off-by: Jack Vogel <[email protected]>
1 parent ad4816c commit ab2f8e2

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

include/linux/netdevice.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3064,6 +3064,8 @@ static inline struct net_device *first_net_device_rcu(struct net *net)
30643064
}
30653065

30663066
int netdev_boot_setup_check(struct net_device *dev);
3067+
struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
3068+
const char *hwaddr);
30673069
struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
30683070
const char *hwaddr);
30693071
struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type);

net/core/dev.c

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,12 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
10151015
return ret;
10161016
}
10171017

1018+
static bool dev_addr_cmp(struct net_device *dev, unsigned short type,
1019+
const char *ha)
1020+
{
1021+
return dev->type == type && !memcmp(dev->dev_addr, ha, dev->addr_len);
1022+
}
1023+
10181024
/**
10191025
* dev_getbyhwaddr_rcu - find a device by its hardware address
10201026
* @net: the applicable net namespace
@@ -1023,7 +1029,7 @@ int netdev_get_name(struct net *net, char *name, int ifindex)
10231029
*
10241030
* Search for an interface by MAC address. Returns NULL if the device
10251031
* is not found or a pointer to the device.
1026-
* The caller must hold RCU or RTNL.
1032+
* The caller must hold RCU.
10271033
* The returned device has not had its ref count increased
10281034
* and the caller must therefore be careful about locking
10291035
*
@@ -1035,14 +1041,39 @@ struct net_device *dev_getbyhwaddr_rcu(struct net *net, unsigned short type,
10351041
struct net_device *dev;
10361042

10371043
for_each_netdev_rcu(net, dev)
1038-
if (dev->type == type &&
1039-
!memcmp(dev->dev_addr, ha, dev->addr_len))
1044+
if (dev_addr_cmp(dev, type, ha))
10401045
return dev;
10411046

10421047
return NULL;
10431048
}
10441049
EXPORT_SYMBOL(dev_getbyhwaddr_rcu);
10451050

1051+
/**
1052+
* dev_getbyhwaddr() - find a device by its hardware address
1053+
* @net: the applicable net namespace
1054+
* @type: media type of device
1055+
* @ha: hardware address
1056+
*
1057+
* Similar to dev_getbyhwaddr_rcu(), but the owner needs to hold
1058+
* rtnl_lock.
1059+
*
1060+
* Context: rtnl_lock() must be held.
1061+
* Return: pointer to the net_device, or NULL if not found
1062+
*/
1063+
struct net_device *dev_getbyhwaddr(struct net *net, unsigned short type,
1064+
const char *ha)
1065+
{
1066+
struct net_device *dev;
1067+
1068+
ASSERT_RTNL();
1069+
for_each_netdev(net, dev)
1070+
if (dev_addr_cmp(dev, type, ha))
1071+
return dev;
1072+
1073+
return NULL;
1074+
}
1075+
EXPORT_SYMBOL(dev_getbyhwaddr);
1076+
10461077
struct net_device *dev_getfirstbyhwtype(struct net *net, unsigned short type)
10471078
{
10481079
struct net_device *dev, *ret = NULL;

0 commit comments

Comments
 (0)