net/netfilter/nf_conntrack_proto_icmpv6.c
Source file repositories/reference/linux-study-clean/net/netfilter/nf_conntrack_proto_icmpv6.c
File Facts
- System
- Linux kernel
- Corpus path
net/netfilter/nf_conntrack_proto_icmpv6.c- Extension
.c- Size
- 9958 bytes
- Lines
- 363
- 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.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/types.hlinux/timer.hlinux/module.hlinux/netfilter.hlinux/in6.hlinux/icmpv6.hlinux/ipv6.hnet/ipv6.hnet/ip6_checksum.hlinux/seq_file.hlinux/netfilter_ipv6.hnet/netfilter/nf_conntrack_tuple.hnet/netfilter/nf_conntrack_l4proto.hnet/netfilter/nf_conntrack_core.hnet/netfilter/nf_conntrack_timeout.hnet/netfilter/nf_conntrack_zones.hnet/netfilter/nf_log.hnf_internals.hlinux/netfilter/nfnetlink.hlinux/netfilter/nfnetlink_conntrack.hlinux/netfilter/nfnetlink_cttimeout.h
Detected Declarations
function icmpv6_pkt_to_tuplefunction nf_conntrack_invert_icmpv6_tuplefunction nf_conntrack_icmpv6_packetfunction icmpv6_error_logfunction nf_conntrack_icmpv6_redirectfunction nf_conntrack_icmpv6_errorfunction icmpv6_tuple_to_nlattrfunction icmpv6_nlattr_to_tuplefunction icmpv6_nlattr_tuple_sizefunction icmpv6_timeout_nlattr_to_objfunction icmpv6_timeout_obj_to_nlattrfunction nf_conntrack_icmpv6_init_net
Annotated Snippet
if (type < 0 || type >= sizeof(valid_new) || !valid_new[type]) {
/* Can't create a new ICMPv6 `conn' with this. */
pr_debug("icmpv6: can't create new conn with type %u\n",
type + 128);
nf_ct_dump_tuple_ipv6(&ct->tuplehash[0].tuple);
return -NF_ACCEPT;
}
}
if (!timeout)
timeout = icmpv6_get_timeouts(nf_ct_net(ct));
/* Do not immediately delete the connection after the first
successful reply to avoid excessive conntrackd traffic
and also to handle correctly ICMP echo reply duplicates. */
nf_ct_refresh_acct(ct, ctinfo, skb, *timeout);
return NF_ACCEPT;
}
static void icmpv6_error_log(const struct sk_buff *skb,
const struct nf_hook_state *state,
const char *msg)
{
nf_l4proto_log_invalid(skb, state, IPPROTO_ICMPV6, "%s", msg);
}
static noinline_for_stack int
nf_conntrack_icmpv6_redirect(struct nf_conn *tmpl, struct sk_buff *skb,
unsigned int dataoff,
const struct nf_hook_state *state)
{
u8 hl = ipv6_hdr(skb)->hop_limit;
union nf_inet_addr outer_daddr;
union {
struct nd_opt_hdr nd_opt;
struct rd_msg rd_msg;
} tmp;
const struct nd_opt_hdr *nd_opt;
const struct rd_msg *rd_msg;
rd_msg = skb_header_pointer(skb, dataoff, sizeof(*rd_msg), &tmp.rd_msg);
if (!rd_msg) {
icmpv6_error_log(skb, state, "short redirect");
return -NF_ACCEPT;
}
if (rd_msg->icmph.icmp6_code != 0)
return NF_ACCEPT;
if (hl != 255 || !(ipv6_addr_type(&ipv6_hdr(skb)->saddr) & IPV6_ADDR_LINKLOCAL)) {
icmpv6_error_log(skb, state, "invalid saddr or hoplimit for redirect");
return -NF_ACCEPT;
}
dataoff += sizeof(*rd_msg);
/* warning: rd_msg no longer usable after this call */
nd_opt = skb_header_pointer(skb, dataoff, sizeof(*nd_opt), &tmp.nd_opt);
if (!nd_opt || nd_opt->nd_opt_len == 0) {
icmpv6_error_log(skb, state, "redirect without options");
return -NF_ACCEPT;
}
/* We could call ndisc_parse_options(), but it would need
* skb_linearize() and a bit more work.
*/
if (nd_opt->nd_opt_type != ND_OPT_REDIRECT_HDR)
return NF_ACCEPT;
memcpy(&outer_daddr.ip6, &ipv6_hdr(skb)->daddr,
sizeof(outer_daddr.ip6));
dataoff += 8;
return nf_conntrack_inet_error(tmpl, skb, dataoff, state,
IPPROTO_ICMPV6, &outer_daddr);
}
int nf_conntrack_icmpv6_error(struct nf_conn *tmpl,
struct sk_buff *skb,
unsigned int dataoff,
const struct nf_hook_state *state)
{
union nf_inet_addr outer_daddr;
const struct icmp6hdr *icmp6h;
struct icmp6hdr _ih;
int type;
icmp6h = skb_header_pointer(skb, dataoff, sizeof(_ih), &_ih);
if (icmp6h == NULL) {
Annotation
- Immediate include surface: `linux/types.h`, `linux/timer.h`, `linux/module.h`, `linux/netfilter.h`, `linux/in6.h`, `linux/icmpv6.h`, `linux/ipv6.h`, `net/ipv6.h`.
- Detected declarations: `function icmpv6_pkt_to_tuple`, `function nf_conntrack_invert_icmpv6_tuple`, `function nf_conntrack_icmpv6_packet`, `function icmpv6_error_log`, `function nf_conntrack_icmpv6_redirect`, `function nf_conntrack_icmpv6_error`, `function icmpv6_tuple_to_nlattr`, `function icmpv6_nlattr_to_tuple`, `function icmpv6_nlattr_tuple_size`, `function icmpv6_timeout_nlattr_to_obj`.
- Atlas domain: Networking Core / Sockets, Protocols, Packet Path, And Network Policy.
- Implementation status: source implementation candidate.
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.