net/bridge/br_switchdev.c
Source file repositories/reference/linux-study-clean/net/bridge/br_switchdev.c
File Facts
- System
- Linux kernel
- Corpus path
net/bridge/br_switchdev.c- Extension
.c- Size
- 22153 bytes
- Lines
- 891
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: implementation source
- Status
- source 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.
- 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/kernel.hlinux/list.hlinux/netdevice.hlinux/rtnetlink.hlinux/skbuff.hnet/ip.hnet/switchdev.hbr_private.h
Detected Declarations
struct br_switchdev_mdb_complete_infofunction nbp_switchdev_can_offload_tx_fwdfunction br_switchdev_frame_uses_tx_fwd_offloadfunction br_switchdev_frame_set_offload_fwd_markfunction nbp_switchdev_frame_mark_tx_fwd_offloadfunction nbp_switchdev_allowed_egressfunction nbp_switchdev_frame_markfunction nbp_switchdev_allowed_egressfunction br_switchdev_set_port_flagfunction br_switchdev_fdb_populatefunction br_switchdev_fdb_notifyfunction br_switchdev_port_vlan_addfunction br_switchdev_port_vlan_no_foreign_addfunction br_switchdev_port_vlan_delfunction nbp_switchdev_hwdom_setfunction nbp_switchdev_hwdom_putfunction nbp_switchdev_addfunction nbp_switchdev_delfunction br_switchdev_fdb_replay_onefunction br_switchdev_fdb_replayfunction hlist_for_each_entry_rcufunction br_switchdev_vlan_attr_replayfunction list_for_each_entryfunction br_switchdev_vlan_replay_onefunction br_switchdev_vlan_replay_groupfunction list_for_each_entryfunction br_switchdev_vlan_replayfunction list_for_each_entryfunction br_switchdev_mdb_completefunction br_switchdev_mdb_populatefunction br_switchdev_host_mdb_onefunction br_switchdev_host_mdbfunction br_switchdev_mdb_replay_onefunction br_switchdev_mdb_queue_onefunction br_switchdev_mdb_notifyfunction br_switchdev_mdb_replayfunction hlist_for_each_entryfunction list_for_each_entryfunction nbp_switchdev_sync_objsfunction nbp_switchdev_unsync_objsfunction br_switchdev_port_offloadfunction br_switchdev_port_unoffloadfunction br_switchdev_port_replay
Annotated Snippet
struct br_switchdev_mdb_complete_info {
struct net_bridge_port *port;
struct br_ip ip;
};
static void br_switchdev_mdb_complete(struct net_device *dev, int err, void *priv)
{
struct br_switchdev_mdb_complete_info *data = priv;
struct net_bridge_port_group __rcu **pp;
struct net_bridge_port_group *p;
struct net_bridge_mdb_entry *mp;
struct net_bridge_port *port = data->port;
struct net_bridge *br = port->br;
u8 old_flags;
if (err == -EOPNOTSUPP)
goto out_free;
spin_lock_bh(&br->multicast_lock);
mp = br_mdb_ip_get(br, &data->ip);
if (!mp)
goto out;
for (pp = &mp->ports; (p = mlock_dereference(*pp, br)) != NULL;
pp = &p->next) {
if (p->key.port != port)
continue;
old_flags = p->flags;
br_multicast_set_pg_offload_flags(p, !err);
if (br_mdb_should_notify(br, old_flags ^ p->flags))
br_mdb_flag_change_notify(br->dev, mp, p);
}
out:
spin_unlock_bh(&br->multicast_lock);
out_free:
kfree(priv);
}
static void br_switchdev_mdb_populate(struct switchdev_obj_port_mdb *mdb,
const struct net_bridge_mdb_entry *mp)
{
if (mp->addr.proto == htons(ETH_P_IP))
ip_eth_mc_map(mp->addr.dst.ip4, mdb->addr);
#if IS_ENABLED(CONFIG_IPV6)
else if (mp->addr.proto == htons(ETH_P_IPV6))
ipv6_eth_mc_map(&mp->addr.dst.ip6, mdb->addr);
#endif
else
ether_addr_copy(mdb->addr, mp->addr.dst.mac_addr);
mdb->vid = mp->addr.vid;
}
static void br_switchdev_host_mdb_one(struct net_device *dev,
struct net_device *lower_dev,
struct net_bridge_mdb_entry *mp,
int type)
{
struct switchdev_obj_port_mdb mdb = {
.obj = {
.id = SWITCHDEV_OBJ_ID_HOST_MDB,
.flags = SWITCHDEV_F_DEFER,
.orig_dev = dev,
},
};
br_switchdev_mdb_populate(&mdb, mp);
switch (type) {
case RTM_NEWMDB:
switchdev_port_obj_add(lower_dev, &mdb.obj, NULL);
break;
case RTM_DELMDB:
switchdev_port_obj_del(lower_dev, &mdb.obj);
break;
}
}
static void br_switchdev_host_mdb(struct net_device *dev,
struct net_bridge_mdb_entry *mp, int type)
{
struct net_device *lower_dev;
struct list_head *iter;
netdev_for_each_lower_dev(dev, lower_dev, iter)
br_switchdev_host_mdb_one(dev, lower_dev, mp, type);
}
static int
br_switchdev_mdb_replay_one(struct notifier_block *nb, struct net_device *dev,
Annotation
- Immediate include surface: `linux/kernel.h`, `linux/list.h`, `linux/netdevice.h`, `linux/rtnetlink.h`, `linux/skbuff.h`, `net/ip.h`, `net/switchdev.h`, `br_private.h`.
- Detected declarations: `struct br_switchdev_mdb_complete_info`, `function nbp_switchdev_can_offload_tx_fwd`, `function br_switchdev_frame_uses_tx_fwd_offload`, `function br_switchdev_frame_set_offload_fwd_mark`, `function nbp_switchdev_frame_mark_tx_fwd_offload`, `function nbp_switchdev_allowed_egress`, `function nbp_switchdev_frame_mark`, `function nbp_switchdev_allowed_egress`, `function br_switchdev_set_port_flag`, `function br_switchdev_fdb_populate`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source 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.