12 #include <linux/types.h>
13 #include <linux/ipv6.h>
14 #include <linux/in6.h>
15 #include <linux/netfilter.h>
16 #include <linux/module.h>
18 #include <linux/icmp.h>
22 #include <linux/netfilter_bridge.h>
23 #include <linux/netfilter_ipv6.h>
35 static bool ipv6_pkt_to_tuple(
const struct sk_buff *
skb,
unsigned int nhoff,
42 sizeof(_addrs), _addrs);
46 memcpy(tuple->
src.u3.ip6, ap,
sizeof(tuple->
src.u3.ip6));
47 memcpy(tuple->
dst.u3.ip6, ap + 4,
sizeof(tuple->
dst.u3.ip6));
61 static int ipv6_print_tuple(
struct seq_file *
s,
65 tuple->
src.u3.ip6, tuple->
dst.u3.ip6);
68 static int ipv6_get_l4proto(
const struct sk_buff *skb,
unsigned int nhoff,
69 unsigned int *dataoff,
u_int8_t *protonum)
71 unsigned int extoff = nhoff +
sizeof(
struct ipv6hdr);
77 &nexthdr,
sizeof(nexthdr)) != 0) {
78 pr_debug(
"ip6_conntrack_core: can't get nexthdr\n");
86 if (protoff < 0 || (frag_off &
htons(~0x7)) != 0) {
87 pr_debug(
"ip6_conntrack_core: can't find proto in pkt\n");
96 static unsigned int ipv6_helper(
unsigned int hooknum,
112 ct = nf_ct_get(skb, &ctinfo);
116 help = nfct_help(ct);
124 nexthdr = ipv6_hdr(skb)->nexthdr;
127 if (protoff < 0 || (frag_off &
htons(~0x7)) != 0) {
128 pr_debug(
"proto header not found\n");
132 ret = helper->
help(skb, protoff, ct, ctinfo);
135 "nf_ct_%s: dropping packet", helper->
name);
140 static unsigned int ipv6_confirm(
unsigned int hooknum,
148 unsigned char pnum = ipv6_hdr(skb)->nexthdr;
152 ct = nf_ct_get(skb, &ctinfo);
158 if (protoff < 0 || (frag_off &
htons(~0x7)) != 0) {
159 pr_debug(
"proto header not found\n");
165 !nf_is_loopback_packet(skb)) {
170 !seq_adjust(skb, ct, ctinfo, protoff)) {
177 return nf_conntrack_confirm(skb);
180 static unsigned int __ipv6_conntrack_in(
struct net *
net,
181 unsigned int hooknum,
187 struct sk_buff *reasm = skb->nfct_reasm;
208 ct = nf_ct_get(reasm, &ctinfo);
209 if (ct !=
NULL && !nf_ct_is_untracked(ct)) {
210 help = nfct_help(ct);
211 if ((help && help->
helper) || !nf_ct_is_confirmed(ct)) {
212 nf_conntrack_get_reasm(skb);
221 nf_conntrack_get(reasm->nfct);
222 skb->nfct = reasm->nfct;
230 static unsigned int ipv6_conntrack_in(
unsigned int hooknum,
236 return __ipv6_conntrack_in(dev_net(in), hooknum, skb, in, out, okfn);
239 static unsigned int ipv6_conntrack_local(
unsigned int hooknum,
250 return __ipv6_conntrack_in(dev_net(out), hooknum, skb, in, out, okfn);
253 static struct nf_hook_ops ipv6_conntrack_ops[]
__read_mostly = {
255 .hook = ipv6_conntrack_in,
262 .hook = ipv6_conntrack_local,
276 .hook = ipv6_confirm,
290 .hook = ipv6_confirm,
298 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
300 #include <linux/netfilter/nfnetlink.h>
303 static int ipv6_tuple_to_nlattr(
struct sk_buff *skb,
307 &tuple->
src.u3.ip6) ||
310 goto nla_put_failure;
322 static int ipv6_nlattr_to_tuple(
struct nlattr *
tb[],
330 memcpy(&t->
dst.u3.ip6, nla_data(tb[CTA_IP_V6_DST]),
336 static int ipv6_nlattr_tuple_size(
void)
345 .pkt_to_tuple = ipv6_pkt_to_tuple,
346 .invert_tuple = ipv6_invert_tuple,
347 .print_tuple = ipv6_print_tuple,
348 .get_l4proto = ipv6_get_l4proto,
349 #if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
350 .tuple_to_nlattr = ipv6_tuple_to_nlattr,
351 .nlattr_tuple_size = ipv6_nlattr_tuple_size,
352 .nlattr_to_tuple = ipv6_nlattr_to_tuple,
353 .nla_policy = ipv6_nla_policy,
362 static int ipv6_net_init(
struct net *net)
367 &nf_conntrack_l4proto_tcp6);
369 printk(
KERN_ERR "nf_conntrack_l4proto_tcp6: protocol register failed\n");
373 &nf_conntrack_l4proto_udp6);
375 printk(
KERN_ERR "nf_conntrack_l4proto_udp6: protocol register failed\n");
379 &nf_conntrack_l4proto_icmpv6);
381 printk(
KERN_ERR "nf_conntrack_l4proto_icmp6: protocol register failed\n");
385 &nf_conntrack_l3proto_ipv6);
387 printk(
KERN_ERR "nf_conntrack_l3proto_ipv6: protocol register failed\n");
393 &nf_conntrack_l4proto_icmpv6);
396 &nf_conntrack_l4proto_udp6);
399 &nf_conntrack_l4proto_tcp6);
404 static void ipv6_net_exit(
struct net *net)
407 &nf_conntrack_l3proto_ipv6);
409 &nf_conntrack_l4proto_icmpv6);
411 &nf_conntrack_l4proto_udp6);
413 &nf_conntrack_l4proto_tcp6);
417 .init = ipv6_net_init,
418 .exit = ipv6_net_exit,
421 static int __init nf_conntrack_l3proto_ipv6_init(
void)
434 pr_err(
"nf_conntrack_ipv6: can't register pre-routing defrag "
446 static void __exit nf_conntrack_l3proto_ipv6_fini(
void)