1 // SPDX-License-Identifier: GPL-2.0-only
2 /* (C) 1999-2001 Paul `Rusty' Russell
3 * (C) 2002-2006 Netfilter Core Team <coreteam@netfilter.org>
4 */
5
6 #include <linux/types.h>
7 #include <linux/export.h>
8 #include <linux/init.h>
9 #include <linux/udp.h>
10 #include <linux/tcp.h>
11 #include <linux/icmp.h>
12 #include <linux/icmpv6.h>
13
14 #include <linux/dccp.h>
15 #include <linux/sctp.h>
16 #include <net/sctp/checksum.h>
17
18 #include <linux/netfilter.h>
19 #include <net/netfilter/nf_nat.h>
20
21 #include <linux/ipv6.h>
22 #include <linux/netfilter_ipv6.h>
23 #include <net/checksum.h>
24 #include <net/ip6_checksum.h>
25 #include <net/ip6_route.h>
26 #include <net/xfrm.h>
27 #include <net/ipv6.h>
28 #include <net/pptp.h>
29
30 #include <net/netfilter/nf_conntrack_core.h>
31 #include <net/netfilter/nf_conntrack.h>
32 #include <linux/netfilter/nfnetlink_conntrack.h>
33
34 static void nf_csum_update(struct sk_buff *skb,
35 unsigned int iphdroff, __sum16 *check,
36 const struct nf_conntrack_tuple *t,
37 enum nf_nat_manip_type maniptype);
38
39 static void
__udp_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,struct udphdr * hdr,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype,bool do_csum)40 __udp_manip_pkt(struct sk_buff *skb,
41 unsigned int iphdroff, struct udphdr *hdr,
42 const struct nf_conntrack_tuple *tuple,
43 enum nf_nat_manip_type maniptype, bool do_csum)
44 {
45 __be16 *portptr, newport;
46
47 if (maniptype == NF_NAT_MANIP_SRC) {
48 /* Get rid of src port */
49 newport = tuple->src.u.udp.port;
50 portptr = &hdr->source;
51 } else {
52 /* Get rid of dst port */
53 newport = tuple->dst.u.udp.port;
54 portptr = &hdr->dest;
55 }
56 if (do_csum) {
57 nf_csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
58 inet_proto_csum_replace2(&hdr->check, skb, *portptr, newport,
59 false);
60 if (!hdr->check)
61 hdr->check = CSUM_MANGLED_0;
62 }
63 *portptr = newport;
64 }
65
udp_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)66 static bool udp_manip_pkt(struct sk_buff *skb,
67 unsigned int iphdroff, unsigned int hdroff,
68 const struct nf_conntrack_tuple *tuple,
69 enum nf_nat_manip_type maniptype)
70 {
71 struct udphdr *hdr;
72
73 if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
74 return false;
75
76 hdr = (struct udphdr *)(skb->data + hdroff);
77 __udp_manip_pkt(skb, iphdroff, hdr, tuple, maniptype, !!hdr->check);
78
79 return true;
80 }
81
82 static bool
sctp_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)83 sctp_manip_pkt(struct sk_buff *skb,
84 unsigned int iphdroff, unsigned int hdroff,
85 const struct nf_conntrack_tuple *tuple,
86 enum nf_nat_manip_type maniptype)
87 {
88 #ifdef CONFIG_NF_CT_PROTO_SCTP
89 struct sctphdr *hdr;
90 int hdrsize = 8;
91
92 /* This could be an inner header returned in imcp packet; in such
93 * cases we cannot update the checksum field since it is outside
94 * of the 8 bytes of transport layer headers we are guaranteed.
95 */
96 if (skb->len >= hdroff + sizeof(*hdr))
97 hdrsize = sizeof(*hdr);
98
99 if (skb_ensure_writable(skb, hdroff + hdrsize))
100 return false;
101
102 hdr = (struct sctphdr *)(skb->data + hdroff);
103
104 if (maniptype == NF_NAT_MANIP_SRC) {
105 /* Get rid of src port */
106 hdr->source = tuple->src.u.sctp.port;
107 } else {
108 /* Get rid of dst port */
109 hdr->dest = tuple->dst.u.sctp.port;
110 }
111
112 if (hdrsize < sizeof(*hdr))
113 return true;
114
115 if (skb->ip_summed != CHECKSUM_PARTIAL) {
116 hdr->checksum = sctp_compute_cksum(skb, hdroff);
117 skb->ip_summed = CHECKSUM_NONE;
118 }
119
120 #endif
121 return true;
122 }
123
124 static bool
tcp_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)125 tcp_manip_pkt(struct sk_buff *skb,
126 unsigned int iphdroff, unsigned int hdroff,
127 const struct nf_conntrack_tuple *tuple,
128 enum nf_nat_manip_type maniptype)
129 {
130 struct tcphdr *hdr;
131 __be16 *portptr, newport, oldport;
132 int hdrsize = 8; /* TCP connection tracking guarantees this much */
133
134 /* this could be a inner header returned in icmp packet; in such
135 cases we cannot update the checksum field since it is outside of
136 the 8 bytes of transport layer headers we are guaranteed */
137 if (skb->len >= hdroff + sizeof(struct tcphdr))
138 hdrsize = sizeof(struct tcphdr);
139
140 if (skb_ensure_writable(skb, hdroff + hdrsize))
141 return false;
142
143 hdr = (struct tcphdr *)(skb->data + hdroff);
144
145 if (maniptype == NF_NAT_MANIP_SRC) {
146 /* Get rid of src port */
147 newport = tuple->src.u.tcp.port;
148 portptr = &hdr->source;
149 } else {
150 /* Get rid of dst port */
151 newport = tuple->dst.u.tcp.port;
152 portptr = &hdr->dest;
153 }
154
155 oldport = *portptr;
156 *portptr = newport;
157
158 if (hdrsize < sizeof(*hdr))
159 return true;
160
161 nf_csum_update(skb, iphdroff, &hdr->check, tuple, maniptype);
162 inet_proto_csum_replace2(&hdr->check, skb, oldport, newport, false);
163 return true;
164 }
165
166 static bool
icmp_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)167 icmp_manip_pkt(struct sk_buff *skb,
168 unsigned int iphdroff, unsigned int hdroff,
169 const struct nf_conntrack_tuple *tuple,
170 enum nf_nat_manip_type maniptype)
171 {
172 struct icmphdr *hdr;
173
174 if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
175 return false;
176
177 hdr = (struct icmphdr *)(skb->data + hdroff);
178 switch (hdr->type) {
179 case ICMP_ECHO:
180 case ICMP_ECHOREPLY:
181 case ICMP_TIMESTAMP:
182 case ICMP_TIMESTAMPREPLY:
183 case ICMP_INFO_REQUEST:
184 case ICMP_INFO_REPLY:
185 case ICMP_ADDRESS:
186 case ICMP_ADDRESSREPLY:
187 break;
188 default:
189 return true;
190 }
191 inet_proto_csum_replace2(&hdr->checksum, skb,
192 hdr->un.echo.id, tuple->src.u.icmp.id, false);
193 hdr->un.echo.id = tuple->src.u.icmp.id;
194 return true;
195 }
196
197 static bool
icmpv6_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)198 icmpv6_manip_pkt(struct sk_buff *skb,
199 unsigned int iphdroff, unsigned int hdroff,
200 const struct nf_conntrack_tuple *tuple,
201 enum nf_nat_manip_type maniptype)
202 {
203 struct icmp6hdr *hdr;
204
205 if (skb_ensure_writable(skb, hdroff + sizeof(*hdr)))
206 return false;
207
208 hdr = (struct icmp6hdr *)(skb->data + hdroff);
209 nf_csum_update(skb, iphdroff, &hdr->icmp6_cksum, tuple, maniptype);
210 if (hdr->icmp6_type == ICMPV6_ECHO_REQUEST ||
211 hdr->icmp6_type == ICMPV6_ECHO_REPLY) {
212 inet_proto_csum_replace2(&hdr->icmp6_cksum, skb,
213 hdr->icmp6_identifier,
214 tuple->src.u.icmp.id, false);
215 hdr->icmp6_identifier = tuple->src.u.icmp.id;
216 }
217 return true;
218 }
219
220 /* manipulate a GRE packet according to maniptype */
221 static bool
gre_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)222 gre_manip_pkt(struct sk_buff *skb,
223 unsigned int iphdroff, unsigned int hdroff,
224 const struct nf_conntrack_tuple *tuple,
225 enum nf_nat_manip_type maniptype)
226 {
227 #if IS_ENABLED(CONFIG_NF_CT_PROTO_GRE)
228 const struct gre_base_hdr *greh;
229 struct pptp_gre_header *pgreh;
230
231 /* pgreh includes two optional 32bit fields which are not required
232 * to be there. That's where the magic '8' comes from */
233 if (skb_ensure_writable(skb, hdroff + sizeof(*pgreh) - 8))
234 return false;
235
236 greh = (void *)skb->data + hdroff;
237 pgreh = (struct pptp_gre_header *)greh;
238
239 /* we only have destination manip of a packet, since 'source key'
240 * is not present in the packet itself */
241 if (maniptype != NF_NAT_MANIP_DST)
242 return true;
243
244 switch (greh->flags & GRE_VERSION) {
245 case GRE_VERSION_0:
246 /* We do not currently NAT any GREv0 packets.
247 * Try to behave like "nf_nat_proto_unknown" */
248 break;
249 case GRE_VERSION_1:
250 pr_debug("call_id -> 0x%04x\n", ntohs(tuple->dst.u.gre.key));
251 pgreh->call_id = tuple->dst.u.gre.key;
252 break;
253 default:
254 pr_debug("can't nat unknown GRE version\n");
255 return false;
256 }
257 #endif
258 return true;
259 }
260
l4proto_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,unsigned int hdroff,const struct nf_conntrack_tuple * tuple,enum nf_nat_manip_type maniptype)261 static bool l4proto_manip_pkt(struct sk_buff *skb,
262 unsigned int iphdroff, unsigned int hdroff,
263 const struct nf_conntrack_tuple *tuple,
264 enum nf_nat_manip_type maniptype)
265 {
266 switch (tuple->dst.protonum) {
267 case IPPROTO_TCP:
268 return tcp_manip_pkt(skb, iphdroff, hdroff,
269 tuple, maniptype);
270 case IPPROTO_UDP:
271 return udp_manip_pkt(skb, iphdroff, hdroff,
272 tuple, maniptype);
273 case IPPROTO_SCTP:
274 return sctp_manip_pkt(skb, iphdroff, hdroff,
275 tuple, maniptype);
276 case IPPROTO_ICMP:
277 return icmp_manip_pkt(skb, iphdroff, hdroff,
278 tuple, maniptype);
279 case IPPROTO_ICMPV6:
280 return icmpv6_manip_pkt(skb, iphdroff, hdroff,
281 tuple, maniptype);
282 case IPPROTO_GRE:
283 return gre_manip_pkt(skb, iphdroff, hdroff,
284 tuple, maniptype);
285 }
286
287 /* If we don't know protocol -- no error, pass it unmodified. */
288 return true;
289 }
290
nf_nat_ipv4_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,const struct nf_conntrack_tuple * target,enum nf_nat_manip_type maniptype)291 static bool nf_nat_ipv4_manip_pkt(struct sk_buff *skb,
292 unsigned int iphdroff,
293 const struct nf_conntrack_tuple *target,
294 enum nf_nat_manip_type maniptype)
295 {
296 struct iphdr *iph;
297 unsigned int hdroff;
298
299 if (skb_ensure_writable(skb, iphdroff + sizeof(*iph)))
300 return false;
301
302 iph = (void *)skb->data + iphdroff;
303 hdroff = iphdroff + iph->ihl * 4;
304
305 if (!l4proto_manip_pkt(skb, iphdroff, hdroff, target, maniptype))
306 return false;
307 iph = (void *)skb->data + iphdroff;
308
309 if (maniptype == NF_NAT_MANIP_SRC) {
310 csum_replace4(&iph->check, iph->saddr, target->src.u3.ip);
311 iph->saddr = target->src.u3.ip;
312 } else {
313 csum_replace4(&iph->check, iph->daddr, target->dst.u3.ip);
314 iph->daddr = target->dst.u3.ip;
315 }
316 return true;
317 }
318
nf_nat_ipv6_manip_pkt(struct sk_buff * skb,unsigned int iphdroff,const struct nf_conntrack_tuple * target,enum nf_nat_manip_type maniptype)319 static bool nf_nat_ipv6_manip_pkt(struct sk_buff *skb,
320 unsigned int iphdroff,
321 const struct nf_conntrack_tuple *target,
322 enum nf_nat_manip_type maniptype)
323 {
324 #if IS_ENABLED(CONFIG_IPV6)
325 struct ipv6hdr *ipv6h;
326 __be16 frag_off;
327 int hdroff;
328 u8 nexthdr;
329
330 if (skb_ensure_writable(skb, iphdroff + sizeof(*ipv6h)))
331 return false;
332
333 ipv6h = (void *)skb->data + iphdroff;
334 nexthdr = ipv6h->nexthdr;
335 hdroff = ipv6_skip_exthdr(skb, iphdroff + sizeof(*ipv6h),
336 &nexthdr, &frag_off);
337 if (hdroff < 0)
338 goto manip_addr;
339
340 if ((frag_off & htons(~0x7)) == 0 &&
341 !l4proto_manip_pkt(skb, iphdroff, hdroff, target, maniptype))
342 return false;
343
344 /* must reload, offset might have changed */
345 ipv6h = (void *)skb->data + iphdroff;
346
347 manip_addr:
348 if (maniptype == NF_NAT_MANIP_SRC)
349 ipv6h->saddr = target->src.u3.in6;
350 else
351 ipv6h->daddr = target->dst.u3.in6;
352
353 #endif
354 return true;
355 }
356
nf_nat_manip_pkt(struct sk_buff * skb,struct nf_conn * ct,enum nf_nat_manip_type mtype,enum ip_conntrack_dir dir)357 unsigned int nf_nat_manip_pkt(struct sk_buff *skb, struct nf_conn *ct,
358 enum nf_nat_manip_type mtype,
359 enum ip_conntrack_dir dir)
360 {
361 struct nf_conntrack_tuple target;
362
363 /* We are aiming to look like inverse of other direction. */
364 nf_ct_invert_tuple(&target, &ct->tuplehash[!dir].tuple);
365
366 switch (target.src.l3num) {
367 case NFPROTO_IPV6:
368 if (nf_nat_ipv6_manip_pkt(skb, 0, &target, mtype))
369 return NF_ACCEPT;
370 break;
371 case NFPROTO_IPV4:
372 if (nf_nat_ipv4_manip_pkt(skb, 0, &target, mtype))
373 return NF_ACCEPT;
374 break;
375 default:
376 WARN_ON_ONCE(1);
377 break;
378 }
379
380 return NF_DROP;
381 }
382
nf_nat_ipv4_csum_update(struct sk_buff * skb,unsigned int iphdroff,__sum16 * check,const struct nf_conntrack_tuple * t,enum nf_nat_manip_type maniptype)383 static void nf_nat_ipv4_csum_update(struct sk_buff *skb,
384 unsigned int iphdroff, __sum16 *check,
385 const struct nf_conntrack_tuple *t,
386 enum nf_nat_manip_type maniptype)
387 {
388 struct iphdr *iph = (struct iphdr *)(skb->data + iphdroff);
389 __be32 oldip, newip;
390
391 if (maniptype == NF_NAT_MANIP_SRC) {
392 oldip = iph->saddr;
393 newip = t->src.u3.ip;
394 } else {
395 oldip = iph->daddr;
396 newip = t->dst.u3.ip;
397 }
398 inet_proto_csum_replace4(check, skb, oldip, newip, true);
399 }
400
nf_nat_ipv6_csum_update(struct sk_buff * skb,unsigned int iphdroff,__sum16 * check,const struct nf_conntrack_tuple * t,enum nf_nat_manip_type maniptype)401 static void nf_nat_ipv6_csum_update(struct sk_buff *skb,
402 unsigned int iphdroff, __sum16 *check,
403 const struct nf_conntrack_tuple *t,
404 enum nf_nat_manip_type maniptype)
405 {
406 #if IS_ENABLED(CONFIG_IPV6)
407 const struct ipv6hdr *ipv6h = (struct ipv6hdr *)(skb->data + iphdroff);
408 const struct in6_addr *oldip, *newip;
409
410 if (maniptype == NF_NAT_MANIP_SRC) {
411 oldip = &ipv6h->saddr;
412 newip = &t->src.u3.in6;
413 } else {
414 oldip = &ipv6h->daddr;
415 newip = &t->dst.u3.in6;
416 }
417 inet_proto_csum_replace16(check, skb, oldip->s6_addr32,
418 newip->s6_addr32, true);
419 #endif
420 }
421
nf_csum_update(struct sk_buff * skb,unsigned int iphdroff,__sum16 * check,const struct nf_conntrack_tuple * t,enum nf_nat_manip_type maniptype)422 static void nf_csum_update(struct sk_buff *skb,
423 unsigned int iphdroff, __sum16 *check,
424 const struct nf_conntrack_tuple *t,
425 enum nf_nat_manip_type maniptype)
426 {
427 switch (t->src.l3num) {
428 case NFPROTO_IPV4:
429 nf_nat_ipv4_csum_update(skb, iphdroff, check, t, maniptype);
430 return;
431 case NFPROTO_IPV6:
432 nf_nat_ipv6_csum_update(skb, iphdroff, check, t, maniptype);
433 return;
434 }
435 }
436
nf_nat_ipv4_csum_recalc(struct sk_buff * skb,u8 proto,void * data,__sum16 * check,int datalen,int oldlen)437 static void nf_nat_ipv4_csum_recalc(struct sk_buff *skb,
438 u8 proto, void *data, __sum16 *check,
439 int datalen, int oldlen)
440 {
441 if (skb->ip_summed != CHECKSUM_PARTIAL) {
442 const struct iphdr *iph = ip_hdr(skb);
443
444 skb->ip_summed = CHECKSUM_PARTIAL;
445 skb->csum_start = skb_headroom(skb) + skb_network_offset(skb) +
446 ip_hdrlen(skb);
447 skb->csum_offset = (void *)check - data;
448 *check = ~csum_tcpudp_magic(iph->saddr, iph->daddr, datalen,
449 proto, 0);
450 } else {
451 inet_proto_csum_replace2(check, skb,
452 htons(oldlen), htons(datalen), true);
453 }
454 }
455
456 #if IS_ENABLED(CONFIG_IPV6)
nf_nat_ipv6_csum_recalc(struct sk_buff * skb,u8 proto,void * data,__sum16 * check,int datalen,int oldlen)457 static void nf_nat_ipv6_csum_recalc(struct sk_buff *skb,
458 u8 proto, void *data, __sum16 *check,
459 int datalen, int oldlen)
460 {
461 if (skb->ip_summed != CHECKSUM_PARTIAL) {
462 const struct ipv6hdr *ipv6h = ipv6_hdr(skb);
463
464 skb->ip_summed = CHECKSUM_PARTIAL;
465 skb->csum_start = skb_headroom(skb) + skb_network_offset(skb) +
466 (data - (void *)skb->data);
467 skb->csum_offset = (void *)check - data;
468 *check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
469 datalen, proto, 0);
470 } else {
471 inet_proto_csum_replace2(check, skb,
472 htons(oldlen), htons(datalen), true);
473 }
474 }
475 #endif
476
nf_nat_csum_recalc(struct sk_buff * skb,u8 nfproto,u8 proto,void * data,__sum16 * check,int datalen,int oldlen)477 void nf_nat_csum_recalc(struct sk_buff *skb,
478 u8 nfproto, u8 proto, void *data, __sum16 *check,
479 int datalen, int oldlen)
480 {
481 switch (nfproto) {
482 case NFPROTO_IPV4:
483 nf_nat_ipv4_csum_recalc(skb, proto, data, check,
484 datalen, oldlen);
485 return;
486 #if IS_ENABLED(CONFIG_IPV6)
487 case NFPROTO_IPV6:
488 nf_nat_ipv6_csum_recalc(skb, proto, data, check,
489 datalen, oldlen);
490 return;
491 #endif
492 }
493
494 WARN_ON_ONCE(1);
495 }
496
nf_nat_icmp_reply_translation(struct sk_buff * skb,struct nf_conn * ct,enum ip_conntrack_info ctinfo,unsigned int hooknum)497 int nf_nat_icmp_reply_translation(struct sk_buff *skb,
498 struct nf_conn *ct,
499 enum ip_conntrack_info ctinfo,
500 unsigned int hooknum)
501 {
502 struct {
503 struct icmphdr icmp;
504 struct iphdr ip;
505 } *inside;
506 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
507 enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
508 unsigned int hdrlen = ip_hdrlen(skb);
509 struct nf_conntrack_tuple target;
510 unsigned long statusbit;
511
512 WARN_ON(ctinfo != IP_CT_RELATED && ctinfo != IP_CT_RELATED_REPLY);
513
514 if (skb_ensure_writable(skb, hdrlen + sizeof(*inside)))
515 return 0;
516 if (nf_ip_checksum(skb, hooknum, hdrlen, IPPROTO_ICMP))
517 return 0;
518
519 inside = (void *)skb->data + hdrlen;
520 if (inside->icmp.type == ICMP_REDIRECT) {
521 if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
522 return 0;
523 if (ct->status & IPS_NAT_MASK)
524 return 0;
525 }
526
527 if (manip == NF_NAT_MANIP_SRC)
528 statusbit = IPS_SRC_NAT;
529 else
530 statusbit = IPS_DST_NAT;
531
532 /* Invert if this is reply direction */
533 if (dir == IP_CT_DIR_REPLY)
534 statusbit ^= IPS_NAT_MASK;
535
536 if (!(ct->status & statusbit))
537 return 1;
538
539 if (!nf_nat_ipv4_manip_pkt(skb, hdrlen + sizeof(inside->icmp),
540 &ct->tuplehash[!dir].tuple, !manip))
541 return 0;
542
543 if (skb->ip_summed != CHECKSUM_PARTIAL) {
544 /* Reloading "inside" here since manip_pkt may reallocate */
545 inside = (void *)skb->data + hdrlen;
546 inside->icmp.checksum = 0;
547 inside->icmp.checksum =
548 csum_fold(skb_checksum(skb, hdrlen,
549 skb->len - hdrlen, 0));
550 }
551
552 /* Change outer to look like the reply to an incoming packet */
553 nf_ct_invert_tuple(&target, &ct->tuplehash[!dir].tuple);
554 target.dst.protonum = IPPROTO_ICMP;
555 if (!nf_nat_ipv4_manip_pkt(skb, 0, &target, manip))
556 return 0;
557
558 return 1;
559 }
560 EXPORT_SYMBOL_GPL(nf_nat_icmp_reply_translation);
561
562 static unsigned int
nf_nat_ipv4_fn(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)563 nf_nat_ipv4_fn(void *priv, struct sk_buff *skb,
564 const struct nf_hook_state *state)
565 {
566 struct nf_conn *ct;
567 enum ip_conntrack_info ctinfo;
568
569 ct = nf_ct_get(skb, &ctinfo);
570 if (!ct)
571 return NF_ACCEPT;
572
573 if (ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY) {
574 if (ip_hdr(skb)->protocol == IPPROTO_ICMP) {
575 if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo,
576 state->hook))
577 return NF_DROP;
578 else
579 return NF_ACCEPT;
580 }
581 }
582
583 return nf_nat_inet_fn(priv, skb, state);
584 }
585
586 static unsigned int
nf_nat_ipv4_pre_routing(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)587 nf_nat_ipv4_pre_routing(void *priv, struct sk_buff *skb,
588 const struct nf_hook_state *state)
589 {
590 unsigned int ret;
591 __be32 daddr = ip_hdr(skb)->daddr;
592
593 ret = nf_nat_ipv4_fn(priv, skb, state);
594 if (ret == NF_ACCEPT && daddr != ip_hdr(skb)->daddr)
595 skb_dst_drop(skb);
596
597 return ret;
598 }
599
600 #ifdef CONFIG_XFRM
nf_xfrm_me_harder(struct net * net,struct sk_buff * skb,unsigned int family)601 static int nf_xfrm_me_harder(struct net *net, struct sk_buff *skb, unsigned int family)
602 {
603 struct sock *sk = skb->sk;
604 struct dst_entry *dst;
605 unsigned int hh_len;
606 struct flowi fl;
607 int err;
608
609 err = xfrm_decode_session(net, skb, &fl, family);
610 if (err < 0)
611 return err;
612
613 dst = skb_dst(skb);
614 if (dst->xfrm)
615 dst = ((struct xfrm_dst *)dst)->route;
616 if (!dst_hold_safe(dst))
617 return -EHOSTUNREACH;
618
619 if (sk && !net_eq(net, sock_net(sk)))
620 sk = NULL;
621
622 dst = xfrm_lookup(net, dst, &fl, sk, 0);
623 if (IS_ERR(dst))
624 return PTR_ERR(dst);
625
626 skb_dst_drop(skb);
627 skb_dst_set(skb, dst);
628
629 /* Change in oif may mean change in hh_len. */
630 hh_len = skb_dst(skb)->dev->hard_header_len;
631 if (skb_headroom(skb) < hh_len &&
632 pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
633 return -ENOMEM;
634 return 0;
635 }
636 #endif
637
nf_nat_inet_port_was_mangled(const struct sk_buff * skb,__be16 sport)638 static bool nf_nat_inet_port_was_mangled(const struct sk_buff *skb, __be16 sport)
639 {
640 enum ip_conntrack_info ctinfo;
641 enum ip_conntrack_dir dir;
642 const struct nf_conn *ct;
643
644 ct = nf_ct_get(skb, &ctinfo);
645 if (!ct)
646 return false;
647
648 switch (nf_ct_protonum(ct)) {
649 case IPPROTO_TCP:
650 case IPPROTO_UDP:
651 break;
652 default:
653 return false;
654 }
655
656 dir = CTINFO2DIR(ctinfo);
657 if (dir != IP_CT_DIR_ORIGINAL)
658 return false;
659
660 return ct->tuplehash[!dir].tuple.dst.u.all != sport;
661 }
662
663 static unsigned int
nf_nat_ipv4_local_in(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)664 nf_nat_ipv4_local_in(void *priv, struct sk_buff *skb,
665 const struct nf_hook_state *state)
666 {
667 __be32 saddr = ip_hdr(skb)->saddr;
668 struct sock *sk = skb->sk;
669 unsigned int ret;
670
671 ret = nf_nat_ipv4_fn(priv, skb, state);
672
673 if (ret != NF_ACCEPT || !sk || inet_sk_transparent(sk))
674 return ret;
675
676 /* skb has a socket assigned via tcp edemux. We need to check
677 * if nf_nat_ipv4_fn() has mangled the packet in a way that
678 * edemux would not have found this socket.
679 *
680 * This includes both changes to the source address and changes
681 * to the source port, which are both handled by the
682 * nf_nat_ipv4_fn() call above -- long after tcp/udp early demux
683 * might have found a socket for the old (pre-snat) address.
684 */
685 if (saddr != ip_hdr(skb)->saddr ||
686 nf_nat_inet_port_was_mangled(skb, sk->sk_dport))
687 skb_orphan(skb); /* TCP edemux obtained wrong socket */
688
689 return ret;
690 }
691
692 static unsigned int
nf_nat_ipv4_out(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)693 nf_nat_ipv4_out(void *priv, struct sk_buff *skb,
694 const struct nf_hook_state *state)
695 {
696 #ifdef CONFIG_XFRM
697 const struct nf_conn *ct;
698 enum ip_conntrack_info ctinfo;
699 int err;
700 #endif
701 unsigned int ret;
702
703 ret = nf_nat_ipv4_fn(priv, skb, state);
704 #ifdef CONFIG_XFRM
705 if (ret != NF_ACCEPT)
706 return ret;
707
708 if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
709 return ret;
710
711 ct = nf_ct_get(skb, &ctinfo);
712 if (ct) {
713 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
714
715 if (ct->tuplehash[dir].tuple.src.u3.ip !=
716 ct->tuplehash[!dir].tuple.dst.u3.ip ||
717 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
718 ct->tuplehash[dir].tuple.src.u.all !=
719 ct->tuplehash[!dir].tuple.dst.u.all)) {
720 err = nf_xfrm_me_harder(state->net, skb, AF_INET);
721 if (err < 0)
722 ret = NF_DROP_ERR(err);
723 }
724 }
725 #endif
726 return ret;
727 }
728
729 static unsigned int
nf_nat_ipv4_local_fn(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)730 nf_nat_ipv4_local_fn(void *priv, struct sk_buff *skb,
731 const struct nf_hook_state *state)
732 {
733 const struct nf_conn *ct;
734 enum ip_conntrack_info ctinfo;
735 unsigned int ret;
736 int err;
737
738 ret = nf_nat_ipv4_fn(priv, skb, state);
739 if (ret != NF_ACCEPT)
740 return ret;
741
742 ct = nf_ct_get(skb, &ctinfo);
743 if (ct) {
744 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
745
746 if (ct->tuplehash[dir].tuple.dst.u3.ip !=
747 ct->tuplehash[!dir].tuple.src.u3.ip) {
748 err = ip_route_me_harder(state->net, state->sk, skb, RTN_UNSPEC);
749 if (err < 0)
750 ret = NF_DROP_ERR(err);
751 }
752 #ifdef CONFIG_XFRM
753 else if (!(IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED) &&
754 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMP &&
755 ct->tuplehash[dir].tuple.dst.u.all !=
756 ct->tuplehash[!dir].tuple.src.u.all) {
757 err = nf_xfrm_me_harder(state->net, skb, AF_INET);
758 if (err < 0)
759 ret = NF_DROP_ERR(err);
760 }
761 #endif
762 }
763 return ret;
764 }
765
766 static const struct nf_hook_ops nf_nat_ipv4_ops[] = {
767 /* Before packet filtering, change destination */
768 {
769 .hook = nf_nat_ipv4_pre_routing,
770 .pf = NFPROTO_IPV4,
771 .hooknum = NF_INET_PRE_ROUTING,
772 .priority = NF_IP_PRI_NAT_DST,
773 .hook_ops_type = NF_HOOK_OP_NAT,
774 },
775 /* After packet filtering, change source */
776 {
777 .hook = nf_nat_ipv4_out,
778 .pf = NFPROTO_IPV4,
779 .hooknum = NF_INET_POST_ROUTING,
780 .priority = NF_IP_PRI_NAT_SRC,
781 .hook_ops_type = NF_HOOK_OP_NAT,
782 },
783 /* Before packet filtering, change destination */
784 {
785 .hook = nf_nat_ipv4_local_fn,
786 .pf = NFPROTO_IPV4,
787 .hooknum = NF_INET_LOCAL_OUT,
788 .priority = NF_IP_PRI_NAT_DST,
789 .hook_ops_type = NF_HOOK_OP_NAT,
790 },
791 /* After packet filtering, change source */
792 {
793 .hook = nf_nat_ipv4_local_in,
794 .pf = NFPROTO_IPV4,
795 .hooknum = NF_INET_LOCAL_IN,
796 .priority = NF_IP_PRI_NAT_SRC,
797 .hook_ops_type = NF_HOOK_OP_NAT,
798 },
799 };
800
nf_nat_ipv4_register_fn(struct net * net,const struct nf_hook_ops * ops)801 int nf_nat_ipv4_register_fn(struct net *net, const struct nf_hook_ops *ops)
802 {
803 return nf_nat_register_fn(net, ops->pf, ops, nf_nat_ipv4_ops,
804 ARRAY_SIZE(nf_nat_ipv4_ops));
805 }
806 EXPORT_SYMBOL_GPL(nf_nat_ipv4_register_fn);
807
nf_nat_ipv4_unregister_fn(struct net * net,const struct nf_hook_ops * ops)808 void nf_nat_ipv4_unregister_fn(struct net *net, const struct nf_hook_ops *ops)
809 {
810 nf_nat_unregister_fn(net, ops->pf, ops, ARRAY_SIZE(nf_nat_ipv4_ops));
811 }
812 EXPORT_SYMBOL_GPL(nf_nat_ipv4_unregister_fn);
813
814 #if IS_ENABLED(CONFIG_IPV6)
nf_nat_icmpv6_reply_translation(struct sk_buff * skb,struct nf_conn * ct,enum ip_conntrack_info ctinfo,unsigned int hooknum,unsigned int hdrlen)815 int nf_nat_icmpv6_reply_translation(struct sk_buff *skb,
816 struct nf_conn *ct,
817 enum ip_conntrack_info ctinfo,
818 unsigned int hooknum,
819 unsigned int hdrlen)
820 {
821 struct {
822 struct icmp6hdr icmp6;
823 struct ipv6hdr ip6;
824 } *inside;
825 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
826 enum nf_nat_manip_type manip = HOOK2MANIP(hooknum);
827 struct nf_conntrack_tuple target;
828 unsigned long statusbit;
829
830 WARN_ON(ctinfo != IP_CT_RELATED && ctinfo != IP_CT_RELATED_REPLY);
831
832 if (skb_ensure_writable(skb, hdrlen + sizeof(*inside)))
833 return 0;
834 if (nf_ip6_checksum(skb, hooknum, hdrlen, IPPROTO_ICMPV6))
835 return 0;
836
837 inside = (void *)skb->data + hdrlen;
838 if (inside->icmp6.icmp6_type == NDISC_REDIRECT) {
839 if ((ct->status & IPS_NAT_DONE_MASK) != IPS_NAT_DONE_MASK)
840 return 0;
841 if (ct->status & IPS_NAT_MASK)
842 return 0;
843 }
844
845 if (manip == NF_NAT_MANIP_SRC)
846 statusbit = IPS_SRC_NAT;
847 else
848 statusbit = IPS_DST_NAT;
849
850 /* Invert if this is reply direction */
851 if (dir == IP_CT_DIR_REPLY)
852 statusbit ^= IPS_NAT_MASK;
853
854 if (!(ct->status & statusbit))
855 return 1;
856
857 if (!nf_nat_ipv6_manip_pkt(skb, hdrlen + sizeof(inside->icmp6),
858 &ct->tuplehash[!dir].tuple, !manip))
859 return 0;
860
861 if (skb->ip_summed != CHECKSUM_PARTIAL) {
862 struct ipv6hdr *ipv6h = ipv6_hdr(skb);
863
864 inside = (void *)skb->data + hdrlen;
865 inside->icmp6.icmp6_cksum = 0;
866 inside->icmp6.icmp6_cksum =
867 csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr,
868 skb->len - hdrlen, IPPROTO_ICMPV6,
869 skb_checksum(skb, hdrlen,
870 skb->len - hdrlen, 0));
871 }
872
873 nf_ct_invert_tuple(&target, &ct->tuplehash[!dir].tuple);
874 target.dst.protonum = IPPROTO_ICMPV6;
875 if (!nf_nat_ipv6_manip_pkt(skb, 0, &target, manip))
876 return 0;
877
878 return 1;
879 }
880 EXPORT_SYMBOL_GPL(nf_nat_icmpv6_reply_translation);
881
882 static unsigned int
nf_nat_ipv6_fn(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)883 nf_nat_ipv6_fn(void *priv, struct sk_buff *skb,
884 const struct nf_hook_state *state)
885 {
886 struct nf_conn *ct;
887 enum ip_conntrack_info ctinfo;
888 __be16 frag_off;
889 int hdrlen;
890 u8 nexthdr;
891
892 ct = nf_ct_get(skb, &ctinfo);
893 /* Can't track? It's not due to stress, or conntrack would
894 * have dropped it. Hence it's the user's responsibilty to
895 * packet filter it out, or implement conntrack/NAT for that
896 * protocol. 8) --RR
897 */
898 if (!ct)
899 return NF_ACCEPT;
900
901 if (ctinfo == IP_CT_RELATED || ctinfo == IP_CT_RELATED_REPLY) {
902 nexthdr = ipv6_hdr(skb)->nexthdr;
903 hdrlen = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr),
904 &nexthdr, &frag_off);
905
906 if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
907 if (!nf_nat_icmpv6_reply_translation(skb, ct, ctinfo,
908 state->hook,
909 hdrlen))
910 return NF_DROP;
911 else
912 return NF_ACCEPT;
913 }
914 }
915
916 return nf_nat_inet_fn(priv, skb, state);
917 }
918
919 static unsigned int
nf_nat_ipv6_local_in(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)920 nf_nat_ipv6_local_in(void *priv, struct sk_buff *skb,
921 const struct nf_hook_state *state)
922 {
923 struct in6_addr saddr = ipv6_hdr(skb)->saddr;
924 struct sock *sk = skb->sk;
925 unsigned int ret;
926
927 ret = nf_nat_ipv6_fn(priv, skb, state);
928
929 if (ret != NF_ACCEPT || !sk || inet_sk_transparent(sk))
930 return ret;
931
932 /* see nf_nat_ipv4_local_in */
933 if (ipv6_addr_cmp(&saddr, &ipv6_hdr(skb)->saddr) ||
934 nf_nat_inet_port_was_mangled(skb, sk->sk_dport))
935 skb_orphan(skb);
936
937 return ret;
938 }
939
940 static unsigned int
nf_nat_ipv6_in(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)941 nf_nat_ipv6_in(void *priv, struct sk_buff *skb,
942 const struct nf_hook_state *state)
943 {
944 unsigned int ret, verdict;
945 struct in6_addr daddr = ipv6_hdr(skb)->daddr;
946
947 ret = nf_nat_ipv6_fn(priv, skb, state);
948 verdict = ret & NF_VERDICT_MASK;
949 if (verdict != NF_DROP && verdict != NF_STOLEN &&
950 ipv6_addr_cmp(&daddr, &ipv6_hdr(skb)->daddr))
951 skb_dst_drop(skb);
952
953 return ret;
954 }
955
956 static unsigned int
nf_nat_ipv6_out(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)957 nf_nat_ipv6_out(void *priv, struct sk_buff *skb,
958 const struct nf_hook_state *state)
959 {
960 #ifdef CONFIG_XFRM
961 const struct nf_conn *ct;
962 enum ip_conntrack_info ctinfo;
963 int err;
964 #endif
965 unsigned int ret;
966
967 ret = nf_nat_ipv6_fn(priv, skb, state);
968 #ifdef CONFIG_XFRM
969 if (ret != NF_ACCEPT)
970 return ret;
971
972 if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
973 return ret;
974 ct = nf_ct_get(skb, &ctinfo);
975 if (ct) {
976 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
977
978 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.src.u3,
979 &ct->tuplehash[!dir].tuple.dst.u3) ||
980 (ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
981 ct->tuplehash[dir].tuple.src.u.all !=
982 ct->tuplehash[!dir].tuple.dst.u.all)) {
983 err = nf_xfrm_me_harder(state->net, skb, AF_INET6);
984 if (err < 0)
985 ret = NF_DROP_ERR(err);
986 }
987 }
988 #endif
989
990 return ret;
991 }
992
993 static unsigned int
nf_nat_ipv6_local_fn(void * priv,struct sk_buff * skb,const struct nf_hook_state * state)994 nf_nat_ipv6_local_fn(void *priv, struct sk_buff *skb,
995 const struct nf_hook_state *state)
996 {
997 const struct nf_conn *ct;
998 enum ip_conntrack_info ctinfo;
999 unsigned int ret;
1000 int err;
1001
1002 ret = nf_nat_ipv6_fn(priv, skb, state);
1003 if (ret != NF_ACCEPT)
1004 return ret;
1005
1006 ct = nf_ct_get(skb, &ctinfo);
1007 if (ct) {
1008 enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
1009
1010 if (!nf_inet_addr_cmp(&ct->tuplehash[dir].tuple.dst.u3,
1011 &ct->tuplehash[!dir].tuple.src.u3)) {
1012 err = nf_ip6_route_me_harder(state->net, state->sk, skb);
1013 if (err < 0)
1014 ret = NF_DROP_ERR(err);
1015 }
1016 #ifdef CONFIG_XFRM
1017 else if (!(IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED) &&
1018 ct->tuplehash[dir].tuple.dst.protonum != IPPROTO_ICMPV6 &&
1019 ct->tuplehash[dir].tuple.dst.u.all !=
1020 ct->tuplehash[!dir].tuple.src.u.all) {
1021 err = nf_xfrm_me_harder(state->net, skb, AF_INET6);
1022 if (err < 0)
1023 ret = NF_DROP_ERR(err);
1024 }
1025 #endif
1026 }
1027
1028 return ret;
1029 }
1030
1031 static const struct nf_hook_ops nf_nat_ipv6_ops[] = {
1032 /* Before packet filtering, change destination */
1033 {
1034 .hook = nf_nat_ipv6_in,
1035 .pf = NFPROTO_IPV6,
1036 .hooknum = NF_INET_PRE_ROUTING,
1037 .priority = NF_IP6_PRI_NAT_DST,
1038 .hook_ops_type = NF_HOOK_OP_NAT,
1039 },
1040 /* After packet filtering, change source */
1041 {
1042 .hook = nf_nat_ipv6_out,
1043 .pf = NFPROTO_IPV6,
1044 .hooknum = NF_INET_POST_ROUTING,
1045 .priority = NF_IP6_PRI_NAT_SRC,
1046 .hook_ops_type = NF_HOOK_OP_NAT,
1047 },
1048 /* Before packet filtering, change destination */
1049 {
1050 .hook = nf_nat_ipv6_local_fn,
1051 .pf = NFPROTO_IPV6,
1052 .hooknum = NF_INET_LOCAL_OUT,
1053 .priority = NF_IP6_PRI_NAT_DST,
1054 .hook_ops_type = NF_HOOK_OP_NAT,
1055 },
1056 /* After packet filtering, change source */
1057 {
1058 .hook = nf_nat_ipv6_local_in,
1059 .pf = NFPROTO_IPV6,
1060 .hooknum = NF_INET_LOCAL_IN,
1061 .priority = NF_IP6_PRI_NAT_SRC,
1062 .hook_ops_type = NF_HOOK_OP_NAT,
1063 },
1064 };
1065
nf_nat_ipv6_register_fn(struct net * net,const struct nf_hook_ops * ops)1066 int nf_nat_ipv6_register_fn(struct net *net, const struct nf_hook_ops *ops)
1067 {
1068 return nf_nat_register_fn(net, ops->pf, ops, nf_nat_ipv6_ops,
1069 ARRAY_SIZE(nf_nat_ipv6_ops));
1070 }
1071 EXPORT_SYMBOL_GPL(nf_nat_ipv6_register_fn);
1072
nf_nat_ipv6_unregister_fn(struct net * net,const struct nf_hook_ops * ops)1073 void nf_nat_ipv6_unregister_fn(struct net *net, const struct nf_hook_ops *ops)
1074 {
1075 nf_nat_unregister_fn(net, ops->pf, ops, ARRAY_SIZE(nf_nat_ipv6_ops));
1076 }
1077 EXPORT_SYMBOL_GPL(nf_nat_ipv6_unregister_fn);
1078 #endif /* CONFIG_IPV6 */
1079
1080 #if defined(CONFIG_NF_TABLES_INET) && IS_ENABLED(CONFIG_NFT_NAT)
nf_nat_inet_register_fn(struct net * net,const struct nf_hook_ops * ops)1081 int nf_nat_inet_register_fn(struct net *net, const struct nf_hook_ops *ops)
1082 {
1083 int ret;
1084
1085 if (WARN_ON_ONCE(ops->pf != NFPROTO_INET))
1086 return -EINVAL;
1087
1088 ret = nf_nat_register_fn(net, NFPROTO_IPV6, ops, nf_nat_ipv6_ops,
1089 ARRAY_SIZE(nf_nat_ipv6_ops));
1090 if (ret)
1091 return ret;
1092
1093 ret = nf_nat_register_fn(net, NFPROTO_IPV4, ops, nf_nat_ipv4_ops,
1094 ARRAY_SIZE(nf_nat_ipv4_ops));
1095 if (ret)
1096 nf_nat_unregister_fn(net, NFPROTO_IPV6, ops,
1097 ARRAY_SIZE(nf_nat_ipv6_ops));
1098 return ret;
1099 }
1100 EXPORT_SYMBOL_GPL(nf_nat_inet_register_fn);
1101
nf_nat_inet_unregister_fn(struct net * net,const struct nf_hook_ops * ops)1102 void nf_nat_inet_unregister_fn(struct net *net, const struct nf_hook_ops *ops)
1103 {
1104 nf_nat_unregister_fn(net, NFPROTO_IPV4, ops, ARRAY_SIZE(nf_nat_ipv4_ops));
1105 nf_nat_unregister_fn(net, NFPROTO_IPV6, ops, ARRAY_SIZE(nf_nat_ipv6_ops));
1106 }
1107 EXPORT_SYMBOL_GPL(nf_nat_inet_unregister_fn);
1108 #endif /* NFT INET NAT */
1109