net/ipv6/route.c
Source file repositories/reference/linux-study-clean/net/ipv6/route.c
File Facts
- System
- Linux kernel
- Corpus path
net/ipv6/route.c- Extension
.c- Size
- 175181 bytes
- Lines
- 6995
- Domain
- Networking Core
- Bucket
- Sockets, Protocols, Packet Path, And Network Policy
- Inferred role
- Networking Core: exported/initcall integration point
- Status
- integration 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.
- Exports symbols or registers init work; inspect boot/module ordering and who consumes the exported contract.
- 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/capability.hlinux/errno.hlinux/export.hlinux/types.hlinux/times.hlinux/socket.hlinux/sockios.hlinux/net.hlinux/route.hlinux/netdevice.hlinux/in6.hlinux/mroute6.hlinux/init.hlinux/if_arp.hlinux/proc_fs.hlinux/seq_file.hlinux/nsproxy.hlinux/slab.hlinux/jhash.hlinux/siphash.hnet/net_namespace.hnet/snmp.hnet/ipv6.hnet/ip6_fib.hnet/ip6_route.hnet/ndisc.hnet/addrconf.hnet/tcp.hlinux/rtnetlink.hnet/dst.hnet/dst_metadata.hnet/xfrm.h
Detected Declarations
struct uncached_liststruct fib6_nh_dm_argstruct __rt6_probe_workstruct fib6_nh_frl_argstruct fib6_nh_excptn_argstruct fib6_nh_match_argstruct fib6_nh_age_excptn_argstruct fib6_nh_rd_argstruct ip6rd_flowistruct fib6_nh_del_cached_rt_argstruct arg_dev_net_ipstruct arg_netdev_eventstruct rt6_mtu_change_argstruct rt6_nhstruct fib6_nh_exception_dump_walkerenum rt6_nud_statefunction rt6_uncached_list_addfunction rt6_uncached_list_delfunction rt6_uncached_list_flush_devfunction for_each_possible_cpufunction list_for_each_entry_safefunction ip6_confirm_neighfunction rt6_info_initfunction ip6_dst_destroyfunction ip6_dst_ifdownfunction __rt6_check_expiredfunction rt6_check_expiredfunction rt6_multipath_first_sibling_rcufunction fib6_select_pathfunction list_for_each_entry_rcufunction __rt6_device_matchfunction __rt6_nh_dev_matchfunction rt6_device_matchfunction rt6_probe_deferredfunction rt6_probefunction READ_ONCEfunction rt6_probefunction rt6_score_routefunction find_matchfunction rt6_nh_find_matchfunction __find_rr_leaffunction find_rr_leaffunction rt6_selectfunction rt6_is_gw_or_nonexthopfunction rt6_route_rcvfunction ip6_rt_type_to_errorfunction fib6_info_dst_flagsfunction ip6_rt_init_dst_reject
Annotated Snippet
struct uncached_list {
spinlock_t lock;
struct list_head head;
};
static DEFINE_PER_CPU_ALIGNED(struct uncached_list, rt6_uncached_list);
void rt6_uncached_list_add(struct rt6_info *rt)
{
struct uncached_list *ul = raw_cpu_ptr(&rt6_uncached_list);
rt->dst.rt_uncached_list = ul;
spin_lock_bh(&ul->lock);
list_add_tail(&rt->dst.rt_uncached, &ul->head);
spin_unlock_bh(&ul->lock);
}
void rt6_uncached_list_del(struct rt6_info *rt)
{
struct uncached_list *ul = rt->dst.rt_uncached_list;
if (ul) {
spin_lock_bh(&ul->lock);
list_del_init(&rt->dst.rt_uncached);
spin_unlock_bh(&ul->lock);
}
}
static void rt6_uncached_list_flush_dev(struct net_device *dev)
{
int cpu;
for_each_possible_cpu(cpu) {
struct uncached_list *ul = per_cpu_ptr(&rt6_uncached_list, cpu);
struct rt6_info *rt, *safe;
if (list_empty(&ul->head))
continue;
spin_lock_bh(&ul->lock);
list_for_each_entry_safe(rt, safe, &ul->head, dst.rt_uncached) {
struct inet6_dev *rt_idev = rt->rt6i_idev;
struct net_device *rt_dev = rt->dst.dev;
bool handled = false;
if (rt_idev && rt_idev->dev == dev) {
rt->rt6i_idev = in6_dev_get(blackhole_netdev);
in6_dev_put(rt_idev);
handled = true;
}
if (rt_dev == dev) {
rt->dst.dev = blackhole_netdev;
netdev_ref_replace(rt_dev, blackhole_netdev,
&rt->dst.dev_tracker,
GFP_ATOMIC);
handled = true;
}
if (handled)
list_del_init(&rt->dst.rt_uncached);
}
spin_unlock_bh(&ul->lock);
}
}
static inline const void *choose_neigh_daddr(const struct in6_addr *p,
struct sk_buff *skb,
const void *daddr)
{
if (!ipv6_addr_any(p))
return (const void *) p;
else if (skb)
return &ipv6_hdr(skb)->daddr;
return daddr;
}
struct neighbour *ip6_neigh_lookup(const struct in6_addr *gw,
struct net_device *dev,
struct sk_buff *skb,
const void *daddr)
{
struct neighbour *n;
daddr = choose_neigh_daddr(gw, skb, daddr);
n = __ipv6_neigh_lookup(dev, daddr);
if (n)
return n;
n = neigh_create(&nd_tbl, daddr, dev);
Annotation
- Immediate include surface: `linux/capability.h`, `linux/errno.h`, `linux/export.h`, `linux/types.h`, `linux/times.h`, `linux/socket.h`, `linux/sockios.h`, `linux/net.h`.
- Detected declarations: `struct uncached_list`, `struct fib6_nh_dm_arg`, `struct __rt6_probe_work`, `struct fib6_nh_frl_arg`, `struct fib6_nh_excptn_arg`, `struct fib6_nh_match_arg`, `struct fib6_nh_age_excptn_arg`, `struct fib6_nh_rd_arg`, `struct ip6rd_flowi`, `struct fib6_nh_del_cached_rt_arg`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: integration 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.