net/ipv6/datagram.c
Source file repositories/reference/linux-study-clean/net/ipv6/datagram.c
File Facts
- System
- Linux kernel
- Corpus path
net/ipv6/datagram.c- Extension
.c- Size
- 27001 bytes
- Lines
- 1121
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/capability.hlinux/errno.hlinux/types.hlinux/kernel.hlinux/interrupt.hlinux/socket.hlinux/sockios.hlinux/in6.hlinux/ipv6.hlinux/route.hlinux/slab.hlinux/export.hlinux/icmp.hnet/ipv6.hnet/ndisc.hnet/addrconf.hnet/transp_v6.hnet/ip6_route.hnet/tcp_states.hnet/dsfield.hnet/sock_reuseport.hlinux/errqueue.hlinux/uaccess.h
Detected Declarations
function ipv6_mapped_addr_anyfunction ip6_datagram_flow_key_initfunction ip6_datagram_dst_updatefunction ip6_datagram_release_cbfunction __ip6_datagram_connectfunction ip6_datagram_connectfunction ip6_datagram_connect_v6_onlyfunction ipv6_icmp_error_rfc4884function ipv6_icmp_errorfunction ipv6_local_errorfunction ipv6_local_rxpmtufunction ipv6_datagram_support_addrfunction ip6_datagram_support_cmsgfunction ipv6_recv_errorfunction ipv6_recv_rxpmtufunction ip6_datagram_recv_common_ctlfunction ipv6_get_exthdr_lenfunction ip6_datagram_recv_specific_ctlfunction ip6_datagram_recv_ctlfunction ip6_datagram_send_ctlfunction for_each_cmsghdrfunction __ip6_dgram_sock_seq_showexport ip6_datagram_release_cbexport __ip6_datagram_connectexport ip6_datagram_connectexport ip6_datagram_connect_v6_onlyexport ipv6_icmp_errorexport ipv6_recv_errorexport ip6_datagram_recv_ctlexport ip6_datagram_send_ctl
Annotated Snippet
if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
sk->sk_v6_rcv_saddr = fl6->saddr;
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
if (sk->sk_prot->rehash)
sk->sk_prot->rehash(sk);
}
}
ip6_sk_dst_store_flow(sk, dst, fl6);
out:
fl6_sock_release(flowlabel);
return err;
}
void ip6_datagram_release_cb(struct sock *sk)
{
struct dst_entry *dst;
if (ipv6_addr_v4mapped(&sk->sk_v6_daddr))
return;
rcu_read_lock();
dst = __sk_dst_get(sk);
if (!dst || !READ_ONCE(dst->obsolete) ||
dst->ops->check(dst, inet6_sk(sk)->dst_cookie)) {
rcu_read_unlock();
return;
}
rcu_read_unlock();
ip6_datagram_dst_update(sk, false);
}
EXPORT_SYMBOL_GPL(ip6_datagram_release_cb);
int __ip6_datagram_connect(struct sock *sk, struct sockaddr_unsized *uaddr,
int addr_len)
{
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *daddr, old_daddr;
__be32 fl6_flowlabel = 0;
__be32 old_fl6_flowlabel;
__be16 old_dport;
int addr_type;
int err;
if (usin->sin6_family == AF_INET) {
if (ipv6_only_sock(sk))
return -EAFNOSUPPORT;
err = __ip4_datagram_connect(sk, uaddr, addr_len);
goto ipv4_connected;
}
if (addr_len < SIN6_LEN_RFC2133)
return -EINVAL;
if (usin->sin6_family != AF_INET6)
return -EAFNOSUPPORT;
if (inet6_test_bit(SNDFLOW, sk))
fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
if (ipv6_addr_any(&usin->sin6_addr)) {
/*
* connect to self
*/
if (ipv6_addr_v4mapped(&sk->sk_v6_rcv_saddr))
ipv6_addr_set_v4mapped(htonl(INADDR_LOOPBACK),
&usin->sin6_addr);
else
usin->sin6_addr = in6addr_loopback;
}
addr_type = ipv6_addr_type(&usin->sin6_addr);
daddr = &usin->sin6_addr;
if (addr_type & IPV6_ADDR_MAPPED) {
struct sockaddr_in sin;
if (ipv6_only_sock(sk)) {
err = -ENETUNREACH;
goto out;
}
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = daddr->s6_addr32[3];
sin.sin_port = usin->sin6_port;
Annotation
- Immediate include surface: `linux/capability.h`, `linux/errno.h`, `linux/types.h`, `linux/kernel.h`, `linux/interrupt.h`, `linux/socket.h`, `linux/sockios.h`, `linux/in6.h`.
- Detected declarations: `function ipv6_mapped_addr_any`, `function ip6_datagram_flow_key_init`, `function ip6_datagram_dst_update`, `function ip6_datagram_release_cb`, `function __ip6_datagram_connect`, `function ip6_datagram_connect`, `function ip6_datagram_connect_v6_only`, `function ipv6_icmp_error_rfc4884`, `function ipv6_icmp_error`, `function ipv6_local_error`.
- 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.