net/ipv4/ipmr.c
Source file repositories/reference/linux-study-clean/net/ipv4/ipmr.c
File Facts
- System
- Linux kernel
- Corpus path
net/ipv4/ipmr.c- Extension
.c- Size
- 84331 bytes
- Lines
- 3406
- 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.
- Touches user memory; correctness depends on fault-safe copying and privilege boundary handling.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Touches IRQ or DMA behavior; this matters for the representative real-device path.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/uaccess.hlinux/types.hlinux/cache.hlinux/capability.hlinux/errno.hlinux/mm.hlinux/kernel.hlinux/fcntl.hlinux/stat.hlinux/socket.hlinux/in.hlinux/inet.hlinux/netdevice.hlinux/inetdevice.hlinux/igmp.hlinux/proc_fs.hlinux/seq_file.hlinux/mroute.hlinux/init.hlinux/if_ether.hlinux/slab.hnet/flow.hnet/net_namespace.hnet/ip.hnet/protocol.hlinux/skbuff.hnet/route.hnet/icmp.hnet/udp.hnet/raw.hlinux/notifier.hlinux/if_arp.h
Detected Declarations
struct ipmr_rulestruct ipmr_resultstruct compat_sioc_sg_reqstruct compat_sioc_vif_reqfunction lockdep_rtnl_is_heldfunction ipmr_for_each_tablefunction ipmr_fib_lookupfunction ipmr_rule_actionfunction ipmr_rule_matchfunction ipmr_rule_configurefunction ipmr_rule_comparefunction ipmr_rule_fillfunction ipmr_rules_initfunction ipmr_rules_exitfunction ipmr_rules_exit_rtnlfunction list_for_each_entry_safefunction ipmr_rules_dumpfunction ipmr_rules_seq_readfunction ipmr_rule_defaultfunction ipmr_fib_lookupfunction ipmr_rules_initfunction ipmr_rules_exitfunction ipmr_rules_dumpfunction ipmr_rules_seq_readfunction ipmr_rule_defaultfunction ipmr_hash_cmpfunction ipmr_new_table_setfunction ipmr_free_tablefunction ipmr_init_vif_indevfunction reg_vif_xmitfunction reg_vif_get_iflinkfunction reg_vif_setupfunction __pim_rcvfunction call_ipmr_vif_entry_notifiersfunction call_ipmr_mfc_entry_notifiersfunction vif_deletefunction ipmr_cache_free_rcufunction ipmr_cache_freefunction ipmr_destroy_unresfunction ipmr_expire_processfunction list_for_each_entry_safefunction ipmr_update_thresholdsfunction vif_addfunction ipmr_cache_resolvefunction rcu_read_lockfunction ipmr_cache_unresolvedfunction list_for_each_entryfunction ipmr_mfc_delete
Annotated Snippet
static const struct net_device_ops reg_vif_netdev_ops = {
.ndo_start_xmit = reg_vif_xmit,
.ndo_get_iflink = reg_vif_get_iflink,
};
static void reg_vif_setup(struct net_device *dev)
{
dev->type = ARPHRD_PIMREG;
dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 8;
dev->flags = IFF_NOARP;
dev->netdev_ops = ®_vif_netdev_ops;
dev->needs_free_netdev = true;
dev->netns_immutable = true;
}
static struct net_device *ipmr_reg_vif(struct net *net, struct mr_table *mrt)
{
struct net_device *dev;
char name[IFNAMSIZ];
if (mrt->id == RT_TABLE_DEFAULT)
sprintf(name, "pimreg");
else
sprintf(name, "pimreg%u", mrt->id);
dev = alloc_netdev(0, name, NET_NAME_UNKNOWN, reg_vif_setup);
if (!dev)
return NULL;
dev_net_set(dev, net);
if (register_netdevice(dev)) {
free_netdev(dev);
return NULL;
}
if (!ipmr_init_vif_indev(dev))
goto failure;
if (dev_open(dev, NULL))
goto failure;
dev_hold(dev);
return dev;
failure:
unregister_netdevice(dev);
return NULL;
}
/* called with rcu_read_lock() */
static int __pim_rcv(struct mr_table *mrt, struct sk_buff *skb,
unsigned int pimlen)
{
struct net_device *reg_dev = NULL;
struct iphdr *encap;
int vif_num;
encap = (struct iphdr *)(skb_transport_header(skb) + pimlen);
/* Check that:
* a. packet is really sent to a multicast group
* b. packet is not a NULL-REGISTER
* c. packet is not truncated
*/
if (!ipv4_is_multicast(encap->daddr) ||
encap->tot_len == 0 ||
ntohs(encap->tot_len) + pimlen > skb->len)
return 1;
/* Pairs with WRITE_ONCE() in vif_add()/vid_delete() */
vif_num = READ_ONCE(mrt->mroute_reg_vif_num);
if (vif_num >= 0)
reg_dev = vif_dev_read(&mrt->vif_table[vif_num]);
if (!reg_dev)
return 1;
skb->mac_header = skb->network_header;
skb_pull(skb, (u8 *)encap - skb->data);
skb_reset_network_header(skb);
skb->protocol = htons(ETH_P_IP);
skb->ip_summed = CHECKSUM_NONE;
skb_tunnel_rx(skb, reg_dev, dev_net(reg_dev));
netif_rx(skb);
return NET_RX_SUCCESS;
}
#else
Annotation
- Immediate include surface: `linux/uaccess.h`, `linux/types.h`, `linux/cache.h`, `linux/capability.h`, `linux/errno.h`, `linux/mm.h`, `linux/kernel.h`, `linux/fcntl.h`.
- Detected declarations: `struct ipmr_rule`, `struct ipmr_result`, `struct compat_sioc_sg_req`, `struct compat_sioc_vif_req`, `function lockdep_rtnl_is_held`, `function ipmr_for_each_table`, `function ipmr_fib_lookup`, `function ipmr_rule_action`, `function ipmr_rule_match`, `function ipmr_rule_configure`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: pattern implementation candidate.
- This snippet crosses the user/kernel memory boundary; validate fault handling and access checks before translating the pattern.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
- IRQ or DMA behavior appears here, which is relevant to the selected PCIe/NVMe device path.
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.