aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-08-25 06:05:27 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2014-09-09 10:30:00 -0400
commit2a5538e9aa4929329813bee69922c9ae4990fcad (patch)
tree66f4331151c6695ca4d0e174d0c233847de22862 /net
parent65cd90ac765fb6960f1e3815cc31972fc4599c37 (diff)
netfilter: nat: move specific NAT IPv6 to core
Move the specific NAT IPv6 core functions that are called from the hooks from ip6table_nat.c to nf_nat_l3proto_ipv6.c. This prepares the ground to allow iptables and nft to use the same NAT engine code that comes in a follow up patch. This also renames nf_nat_ipv6_fn to nft_nat_ipv6_fn in net/ipv6/netfilter/nft_chain_nat_ipv6.c to avoid a compilation breakage. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/netfilter/ip6table_nat.c233
-rw-r--r--net/ipv6/netfilter/nf_nat_l3proto_ipv6.c199
-rw-r--r--net/ipv6/netfilter/nft_chain_nat_ipv6.c10
3 files changed, 238 insertions, 204 deletions
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index 387d8b8fc18d..b0634ac996b7 100644
--- a/net/ipv6/netfilter/ip6table_nat.c
+++ b/net/ipv6/netfilter/ip6table_nat.c
@@ -30,222 +30,57 @@ static const struct xt_table nf_nat_ipv6_table = {
30 .af = NFPROTO_IPV6, 30 .af = NFPROTO_IPV6,
31}; 31};
32 32
33static unsigned int alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) 33static unsigned int ip6table_nat_do_chain(const struct nf_hook_ops *ops,
34{ 34 struct sk_buff *skb,
35 /* Force range to this IP; let proto decide mapping for 35 const struct net_device *in,
36 * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). 36 const struct net_device *out,
37 */ 37 struct nf_conn *ct)
38 struct nf_nat_range range;
39
40 range.flags = 0;
41 pr_debug("Allocating NULL binding for %p (%pI6)\n", ct,
42 HOOK2MANIP(hooknum) == NF_NAT_MANIP_SRC ?
43 &ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3.ip6 :
44 &ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3.ip6);
45
46 return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum));
47}
48
49static unsigned int nf_nat_rule_find(struct sk_buff *skb, unsigned int hooknum,
50 const struct net_device *in,
51 const struct net_device *out,
52 struct nf_conn *ct)
53{ 38{
54 struct net *net = nf_ct_net(ct); 39 struct net *net = nf_ct_net(ct);
55 unsigned int ret;
56 40
57 ret = ip6t_do_table(skb, hooknum, in, out, net->ipv6.ip6table_nat); 41 return ip6t_do_table(skb, ops->hooknum, in, out, net->ipv6.ip6table_nat);
58 if (ret == NF_ACCEPT) {
59 if (!nf_nat_initialized(ct, HOOK2MANIP(hooknum)))
60 ret = alloc_null_binding(ct, hooknum);
61 }
62 return ret;
63} 42}
64 43
65static unsigned int 44static unsigned int ip6table_nat_fn(const struct nf_hook_ops *ops,
66nf_nat_ipv6_fn(const struct nf_hook_ops *ops, 45 struct sk_buff *skb,
67 struct sk_buff *skb, 46 const struct net_device *in,
68 const struct net_device *in, 47 const struct net_device *out,
69 const struct net_device *out, 48 int (*okfn)(struct sk_buff *))
70 int (*okfn)(struct sk_buff *))
71{ 49{
72 struct nf_conn *ct; 50 return nf_nat_ipv6_fn(ops, skb, in, out, ip6table_nat_do_chain);
73 enum ip_conntrack_info ctinfo;
74 struct nf_conn_nat *nat;
75 enum nf_nat_manip_type maniptype = HOOK2MANIP(ops->hooknum);
76 __be16 frag_off;
77 int hdrlen;
78 u8 nexthdr;
79
80 ct = nf_ct_get(skb, &ctinfo);
81 /* Can't track? It's not due to stress, or conntrack would
82 * have dropped it. Hence it's the user's responsibilty to
83 * packet filter it out, or implement conntrack/NAT for that
84 * protocol. 8) --RR
85 */
86 if (!ct)
87 return NF_ACCEPT;
88
89 /* Don't try to NAT if this packet is not conntracked */
90 if (nf_ct_is_untracked(ct))
91 return NF_ACCEPT;
92
93 nat = nf_ct_nat_ext_add(ct);
94 if (nat == NULL)
95 return NF_ACCEPT;
96
97 switch (ctinfo) {
98 case IP_CT_RELATED:
99 case IP_CT_RELATED_REPLY:
100 nexthdr = ipv6_hdr(skb)->nexthdr;
101 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
102 &nexthdr, &frag_off);
103
104 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
105 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
106 ops->hooknum,
107 hdrlen))
108 return NF_DROP;
109 else
110 return NF_ACCEPT;
111 }
112 /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
113 case IP_CT_NEW:
114 /* Seen it before? This can happen for loopback, retrans,
115 * or local packets.
116 */
117 if (!nf_nat_initialized(ct, maniptype)) {
118 unsigned int ret;
119
120 ret = nf_nat_rule_find(skb, ops->hooknum, in, out, ct);
121 if (ret != NF_ACCEPT)
122 return ret;
123 } else {
124 pr_debug("Already setup manip %s for ct %p\n",
125 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
126 ct);
127 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
128 goto oif_changed;
129 }
130 break;
131
132 default:
133 /* ESTABLISHED */
134 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
135 ctinfo == IP_CT_ESTABLISHED_REPLY);
136 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
137 goto oif_changed;
138 }
139
140 return nf_nat_packet(ct, ctinfo, ops->hooknum, skb);
141
142oif_changed:
143 nf_ct_kill_acct(ct, ctinfo, skb);
144 return NF_DROP;
145} 51}
146 52
147static unsigned int 53static unsigned int ip6table_nat_in(const struct nf_hook_ops *ops,
148nf_nat_ipv6_in(const struct nf_hook_ops *ops, 54 struct sk_buff *skb,
149 struct sk_buff *skb, 55 const struct net_device *in,
150 const struct net_device *in, 56 const struct net_device *out,
151 const struct net_device *out, 57 int (*okfn)(struct sk_buff *))
152 int (*okfn)(struct sk_buff *))
153{ 58{
154 unsigned int ret; 59 return nf_nat_ipv6_in(ops, skb, in, out, ip6table_nat_do_chain);
155 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
156
157 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
158 if (ret != NF_DROP && ret != NF_STOLEN &&
159 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
160 skb_dst_drop(skb);
161
162 return ret;
163} 60}
164 61
165static unsigned int 62static unsigned int ip6table_nat_out(const struct nf_hook_ops *ops,
166nf_nat_ipv6_out(const struct nf_hook_ops *ops, 63 struct sk_buff *skb,
167 struct sk_buff *skb, 64 const struct net_device *in,
168 const struct net_device *in, 65 const struct net_device *out,
169 const struct net_device *out, 66 int (*okfn)(struct sk_buff *))
170 int (*okfn)(struct sk_buff *))
171{ 67{
172#ifdef CONFIG_XFRM 68 return nf_nat_ipv6_out(ops, skb, in, out, ip6table_nat_do_chain);
173 const struct nf_conn *ct;
174 enum ip_conntrack_info ctinfo;
175 int err;
176#endif
177 unsigned int ret;
178
179 /* root is playing with raw sockets. */
180 if (skb->len < sizeof(struct ipv6hdr))
181 return NF_ACCEPT;
182
183 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
184#ifdef CONFIG_XFRM
185 if (ret != NF_DROP && ret != NF_STOLEN &&
186 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
187 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
188 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
189
190 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
191 &ct->tuplehash[!dir].tuple.dst.u3) ||
192 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
193 ct->tuplehash[dir].tuple.src.u.all !=
194 ct->tuplehash[!dir].tuple.dst.u.all)) {
195 err = nf_xfrm_me_harder(skb, AF_INET6);
196 if (err < 0)
197 ret = NF_DROP_ERR(err);
198 }
199 }
200#endif
201 return ret;
202} 69}
203 70
204static unsigned int 71static unsigned int ip6table_nat_local_fn(const struct nf_hook_ops *ops,
205nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, 72 struct sk_buff *skb,
206 struct sk_buff *skb, 73 const struct net_device *in,
207 const struct net_device *in, 74 const struct net_device *out,
208 const struct net_device *out, 75 int (*okfn)(struct sk_buff *))
209 int (*okfn)(struct sk_buff *))
210{ 76{
211 const struct nf_conn *ct; 77 return nf_nat_ipv6_local_fn(ops, skb, in, out, ip6table_nat_do_chain);
212 enum ip_conntrack_info ctinfo;
213 unsigned int ret;
214 int err;
215
216 /* root is playing with raw sockets. */
217 if (skb->len < sizeof(struct ipv6hdr))
218 return NF_ACCEPT;
219
220 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn);
221 if (ret != NF_DROP && ret != NF_STOLEN &&
222 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
223 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
224
225 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
226 &ct->tuplehash[!dir].tuple.src.u3)) {
227 err = ip6_route_me_harder(skb);
228 if (err < 0)
229 ret = NF_DROP_ERR(err);
230 }
231#ifdef CONFIG_XFRM
232 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
233 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
234 ct->tuplehash[dir].tuple.dst.u.all !=
235 ct->tuplehash[!dir].tuple.src.u.all) {
236 err = nf_xfrm_me_harder(skb, AF_INET6);
237 if (err < 0)
238 ret = NF_DROP_ERR(err);
239 }
240#endif
241 }
242 return ret;
243} 78}
244 79
245static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = { 80static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
246 /* Before packet filtering, change destination */ 81 /* Before packet filtering, change destination */
247 { 82 {
248 .hook = nf_nat_ipv6_in, 83 .hook = ip6table_nat_in,
249 .owner = THIS_MODULE, 84 .owner = THIS_MODULE,
250 .pf = NFPROTO_IPV6, 85 .pf = NFPROTO_IPV6,
251 .hooknum = NF_INET_PRE_ROUTING, 86 .hooknum = NF_INET_PRE_ROUTING,
@@ -253,7 +88,7 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
253 }, 88 },
254 /* After packet filtering, change source */ 89 /* After packet filtering, change source */
255 { 90 {
256 .hook = nf_nat_ipv6_out, 91 .hook = ip6table_nat_out,
257 .owner = THIS_MODULE, 92 .owner = THIS_MODULE,
258 .pf = NFPROTO_IPV6, 93 .pf = NFPROTO_IPV6,
259 .hooknum = NF_INET_POST_ROUTING, 94 .hooknum = NF_INET_POST_ROUTING,
@@ -261,7 +96,7 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
261 }, 96 },
262 /* Before packet filtering, change destination */ 97 /* Before packet filtering, change destination */
263 { 98 {
264 .hook = nf_nat_ipv6_local_fn, 99 .hook = ip6table_nat_local_fn,
265 .owner = THIS_MODULE, 100 .owner = THIS_MODULE,
266 .pf = NFPROTO_IPV6, 101 .pf = NFPROTO_IPV6,
267 .hooknum = NF_INET_LOCAL_OUT, 102 .hooknum = NF_INET_LOCAL_OUT,
@@ -269,7 +104,7 @@ static struct nf_hook_ops nf_nat_ipv6_ops[] __read_mostly = {
269 }, 104 },
270 /* After packet filtering, change source */ 105 /* After packet filtering, change source */
271 { 106 {
272 .hook = nf_nat_ipv6_fn, 107 .hook = ip6table_nat_fn,
273 .owner = THIS_MODULE, 108 .owner = THIS_MODULE,
274 .pf = NFPROTO_IPV6, 109 .pf = NFPROTO_IPV6,
275 .hooknum = NF_INET_LOCAL_IN, 110 .hooknum = NF_INET_LOCAL_IN,
diff --git a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
index fc8e49b2ff3e..c5812e1c1ffb 100644
--- a/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_nat_l3proto_ipv6.c
@@ -261,6 +261,205 @@ int nf_nat_icmpv6_reply_translation(struct sk_buff *skb,
261} 261}
262EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation); 262EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation);
263 263
264unsigned int
265nf_nat_ipv6_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
266 const struct net_device *in, const struct net_device *out,
267 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
268 struct sk_buff *skb,
269 const struct net_device *in,
270 const struct net_device *out,
271 struct nf_conn *ct))
272{
273 struct nf_conn *ct;
274 enum ip_conntrack_info ctinfo;
275 struct nf_conn_nat *nat;
276 enum nf_nat_manip_type maniptype = HOOK2MANIP(ops->hooknum);
277 __be16 frag_off;
278 int hdrlen;
279 u8 nexthdr;
280
281 ct = nf_ct_get(skb, &ctinfo);
282 /* Can't track? It's not due to stress, or conntrack would
283 * have dropped it. Hence it's the user's responsibilty to
284 * packet filter it out, or implement conntrack/NAT for that
285 * protocol. 8) --RR
286 */
287 if (!ct)
288 return NF_ACCEPT;
289
290 /* Don't try to NAT if this packet is not conntracked */
291 if (nf_ct_is_untracked(ct))
292 return NF_ACCEPT;
293
294 nat = nf_ct_nat_ext_add(ct);
295 if (nat == NULL)
296 return NF_ACCEPT;
297
298 switch (ctinfo) {
299 case IP_CT_RELATED:
300 case IP_CT_RELATED_REPLY:
301 nexthdr = ipv6_hdr(skb)->nexthdr;
302 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
303 &nexthdr, &frag_off);
304
305 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
306 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
307 ops->hooknum,
308 hdrlen))
309 return NF_DROP;
310 else
311 return NF_ACCEPT;
312 }
313 /* Fall thru... (Only ICMPs can be IP_CT_IS_REPLY) */
314 case IP_CT_NEW:
315 /* Seen it before? This can happen for loopback, retrans,
316 * or local packets.
317 */
318 if (!nf_nat_initialized(ct, maniptype)) {
319 unsigned int ret;
320
321 ret = do_chain(ops, skb, in, out, ct);
322 if (ret != NF_ACCEPT)
323 return ret;
324
325 if (nf_nat_initialized(ct, HOOK2MANIP(ops->hooknum)))
326 break;
327
328 ret = nf_nat_alloc_null_binding(ct, ops->hooknum);
329 if (ret != NF_ACCEPT)
330 return ret;
331 } else {
332 pr_debug("Already setup manip %s for ct %p\n",
333 maniptype == NF_NAT_MANIP_SRC ? "SRC" : "DST",
334 ct);
335 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
336 goto oif_changed;
337 }
338 break;
339
340 default:
341 /* ESTABLISHED */
342 NF_CT_ASSERT(ctinfo == IP_CT_ESTABLISHED ||
343 ctinfo == IP_CT_ESTABLISHED_REPLY);
344 if (nf_nat_oif_changed(ops->hooknum, ctinfo, nat, out))
345 goto oif_changed;
346 }
347
348 return nf_nat_packet(ct, ctinfo, ops->hooknum, skb);
349
350oif_changed:
351 nf_ct_kill_acct(ct, ctinfo, skb);
352 return NF_DROP;
353}
354EXPORT_SYMBOL_GPL(nf_nat_ipv6_fn);
355
356unsigned int
357nf_nat_ipv6_in(const struct nf_hook_ops *ops, struct sk_buff *skb,
358 const struct net_device *in, const struct net_device *out,
359 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
360 struct sk_buff *skb,
361 const struct net_device *in,
362 const struct net_device *out,
363 struct nf_conn *ct))
364{
365 unsigned int ret;
366 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
367
368 ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain);
369 if (ret != NF_DROP && ret != NF_STOLEN &&
370 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
371 skb_dst_drop(skb);
372
373 return ret;
374}
375EXPORT_SYMBOL_GPL(nf_nat_ipv6_in);
376
377unsigned int
378nf_nat_ipv6_out(const struct nf_hook_ops *ops, struct sk_buff *skb,
379 const struct net_device *in, const struct net_device *out,
380 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
381 struct sk_buff *skb,
382 const struct net_device *in,
383 const struct net_device *out,
384 struct nf_conn *ct))
385{
386#ifdef CONFIG_XFRM
387 const struct nf_conn *ct;
388 enum ip_conntrack_info ctinfo;
389 int err;
390#endif
391 unsigned int ret;
392
393 /* root is playing with raw sockets. */
394 if (skb->len < sizeof(struct ipv6hdr))
395 return NF_ACCEPT;
396
397 ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain);
398#ifdef CONFIG_XFRM
399 if (ret != NF_DROP && ret != NF_STOLEN &&
400 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
401 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
402 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
403
404 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
405 &ct->tuplehash[!dir].tuple.dst.u3) ||
406 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
407 ct->tuplehash[dir].tuple.src.u.all !=
408 ct->tuplehash[!dir].tuple.dst.u.all)) {
409 err = nf_xfrm_me_harder(skb, AF_INET6);
410 if (err < 0)
411 ret = NF_DROP_ERR(err);
412 }
413 }
414#endif
415 return ret;
416}
417EXPORT_SYMBOL_GPL(nf_nat_ipv6_out);
418
419unsigned int
420nf_nat_ipv6_local_fn(const struct nf_hook_ops *ops, struct sk_buff *skb,
421 const struct net_device *in, const struct net_device *out,
422 unsigned int (*do_chain)(const struct nf_hook_ops *ops,
423 struct sk_buff *skb,
424 const struct net_device *in,
425 const struct net_device *out,
426 struct nf_conn *ct))
427{
428 const struct nf_conn *ct;
429 enum ip_conntrack_info ctinfo;
430 unsigned int ret;
431 int err;
432
433 /* root is playing with raw sockets. */
434 if (skb->len < sizeof(struct ipv6hdr))
435 return NF_ACCEPT;
436
437 ret = nf_nat_ipv6_fn(ops, skb, in, out, do_chain);
438 if (ret != NF_DROP && ret != NF_STOLEN &&
439 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
440 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
441
442 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
443 &ct->tuplehash[!dir].tuple.src.u3)) {
444 err = ip6_route_me_harder(skb);
445 if (err < 0)
446 ret = NF_DROP_ERR(err);
447 }
448#ifdef CONFIG_XFRM
449 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
450 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
451 ct->tuplehash[dir].tuple.dst.u.all !=
452 ct->tuplehash[!dir].tuple.src.u.all) {
453 err = nf_xfrm_me_harder(skb, AF_INET6);
454 if (err < 0)
455 ret = NF_DROP_ERR(err);
456 }
457#endif
458 }
459 return ret;
460}
461EXPORT_SYMBOL_GPL(nf_nat_ipv6_local_fn);
462
264static int __init nf_nat_l3proto_ipv6_init(void) 463static int __init nf_nat_l3proto_ipv6_init(void)
265{ 464{
266 int err; 465 int err;
diff --git a/net/ipv6/netfilter/nft_chain_nat_ipv6.c b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
index d189fcb437fe..c1c74491a10b 100644
--- a/net/ipv6/netfilter/nft_chain_nat_ipv6.c
+++ b/net/ipv6/netfilter/nft_chain_nat_ipv6.c
@@ -28,7 +28,7 @@
28 * IPv6 NAT chains 28 * IPv6 NAT chains
29 */ 29 */
30 30
31static unsigned int nf_nat_ipv6_fn(const struct nf_hook_ops *ops, 31static unsigned int nft_nat_ipv6_fn(const struct nf_hook_ops *ops,
32 struct sk_buff *skb, 32 struct sk_buff *skb,
33 const struct net_device *in, 33 const struct net_device *in,
34 const struct net_device *out, 34 const struct net_device *out,
@@ -97,7 +97,7 @@ static unsigned int nf_nat_ipv6_prerouting(const struct nf_hook_ops *ops,
97 struct in6_addr daddr = ipv6_hdr(skb)->daddr; 97 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
98 unsigned int ret; 98 unsigned int ret;
99 99
100 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn); 100 ret = nft_nat_ipv6_fn(ops, skb, in, out, okfn);
101 if (ret != NF_DROP && ret != NF_STOLEN && 101 if (ret != NF_DROP && ret != NF_STOLEN &&
102 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr)) 102 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
103 skb_dst_drop(skb); 103 skb_dst_drop(skb);
@@ -115,7 +115,7 @@ static unsigned int nf_nat_ipv6_postrouting(const struct nf_hook_ops *ops,
115 const struct nf_conn *ct __maybe_unused; 115 const struct nf_conn *ct __maybe_unused;
116 unsigned int ret; 116 unsigned int ret;
117 117
118 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn); 118 ret = nft_nat_ipv6_fn(ops, skb, in, out, okfn);
119#ifdef CONFIG_XFRM 119#ifdef CONFIG_XFRM
120 if (ret != NF_DROP && ret != NF_STOLEN && 120 if (ret != NF_DROP && ret != NF_STOLEN &&
121 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) && 121 !(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
@@ -143,7 +143,7 @@ static unsigned int nf_nat_ipv6_output(const struct nf_hook_ops *ops,
143 const struct nf_conn *ct; 143 const struct nf_conn *ct;
144 unsigned int ret; 144 unsigned int ret;
145 145
146 ret = nf_nat_ipv6_fn(ops, skb, in, out, okfn); 146 ret = nft_nat_ipv6_fn(ops, skb, in, out, okfn);
147 if (ret != NF_DROP && ret != NF_STOLEN && 147 if (ret != NF_DROP && ret != NF_STOLEN &&
148 (ct = nf_ct_get(skb, &ctinfo)) != NULL) { 148 (ct = nf_ct_get(skb, &ctinfo)) != NULL) {
149 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); 149 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
@@ -177,7 +177,7 @@ static const struct nf_chain_type nft_chain_nat_ipv6 = {
177 [NF_INET_PRE_ROUTING] = nf_nat_ipv6_prerouting, 177 [NF_INET_PRE_ROUTING] = nf_nat_ipv6_prerouting,
178 [NF_INET_POST_ROUTING] = nf_nat_ipv6_postrouting, 178 [NF_INET_POST_ROUTING] = nf_nat_ipv6_postrouting,
179 [NF_INET_LOCAL_OUT] = nf_nat_ipv6_output, 179 [NF_INET_LOCAL_OUT] = nf_nat_ipv6_output,
180 [NF_INET_LOCAL_IN] = nf_nat_ipv6_fn, 180 [NF_INET_LOCAL_IN] = nft_nat_ipv6_fn,
181 }, 181 },
182}; 182};
183 183