net/core/dev_addr_lists.c
Source file repositories/reference/linux-study-clean/net/core/dev_addr_lists.c
File Facts
- System
- Linux kernel
- Corpus path
net/core/dev_addr_lists.c- Extension
.c- Size
- 38862 bytes
- Lines
- 1484
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: operation-table or driver-model contract
- Status
- pattern implementation candidate
Why This File Exists
Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/netdevice.hlinux/rtnetlink.hlinux/export.hlinux/list.hlinux/spinlock.hlinux/workqueue.hkunit/visibility.hdev.h
Detected Declarations
function __hw_addr_insertfunction __hw_addr_createfunction __hw_addr_add_exfunction __hw_addr_addfunction __hw_addr_del_entryfunction __hw_addr_del_exfunction __hw_addr_delfunction __hw_addr_sync_onefunction __hw_addr_unsync_onefunction __hw_addr_sync_multiplefunction list_for_each_entry_safefunction __hw_addr_sync_multiplefunction list_for_each_entry_safefunction __hw_addr_unsyncfunction list_for_each_entry_safefunction __hw_addr_sync_devfunction __hw_addr_ref_sync_devfunction __hw_addr_ref_sync_devfunction list_for_each_entry_safefunction __hw_addr_sync_devfunction list_for_each_entry_safefunction __hw_addr_flushfunction __hw_addr_initfunction __hw_addr_splicefunction __hw_addr_list_snapshotfunction list_for_each_entryfunction __hw_addr_list_reconcilefunction list_for_each_entry_safefunction dev_addr_checkfunction dev_addr_flushfunction dev_addr_initfunction dev_addr_modfunction dev_addr_addfunction dev_addr_delfunction dev_uc_add_exclfunction dev_uc_addfunction dev_uc_delfunction dev_uc_syncfunction dev_uc_sync_multiplefunction dev_uc_syncfunction dev_uc_flushfunction dev_uc_initfunction dev_mc_add_exclfunction __dev_mc_addfunction dev_mc_addfunction dev_mc_add_globalfunction __dev_mc_delfunction dev_mc_del
Annotated Snippet
const struct net_device_ops *ops = dev->netdev_ops;
int promisc_inc;
int err;
might_sleep();
netdev_assert_locked_ops_compat(dev);
__hw_addr_init(&uc_snap);
__hw_addr_init(&mc_snap);
__hw_addr_init(&uc_ref);
__hw_addr_init(&mc_ref);
if (!(dev->flags & IFF_UP) || !netif_device_present(dev))
return;
if (ops->ndo_set_rx_mode_async) {
netif_addr_lock_bh(dev);
err = netif_addr_lists_snapshot(dev, &uc_snap, &mc_snap,
&uc_ref, &mc_ref);
if (err) {
netif_addr_unlock_bh(dev);
netif_rx_mode_schedule_retry(dev);
return;
}
promisc_inc = netif_uc_promisc_update(dev);
netif_addr_unlock_bh(dev);
} else {
netif_addr_lock_bh(dev);
promisc_inc = netif_uc_promisc_update(dev);
netif_addr_unlock_bh(dev);
}
if (promisc_inc)
__dev_set_promiscuity(dev, promisc_inc, false);
if (ops->ndo_set_rx_mode_async) {
err = ops->ndo_set_rx_mode_async(dev, &uc_snap, &mc_snap);
netif_addr_lock_bh(dev);
netif_addr_lists_reconcile(dev, &uc_snap, &mc_snap,
&uc_ref, &mc_ref);
netif_addr_unlock_bh(dev);
if (err)
netif_rx_mode_schedule_retry(dev);
else
dev->rx_mode_retry_count = 0;
} else if (ops->ndo_set_rx_mode) {
netif_addr_lock_bh(dev);
ops->ndo_set_rx_mode(dev);
netif_addr_unlock_bh(dev);
}
}
static void netdev_rx_mode_work(struct work_struct *work)
{
struct net_device *dev;
rtnl_lock();
while (true) {
spin_lock_bh(&rx_mode_lock);
if (list_empty(&rx_mode_list)) {
spin_unlock_bh(&rx_mode_lock);
break;
}
dev = list_first_entry(&rx_mode_list, struct net_device,
rx_mode_node);
list_del_init(&dev->rx_mode_node);
/* We must free netdev tracker under
* the spinlock protection.
*/
netdev_tracker_free(dev, &dev->rx_mode_tracker);
spin_unlock_bh(&rx_mode_lock);
netdev_lock_ops(dev);
netif_rx_mode_run(dev);
netdev_unlock_ops(dev);
/* Use __dev_put() because netdev_tracker_free() was already
* called above. Must be after netdev_unlock_ops() to prevent
* netdev_run_todo() from freeing the device while still in use.
*/
__dev_put(dev);
}
rtnl_unlock();
}
static void netif_rx_mode_queue(struct net_device *dev)
Annotation
- Immediate include surface: `linux/netdevice.h`, `linux/rtnetlink.h`, `linux/export.h`, `linux/list.h`, `linux/spinlock.h`, `linux/workqueue.h`, `kunit/visibility.h`, `dev.h`.
- Detected declarations: `function __hw_addr_insert`, `function __hw_addr_create`, `function __hw_addr_add_ex`, `function __hw_addr_add`, `function __hw_addr_del_entry`, `function __hw_addr_del_ex`, `function __hw_addr_del`, `function __hw_addr_sync_one`, `function __hw_addr_unsync_one`, `function __hw_addr_sync_multiple`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: pattern implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.