10 #include <linux/types.h>
11 #include <linux/module.h>
13 #include <linux/ipv6.h>
14 #include <linux/netfilter.h>
15 #include <linux/netfilter_ipv6.h>
31 static void nf_nat_ipv6_decode_session(
struct sk_buff *
skb,
34 unsigned long statusbit,
40 if (ct->
status & statusbit) {
47 fl6->fl6_dport = t->
dst.u.all;
52 if (ct->
status & statusbit) {
59 fl6->fl6_sport = t->
src.u.all;
77 static bool nf_nat_ipv6_manip_pkt(
struct sk_buff *skb,
78 unsigned int iphdroff,
91 ipv6h = (
void *)skb->
data + iphdroff;
98 if ((frag_off &
htons(~0x7)) == 0 &&
99 !l4proto->
manip_pkt(skb, &nf_nat_l3proto_ipv6, iphdroff, hdroff,
111 static void nf_nat_ipv6_csum_update(
struct sk_buff *skb,
117 const struct in6_addr *oldip, *newip;
120 oldip = &ipv6h->
saddr;
121 newip = &t->
src.u3.in6;
123 oldip = &ipv6h->
daddr;
124 newip = &t->
dst.u3.in6;
127 newip->s6_addr32, 1);
130 static void nf_nat_ipv6_csum_recalc(
struct sk_buff *skb,
134 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
142 skb_network_offset(skb) +
143 (data - (
void *)skb->
data);
157 inet_proto_csum_replace2(check, skb,
161 static int nf_nat_ipv6_nlattr_to_range(
struct nlattr *
tb[],
181 .secure_port = nf_nat_ipv6_secure_port,
182 .in_range = nf_nat_ipv6_in_range,
183 .manip_pkt = nf_nat_ipv6_manip_pkt,
184 .csum_update = nf_nat_ipv6_csum_update,
185 .csum_recalc = nf_nat_ipv6_csum_recalc,
186 .nlattr_to_range = nf_nat_ipv6_nlattr_to_range,
188 .decode_session = nf_nat_ipv6_decode_session,
206 unsigned long statusbit;
232 if (!(ct->
status & statusbit))
236 if (!nf_nat_ipv6_manip_pkt(skb, hdrlen +
sizeof(
inside->icmp6),
237 l4proto, &ct->
tuplehash[!dir].tuple, !manip))
241 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
243 inside->icmp6.icmp6_cksum = 0;
244 inside->icmp6.icmp6_cksum =
248 skb->
len - hdrlen, 0));
253 if (!nf_nat_ipv6_manip_pkt(skb, 0, l4proto, &target, manip))
260 static int __init nf_nat_l3proto_ipv6_init(
void)
278 static void __exit nf_nat_l3proto_ipv6_exit(
void)