FreeBSD/Linux Kernel Cross Reference
sys/netinet/ip_ipip.c
1 /* $OpenBSD: ip_ipip.c,v 1.98 2022/01/02 22:36:04 jsg Exp $ */
2 /*
3 * The authors of this code are John Ioannidis (ji@tla.org),
4 * Angelos D. Keromytis (kermit@csd.uch.gr) and
5 * Niels Provos (provos@physnet.uni-hamburg.de).
6 *
7 * The original version of this code was written by John Ioannidis
8 * for BSD/OS in Athens, Greece, in November 1995.
9 *
10 * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
11 * by Angelos D. Keromytis.
12 *
13 * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
14 * and Niels Provos.
15 *
16 * Additional features in 1999 by Angelos D. Keromytis.
17 *
18 * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
19 * Angelos D. Keromytis and Niels Provos.
20 * Copyright (c) 2001, Angelos D. Keromytis.
21 *
22 * Permission to use, copy, and modify this software with or without fee
23 * is hereby granted, provided that this entire notice is included in
24 * all copies of any software which is or includes a copy or
25 * modification of this software.
26 * You may use this code under the GNU public license if you so wish. Please
27 * contribute changes back to the authors under this freer than GPL license
28 * so that we may further the use of strong encryption without limitations to
29 * all.
30 *
31 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
32 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
33 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
34 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
35 * PURPOSE.
36 */
37
38 /*
39 * IP-inside-IP processing
40 */
41
42 #include "bpfilter.h"
43 #include "gif.h"
44 #include "pf.h"
45
46 #include <sys/param.h>
47 #include <sys/systm.h>
48 #include <sys/mbuf.h>
49 #include <sys/socket.h>
50 #include <sys/sysctl.h>
51
52 #include <net/if.h>
53 #include <net/if_types.h>
54 #include <net/if_var.h>
55 #include <net/route.h>
56 #include <net/netisr.h>
57 #include <net/bpf.h>
58
59 #include <netinet/in.h>
60 #include <netinet/ip.h>
61 #include <netinet/in_pcb.h>
62 #include <netinet/ip_var.h>
63 #include <netinet/ip_ecn.h>
64 #include <netinet/ip_ipip.h>
65
66 #ifdef MROUTING
67 #include <netinet/ip_mroute.h>
68 #endif
69
70 #if NPF > 0
71 #include <net/pfvar.h>
72 #endif
73
74 #ifdef ENCDEBUG
75 #define DPRINTF(fmt, args...) \
76 do { \
77 if (encdebug) \
78 printf("%s: " fmt "\n", __func__, ## args); \
79 } while (0)
80 #else
81 #define DPRINTF(fmt, args...) \
82 do { } while (0)
83 #endif
84
85 /*
86 * We can control the acceptance of IP4 packets by altering the sysctl
87 * net.inet.ipip.allow value. Zero means drop them, all else is acceptance.
88 */
89 int ipip_allow = 0;
90
91 struct cpumem *ipipcounters;
92
93 void
94 ipip_init(void)
95 {
96 ipipcounters = counters_alloc(ipips_ncounters);
97 }
98
99 /*
100 * Really only a wrapper for ipip_input_if(), for use with pr_input.
101 */
102 int
103 ipip_input(struct mbuf **mp, int *offp, int nxt, int af)
104 {
105 struct ifnet *ifp;
106
107 /* If we do not accept IP-in-IP explicitly, drop. */
108 if (!ipip_allow && ((*mp)->m_flags & (M_AUTH|M_CONF)) == 0) {
109 DPRINTF("dropped due to policy");
110 ipipstat_inc(ipips_pdrops);
111 m_freemp(mp);
112 return IPPROTO_DONE;
113 }
114
115 ifp = if_get((*mp)->m_pkthdr.ph_ifidx);
116 if (ifp == NULL) {
117 m_freemp(mp);
118 return IPPROTO_DONE;
119 }
120 nxt = ipip_input_if(mp, offp, nxt, af, ifp);
121 if_put(ifp);
122
123 return nxt;
124 }
125
126 /*
127 * ipip_input gets called when we receive an IP{46} encapsulated packet,
128 * either because we got it at a real interface, or because AH or ESP
129 * were being used in tunnel mode (in which case the ph_ifidx element
130 * will contain the index of the encX interface associated with the
131 * tunnel.
132 */
133
134 int
135 ipip_input_if(struct mbuf **mp, int *offp, int proto, int oaf,
136 struct ifnet *ifp)
137 {
138 struct mbuf *m = *mp;
139 struct sockaddr_in *sin;
140 struct ip *ip;
141 #ifdef INET6
142 struct sockaddr_in6 *sin6;
143 struct ip6_hdr *ip6;
144 #endif
145 int mode, hlen;
146 u_int8_t itos, otos;
147 sa_family_t iaf;
148
149 ipipstat_inc(ipips_ipackets);
150
151 switch (oaf) {
152 case AF_INET:
153 hlen = sizeof(struct ip);
154 break;
155 #ifdef INET6
156 case AF_INET6:
157 hlen = sizeof(struct ip6_hdr);
158 break;
159 #endif
160 default:
161 unhandled_af(oaf);
162 }
163
164 /* Bring the IP header in the first mbuf, if not there already */
165 if (m->m_len < hlen) {
166 if ((m = *mp = m_pullup(m, hlen)) == NULL) {
167 DPRINTF("m_pullup() failed");
168 ipipstat_inc(ipips_hdrops);
169 goto bad;
170 }
171 }
172
173 /* Keep outer ecn field. */
174 switch (oaf) {
175 case AF_INET:
176 ip = mtod(m, struct ip *);
177 otos = ip->ip_tos;
178 break;
179 #ifdef INET6
180 case AF_INET6:
181 ip6 = mtod(m, struct ip6_hdr *);
182 otos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
183 break;
184 #endif
185 }
186
187 /* Remove outer IP header */
188 KASSERT(*offp > 0);
189 m_adj(m, *offp);
190 *offp = 0;
191 ip = NULL;
192 #ifdef INET6
193 ip6 = NULL;
194 #endif
195
196 switch (proto) {
197 case IPPROTO_IPV4:
198 hlen = sizeof(struct ip);
199 break;
200
201 #ifdef INET6
202 case IPPROTO_IPV6:
203 hlen = sizeof(struct ip6_hdr);
204 break;
205 #endif
206 default:
207 ipipstat_inc(ipips_family);
208 goto bad;
209 }
210
211 /* Sanity check */
212 if (m->m_pkthdr.len < hlen) {
213 ipipstat_inc(ipips_hdrops);
214 goto bad;
215 }
216
217 /*
218 * Bring the inner header into the first mbuf, if not there already.
219 */
220 if (m->m_len < hlen) {
221 if ((m = *mp = m_pullup(m, hlen)) == NULL) {
222 DPRINTF("m_pullup() failed");
223 ipipstat_inc(ipips_hdrops);
224 goto bad;
225 }
226 }
227
228 /*
229 * RFC 1853 specifies that the inner TTL should not be touched on
230 * decapsulation. There's no reason this comment should be here, but
231 * this is as good as any a position.
232 */
233
234 /* Some sanity checks in the inner IP header */
235 switch (proto) {
236 case IPPROTO_IPV4:
237 iaf = AF_INET;
238 ip = mtod(m, struct ip *);
239 hlen = ip->ip_hl << 2;
240 if (m->m_pkthdr.len < hlen) {
241 ipipstat_inc(ipips_hdrops);
242 goto bad;
243 }
244 itos = ip->ip_tos;
245 mode = m->m_flags & (M_AUTH|M_CONF) ?
246 ECN_ALLOWED_IPSEC : ECN_ALLOWED;
247 if (!ip_ecn_egress(mode, &otos, &itos)) {
248 DPRINTF("ip_ecn_egress() failed");
249 ipipstat_inc(ipips_pdrops);
250 goto bad;
251 }
252 /* re-calculate the checksum if ip_tos was changed */
253 if (itos != ip->ip_tos)
254 ip_tos_patch(ip, itos);
255 break;
256 #ifdef INET6
257 case IPPROTO_IPV6:
258 iaf = AF_INET6;
259 ip6 = mtod(m, struct ip6_hdr *);
260 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
261 if (!ip_ecn_egress(ECN_ALLOWED, &otos, &itos)) {
262 DPRINTF("ip_ecn_egress() failed");
263 ipipstat_inc(ipips_pdrops);
264 goto bad;
265 }
266 ip6->ip6_flow &= ~htonl(0xff << 20);
267 ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
268 break;
269 #endif
270 }
271
272 /* Check for local address spoofing. */
273 if (!(ifp->if_flags & IFF_LOOPBACK) && ipip_allow != 2) {
274 struct sockaddr_storage ss;
275 struct rtentry *rt;
276
277 memset(&ss, 0, sizeof(ss));
278
279 if (ip) {
280 sin = (struct sockaddr_in *)&ss;
281 sin->sin_family = AF_INET;
282 sin->sin_len = sizeof(*sin);
283 sin->sin_addr = ip->ip_src;
284 #ifdef INET6
285 } else if (ip6) {
286 sin6 = (struct sockaddr_in6 *)&ss;
287 sin6->sin6_family = AF_INET6;
288 sin6->sin6_len = sizeof(*sin6);
289 sin6->sin6_addr = ip6->ip6_src;
290 #endif /* INET6 */
291 }
292 rt = rtalloc(sstosa(&ss), 0, m->m_pkthdr.ph_rtableid);
293 if ((rt != NULL) && (rt->rt_flags & RTF_LOCAL)) {
294 ipipstat_inc(ipips_spoof);
295 rtfree(rt);
296 goto bad;
297 }
298 rtfree(rt);
299 }
300
301 /* Statistics */
302 ipipstat_add(ipips_ibytes, m->m_pkthdr.len - hlen);
303
304 #if NBPFILTER > 0 && NGIF > 0
305 if (ifp->if_type == IFT_GIF && ifp->if_bpf != NULL)
306 bpf_mtap_af(ifp->if_bpf, iaf, m, BPF_DIRECTION_IN);
307 #endif
308 #if NPF > 0
309 pf_pkt_addr_changed(m);
310 #endif
311
312 /*
313 * Interface pointer stays the same; if no IPsec processing has
314 * been done (or will be done), this will point to a normal
315 * interface. Otherwise, it'll point to an enc interface, which
316 * will allow a packet filter to distinguish between secure and
317 * untrusted packets.
318 */
319
320 switch (proto) {
321 case IPPROTO_IPV4:
322 return ip_input_if(mp, offp, proto, oaf, ifp);
323 #ifdef INET6
324 case IPPROTO_IPV6:
325 return ip6_input_if(mp, offp, proto, oaf, ifp);
326 #endif
327 }
328 bad:
329 m_freemp(mp);
330 return IPPROTO_DONE;
331 }
332
333 int
334 ipip_output(struct mbuf **mp, struct tdb *tdb)
335 {
336 struct mbuf *m = *mp;
337 u_int8_t tp, otos, itos;
338 u_int64_t obytes;
339 struct ip *ipo;
340 #ifdef INET6
341 struct ip6_hdr *ip6, *ip6o;
342 #endif /* INET6 */
343 #ifdef ENCDEBUG
344 char buf[INET6_ADDRSTRLEN];
345 #endif
346 int error;
347
348 /* XXX Deal with empty TDB source/destination addresses. */
349
350 m_copydata(m, 0, 1, &tp);
351 tp = (tp >> 4) & 0xff; /* Get the IP version number. */
352
353 switch (tdb->tdb_dst.sa.sa_family) {
354 case AF_INET:
355 if (tdb->tdb_src.sa.sa_family != AF_INET ||
356 tdb->tdb_src.sin.sin_addr.s_addr == INADDR_ANY ||
357 tdb->tdb_dst.sin.sin_addr.s_addr == INADDR_ANY) {
358
359 DPRINTF("unspecified tunnel endpoint address "
360 "in SA %s/%08x",
361 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
362 ntohl(tdb->tdb_spi));
363
364 ipipstat_inc(ipips_unspec);
365 error = EINVAL;
366 goto drop;
367 }
368
369 M_PREPEND(*mp, sizeof(struct ip), M_DONTWAIT);
370 if (*mp == NULL) {
371 DPRINTF("M_PREPEND failed");
372 ipipstat_inc(ipips_hdrops);
373 error = ENOBUFS;
374 goto drop;
375 }
376 m = *mp;
377
378 ipo = mtod(m, struct ip *);
379
380 ipo->ip_v = IPVERSION;
381 ipo->ip_hl = 5;
382 ipo->ip_len = htons(m->m_pkthdr.len);
383 ipo->ip_ttl = ip_defttl;
384 ipo->ip_sum = 0;
385 ipo->ip_src = tdb->tdb_src.sin.sin_addr;
386 ipo->ip_dst = tdb->tdb_dst.sin.sin_addr;
387
388 /*
389 * We do the htons() to prevent snoopers from determining our
390 * endianness.
391 */
392 ipo->ip_id = htons(ip_randomid());
393
394 /* If the inner protocol is IP... */
395 if (tp == IPVERSION) {
396 /* Save ECN notification */
397 m_copydata(m, sizeof(struct ip) +
398 offsetof(struct ip, ip_tos),
399 sizeof(u_int8_t), (caddr_t) &itos);
400
401 ipo->ip_p = IPPROTO_IPIP;
402
403 /*
404 * We should be keeping tunnel soft-state and
405 * send back ICMPs if needed.
406 */
407 m_copydata(m, sizeof(struct ip) +
408 offsetof(struct ip, ip_off),
409 sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
410 ipo->ip_off = ntohs(ipo->ip_off);
411 ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
412 ipo->ip_off = htons(ipo->ip_off);
413 }
414 #ifdef INET6
415 else if (tp == (IPV6_VERSION >> 4)) {
416 u_int32_t itos32;
417
418 /* Save ECN notification. */
419 m_copydata(m, sizeof(struct ip) +
420 offsetof(struct ip6_hdr, ip6_flow),
421 sizeof(u_int32_t), (caddr_t) &itos32);
422 itos = ntohl(itos32) >> 20;
423 ipo->ip_p = IPPROTO_IPV6;
424 ipo->ip_off = 0;
425 }
426 #endif /* INET6 */
427 else {
428 ipipstat_inc(ipips_family);
429 error = EAFNOSUPPORT;
430 goto drop;
431 }
432
433 otos = 0;
434 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
435 ipo->ip_tos = otos;
436
437 obytes = m->m_pkthdr.len - sizeof(struct ip);
438 if (tdb->tdb_xform->xf_type == XF_IP4)
439 tdb->tdb_cur_bytes += obytes;
440 break;
441
442 #ifdef INET6
443 case AF_INET6:
444 if (IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_dst.sin6.sin6_addr) ||
445 tdb->tdb_src.sa.sa_family != AF_INET6 ||
446 IN6_IS_ADDR_UNSPECIFIED(&tdb->tdb_src.sin6.sin6_addr)) {
447
448 DPRINTF("unspecified tunnel endpoint address "
449 "in SA %s/%08x",
450 ipsp_address(&tdb->tdb_dst, buf, sizeof(buf)),
451 ntohl(tdb->tdb_spi));
452
453 ipipstat_inc(ipips_unspec);
454 error = EINVAL;
455 goto drop;
456 }
457
458 /* If the inner protocol is IPv6, clear link local scope */
459 if (tp == (IPV6_VERSION >> 4)) {
460 /* scoped address handling */
461 ip6 = mtod(m, struct ip6_hdr *);
462 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_src))
463 ip6->ip6_src.s6_addr16[1] = 0;
464 if (IN6_IS_SCOPE_EMBED(&ip6->ip6_dst))
465 ip6->ip6_dst.s6_addr16[1] = 0;
466 }
467
468 M_PREPEND(*mp, sizeof(struct ip6_hdr), M_DONTWAIT);
469 if (*mp == NULL) {
470 DPRINTF("M_PREPEND failed");
471 ipipstat_inc(ipips_hdrops);
472 error = ENOBUFS;
473 goto drop;
474 }
475 m = *mp;
476
477 /* Initialize IPv6 header */
478 ip6o = mtod(m, struct ip6_hdr *);
479 ip6o->ip6_flow = 0;
480 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
481 ip6o->ip6_vfc |= IPV6_VERSION;
482 ip6o->ip6_plen = htons(m->m_pkthdr.len - sizeof(*ip6o));
483 ip6o->ip6_hlim = ip_defttl;
484 in6_embedscope(&ip6o->ip6_src, &tdb->tdb_src.sin6, NULL);
485 in6_embedscope(&ip6o->ip6_dst, &tdb->tdb_dst.sin6, NULL);
486
487 if (tp == IPVERSION) {
488 /* Save ECN notification */
489 m_copydata(m, sizeof(struct ip6_hdr) +
490 offsetof(struct ip, ip_tos), sizeof(u_int8_t),
491 (caddr_t) &itos);
492
493 /* This is really IPVERSION. */
494 ip6o->ip6_nxt = IPPROTO_IPIP;
495 }
496 else
497 if (tp == (IPV6_VERSION >> 4)) {
498 u_int32_t itos32;
499
500 /* Save ECN notification. */
501 m_copydata(m, sizeof(struct ip6_hdr) +
502 offsetof(struct ip6_hdr, ip6_flow),
503 sizeof(u_int32_t), (caddr_t) &itos32);
504 itos = ntohl(itos32) >> 20;
505
506 ip6o->ip6_nxt = IPPROTO_IPV6;
507 } else {
508 ipipstat_inc(ipips_family);
509 error = EAFNOSUPPORT;
510 goto drop;
511 }
512
513 otos = 0;
514 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
515 ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
516
517 obytes = m->m_pkthdr.len - sizeof(struct ip6_hdr);
518 if (tdb->tdb_xform->xf_type == XF_IP4)
519 tdb->tdb_cur_bytes += obytes;
520 break;
521 #endif /* INET6 */
522
523 default:
524 DPRINTF("unsupported protocol family %d",
525 tdb->tdb_dst.sa.sa_family);
526 ipipstat_inc(ipips_family);
527 error = EPFNOSUPPORT;
528 goto drop;
529 }
530
531 ipipstat_pkt(ipips_opackets, ipips_obytes, obytes);
532 return 0;
533
534 drop:
535 m_freemp(mp);
536 return error;
537 }
538
539 #ifdef IPSEC
540 int
541 ipe4_attach(void)
542 {
543 return 0;
544 }
545
546 int
547 ipe4_init(struct tdb *tdbp, const struct xformsw *xsp, struct ipsecinit *ii)
548 {
549 tdbp->tdb_xform = xsp;
550 return 0;
551 }
552
553 int
554 ipe4_zeroize(struct tdb *tdbp)
555 {
556 return 0;
557 }
558
559 int
560 ipe4_input(struct mbuf **mp, struct tdb *tdb, int hlen, int proto)
561 {
562 /* This is a rather serious mistake, so no conditional printing. */
563 printf("%s: should never be called\n", __func__);
564 m_freemp(mp);
565 return EINVAL;
566 }
567 #endif /* IPSEC */
568
569 int
570 ipip_sysctl_ipipstat(void *oldp, size_t *oldlenp, void *newp)
571 {
572 struct ipipstat ipipstat;
573
574 CTASSERT(sizeof(ipipstat) == (ipips_ncounters * sizeof(uint64_t)));
575 memset(&ipipstat, 0, sizeof ipipstat);
576 counters_read(ipipcounters, (uint64_t *)&ipipstat, ipips_ncounters);
577 return (sysctl_rdstruct(oldp, oldlenp, newp,
578 &ipipstat, sizeof(ipipstat)));
579 }
580
581 int
582 ipip_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp,
583 size_t newlen)
584 {
585 int error;
586
587 /* All sysctl names at this level are terminal. */
588 if (namelen != 1)
589 return (ENOTDIR);
590
591 switch (name[0]) {
592 case IPIPCTL_ALLOW:
593 NET_LOCK();
594 error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
595 &ipip_allow, 0, 2);
596 NET_UNLOCK();
597 return (error);
598 case IPIPCTL_STATS:
599 return (ipip_sysctl_ipipstat(oldp, oldlenp, newp));
600 default:
601 return (ENOPROTOOPT);
602 }
603 /* NOTREACHED */
604 }
Cache object: bd5801e11878739f7df8f487471b8ba2
|