net/ipv6/xfrm6_input.c
Source file repositories/reference/linux-study-clean/net/ipv6/xfrm6_input.c
File Facts
- System
- Linux kernel
- Corpus path
net/ipv6/xfrm6_input.c- Extension
.c- Size
- 7679 bytes
- Lines
- 326
- 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/module.hlinux/string.hlinux/netfilter.hlinux/netfilter_ipv6.hnet/ipv6.hnet/xfrm.hnet/protocol.hnet/gro.h
Detected Declarations
function xfrm6_rcv_spifunction xfrm6_transport_finish2function xfrm6_transport_finishfunction __xfrm6_udp_encap_rcvfunction xfrm6_udp_encap_rcvfunction xfrm6_rcv_tnlfunction xfrm6_rcvfunction xfrm6_input_addrexport xfrm6_rcv_spiexport xfrm6_rcv_tnlexport xfrm6_rcvexport xfrm6_input_addr
Annotated Snippet
if (len == 1 && udpdata[0] == 0xff) {
return -EINVAL;
} else if (len > sizeof(struct ip_esp_hdr) && udpdata32[0] != 0) {
/* ESP Packet without Non-ESP header */
len = sizeof(struct udphdr);
} else
/* Must be an IKE packet.. pass it through */
return 1;
break;
}
/* At this point we are sure that this is an ESPinUDP packet,
* so we need to remove 'len' bytes from the packet (the UDP
* header and optional ESP marker bytes) and then modify the
* protocol to ESP, and then call into the transform receiver.
*/
if (skb_unclone(skb, GFP_ATOMIC))
return -EINVAL;
/* Now we can update and verify the packet length... */
ip6h = ipv6_hdr(skb);
ip6h->payload_len = htons(ntohs(ip6h->payload_len) - len);
if (skb->len < ip6hlen + len) {
/* packet is too small!?! */
return -EINVAL;
}
/* pull the data buffer up to the ESP header and set the
* transport header to point to ESP. Keep UDP on the stack
* for later.
*/
if (pull) {
__skb_pull(skb, len);
skb_reset_transport_header(skb);
} else {
skb_set_transport_header(skb, len);
}
/* process ESP */
return 0;
}
/* If it's a keepalive packet, then just eat it.
* If it's an encapsulated packet, then pass it to the
* IPsec xfrm input.
* Returns 0 if skb passed to xfrm or was dropped.
* Returns >0 if skb should be passed to UDP.
* Returns <0 if skb should be resubmitted (-ret is protocol)
*/
int xfrm6_udp_encap_rcv(struct sock *sk, struct sk_buff *skb)
{
int ret;
if (skb->protocol == htons(ETH_P_IP))
return xfrm4_udp_encap_rcv(sk, skb);
ret = __xfrm6_udp_encap_rcv(sk, skb, true);
if (!ret)
return xfrm6_rcv_encap(skb, IPPROTO_ESP, 0,
udp_sk(sk)->encap_type);
if (ret < 0) {
kfree_skb(skb);
return 0;
}
return ret;
}
struct sk_buff *xfrm6_gro_udp_encap_rcv(struct sock *sk, struct list_head *head,
struct sk_buff *skb)
{
int offset = skb_gro_offset(skb);
const struct net_offload *ops;
struct sk_buff *pp = NULL;
int len, dlen;
__u8 *udpdata;
__be32 *udpdata32;
if (skb->protocol == htons(ETH_P_IP))
return xfrm4_gro_udp_encap_rcv(sk, head, skb);
len = skb->len - offset;
dlen = offset + min(len, 8);
udpdata = skb_gro_header(skb, dlen, offset);
udpdata32 = (__be32 *)udpdata;
if (unlikely(!udpdata))
return NULL;
rcu_read_lock();
Annotation
- Immediate include surface: `linux/module.h`, `linux/string.h`, `linux/netfilter.h`, `linux/netfilter_ipv6.h`, `net/ipv6.h`, `net/xfrm.h`, `net/protocol.h`, `net/gro.h`.
- Detected declarations: `function xfrm6_rcv_spi`, `function xfrm6_transport_finish2`, `function xfrm6_transport_finish`, `function __xfrm6_udp_encap_rcv`, `function xfrm6_udp_encap_rcv`, `function xfrm6_rcv_tnl`, `function xfrm6_rcv`, `function xfrm6_input_addr`, `export xfrm6_rcv_spi`, `export xfrm6_rcv_tnl`.
- 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.