12 #include <linux/module.h>
13 #include <linux/netfilter.h>
14 #include <linux/netfilter_ipv6.h>
15 #include <linux/netfilter_ipv6/ip6_tables.h>
16 #include <linux/ipv6.h>
23 static const struct xt_table nf_nat_ipv6_table = {
33 static unsigned int alloc_null_binding(
struct nf_conn *
ct,
unsigned int hooknum)
41 pr_debug(
"Allocating NULL binding for %p (%pI6)\n", ct,
49 static unsigned int nf_nat_rule_find(
struct sk_buff *
skb,
unsigned int hooknum,
54 struct net *
net = nf_ct_net(ct);
57 ret =
ip6t_do_table(skb, hooknum, in, out, net->ipv6.ip6table_nat);
59 if (!nf_nat_initialized(ct,
HOOK2MANIP(hooknum)))
60 ret = alloc_null_binding(ct, hooknum);
66 nf_nat_ipv6_fn(
unsigned int hooknum,
80 ct = nf_ct_get(skb, &ctinfo);
90 if (nf_ct_is_untracked(ct))
96 if (nf_ct_is_confirmed(ct))
100 pr_debug(
"failed to add NAT extension\n");
108 nexthdr = ipv6_hdr(skb)->nexthdr;
110 &nexthdr, &frag_off);
124 if (!nf_nat_initialized(ct, maniptype)) {
127 ret = nf_nat_rule_find(skb, hooknum, in, out, ct);
131 pr_debug(
"Already setup manip %s for ct %p\n",
146 nf_nat_ipv6_in(
unsigned int hooknum,
155 ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
157 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
164 nf_nat_ipv6_out(
unsigned int hooknum,
180 ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
184 (ct = nf_ct_get(skb, &ctinfo)) !=
NULL) {
187 if (!nf_inet_addr_cmp(&ct->
tuplehash[dir].tuple.src.u3,
200 nf_nat_ipv6_local_fn(
unsigned int hooknum,
214 ret = nf_nat_ipv6_fn(hooknum, skb, in, out, okfn);
216 (ct = nf_ct_get(skb, &ctinfo)) !=
NULL) {
219 if (!nf_inet_addr_cmp(&ct->
tuplehash[dir].tuple.dst.u3,
225 else if (!(
IP6CB(skb)->
flags & IP6SKB_XFRM_TRANSFORMED) &&
236 static struct nf_hook_ops nf_nat_ipv6_ops[]
__read_mostly = {
239 .hook = nf_nat_ipv6_in,
247 .hook = nf_nat_ipv6_out,
255 .hook = nf_nat_ipv6_local_fn,
263 .hook = nf_nat_ipv6_fn,
271 static int __net_init ip6table_nat_net_init(
struct net *net)
280 if (IS_ERR(net->ipv6.ip6table_nat))
281 return PTR_ERR(net->ipv6.ip6table_nat);
285 static void __net_exit ip6table_nat_net_exit(
struct net *net)
291 .init = ip6table_nat_net_init,
292 .exit = ip6table_nat_net_exit,
295 static int __init ip6table_nat_init(
void)
314 static void __exit ip6table_nat_exit(
void)