Merge from vendor branch ZLIB:
[dragonfly.git] / sys / netproto / ipsec / xform_ipip.c
1 /*      $FreeBSD: src/sys/netipsec/xform_ipip.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $ */
2 /*      $DragonFly: src/sys/netproto/ipsec/xform_ipip.c,v 1.9 2004/10/15 22:59:10 hsu Exp $     */
3 /*      $OpenBSD: ip_ipip.c,v 1.25 2002/06/10 18:04:55 itojun Exp $ */
4 /*
5  * The authors of this code are John Ioannidis (ji@tla.org),
6  * Angelos D. Keromytis (kermit@csd.uch.gr) and
7  * Niels Provos (provos@physnet.uni-hamburg.de).
8  *
9  * The original version of this code was written by John Ioannidis
10  * for BSD/OS in Athens, Greece, in November 1995.
11  *
12  * Ported to OpenBSD and NetBSD, with additional transforms, in December 1996,
13  * by Angelos D. Keromytis.
14  *
15  * Additional transforms and features in 1997 and 1998 by Angelos D. Keromytis
16  * and Niels Provos.
17  *
18  * Additional features in 1999 by Angelos D. Keromytis.
19  *
20  * Copyright (C) 1995, 1996, 1997, 1998, 1999 by John Ioannidis,
21  * Angelos D. Keromytis and Niels Provos.
22  * Copyright (c) 2001, Angelos D. Keromytis.
23  *
24  * Permission to use, copy, and modify this software with or without fee
25  * is hereby granted, provided that this entire notice is included in
26  * all copies of any software which is or includes a copy or
27  * modification of this software.
28  * You may use this code under the GNU public license if you so wish. Please
29  * contribute changes back to the authors under this freer than GPL license
30  * so that we may further the use of strong encryption without limitations to
31  * all.
32  *
33  * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR
34  * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY
35  * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE
36  * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR
37  * PURPOSE.
38  */
39
40 /*
41  * IP-inside-IP processing
42  */
43 #include "opt_inet.h"
44 #include "opt_inet6.h"
45 #include "opt_random_ip_id.h"
46
47 #include <sys/param.h>
48 #include <sys/systm.h>
49 #include <sys/mbuf.h>
50 #include <sys/socket.h>
51 #include <sys/kernel.h>
52 #include <sys/protosw.h>
53 #include <sys/sysctl.h>
54
55 #include <net/if.h>
56 #include <net/route.h>
57 #include <net/netisr.h>
58
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/in_var.h>
62 #include <netinet/ip.h>
63 #include <netinet/ip_ecn.h>
64 #include <netinet/ip_var.h>
65 #include <netinet/ip_encap.h>
66 #include <netinet/ipprotosw.h>
67
68 #include <netproto/ipsec/ipsec.h>
69 #include <netproto/ipsec/xform.h>
70
71 #include <netproto/ipsec/ipip_var.h>
72
73 #ifdef MROUTING
74 #include <netinet/ip_mroute.h>
75 #endif
76
77 #ifdef INET6
78 #include <netinet/ip6.h>
79 #include <netproto/ipsec/ipsec6.h>
80 #include <netinet6/ip6_ecn.h>
81 #include <netinet6/in6_var.h>
82 #include <netinet6/ip6protosw.h>
83 #endif
84
85 #include <netproto/ipsec/key.h>
86 #include <netproto/ipsec/key_debug.h>
87
88 #include <machine/stdarg.h>
89
90 typedef void    pr_in_input_t (struct mbuf *, int, int); /* XXX FIX THIS */
91
92 /*
93  * We can control the acceptance of IP4 packets by altering the sysctl
94  * net.inet.ipip.allow value.  Zero means drop them, all else is acceptance.
95  */
96 int     ipip_allow = 0;
97 struct  ipipstat ipipstat;
98
99 SYSCTL_DECL(_net_inet_ipip);
100 SYSCTL_INT(_net_inet_ipip, OID_AUTO,
101         ipip_allow,     CTLFLAG_RW,     &ipip_allow,    0, "");
102 SYSCTL_STRUCT(_net_inet_ipip, IPSECCTL_STATS,
103         stats,          CTLFLAG_RD,     &ipipstat,      ipipstat, "");
104
105 /* XXX IPCOMP */
106 #define M_IPSEC (M_AUTHIPHDR|M_AUTHIPDGM|M_DECRYPTED)
107
108 static void _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp);
109
110 #ifdef INET6
111 /*
112  * Really only a wrapper for ipip_input(), for use with IPv6.
113  */
114 int
115 ip4_input6(struct mbuf **m, int *offp, int proto)
116 {
117 #if 0
118         /* If we do not accept IP-in-IP explicitly, drop.  */
119         if (!ipip_allow && ((*m)->m_flags & M_IPSEC) == 0) {
120                 DPRINTF(("ip4_input6: dropped due to policy\n"));
121                 ipipstat.ipips_pdrops++;
122                 m_freem(*m);
123                 return IPPROTO_DONE;
124         }
125 #endif
126         _ipip_input(*m, *offp, NULL);
127         return IPPROTO_DONE;
128 }
129 #endif /* INET6 */
130
131 #ifdef INET
132 /*
133  * Really only a wrapper for ipip_input(), for use with IPv4.
134  */
135 void
136 ip4_input(struct mbuf *m, ...)
137 {
138         __va_list ap;
139         int iphlen;
140
141 #if 0
142         /* If we do not accept IP-in-IP explicitly, drop.  */
143         if (!ipip_allow && (m->m_flags & M_IPSEC) == 0) {
144                 DPRINTF(("ip4_input: dropped due to policy\n"));
145                 ipipstat.ipips_pdrops++;
146                 m_freem(m);
147                 return;
148         }
149 #endif
150         __va_start(ap, m);
151         iphlen = __va_arg(ap, int);
152         __va_end(ap);
153
154         _ipip_input(m, iphlen, NULL);
155 }
156 #endif /* INET */
157
158 /*
159  * ipip_input gets called when we receive an IP{46} encapsulated packet,
160  * either because we got it at a real interface, or because AH or ESP
161  * were being used in tunnel mode (in which case the rcvif element will
162  * contain the address of the encX interface associated with the tunnel.
163  */
164
165 static void
166 _ipip_input(struct mbuf *m, int iphlen, struct ifnet *gifp)
167 {
168         struct sockaddr_in *sin;
169         struct ifnet *ifp;
170         struct ifaddr *ifa;
171         struct ip *ipo;
172 #ifdef INET6
173         struct sockaddr_in6 *sin6;
174         struct ip6_hdr *ip6 = NULL;
175         u_int8_t itos;
176 #endif
177         u_int8_t nxt;
178         int isr;
179         u_int8_t otos;
180         u_int8_t v;
181         int hlen;
182
183         ipipstat.ipips_ipackets++;
184
185         m_copydata(m, 0, 1, &v);
186
187         switch (v >> 4) {
188 #ifdef INET
189         case 4:
190                 hlen = sizeof(struct ip);
191                 break;
192 #endif /* INET */
193 #ifdef INET6
194         case 6:
195                 hlen = sizeof(struct ip6_hdr);
196                 break;
197 #endif
198         default:
199                 DPRINTF(("_ipip_input: bad protocol version 0x%x (%u) "
200                         "for outer header\n", v, v>>4));
201                 ipipstat.ipips_family++;
202                 m_freem(m);
203                 return /* EAFNOSUPPORT */;
204         }
205
206         /* Bring the IP header in the first mbuf, if not there already */
207         if (m->m_len < hlen) {
208                 if ((m = m_pullup(m, hlen)) == NULL) {
209                         DPRINTF(("ipip_input: m_pullup (1) failed\n"));
210                         ipipstat.ipips_hdrops++;
211                         return;
212                 }
213         }
214
215         ipo = mtod(m, struct ip *);
216
217 #ifdef MROUTING
218         if (ipo->ip_v == IPVERSION && ipo->ip_p == IPPROTO_IPV4) {
219                 if (IN_MULTICAST(((struct ip *)((char *) ipo + iphlen))->ip_dst.s_addr)) {
220                         ipip_mroute_input (m, iphlen);
221                         return;
222                 }
223         }
224 #endif /* MROUTING */
225
226         /* Keep outer ecn field. */
227         switch (v >> 4) {
228 #ifdef INET
229         case 4:
230                 otos = ipo->ip_tos;
231                 break;
232 #endif /* INET */
233 #ifdef INET6
234         case 6:
235                 otos = (ntohl(mtod(m, struct ip6_hdr *)->ip6_flow) >> 20) & 0xff;
236                 break;
237 #endif
238         default:
239                 panic("ipip_input: unknown ip version %u (outer)", v>>4);
240         }
241
242         /* Remove outer IP header */
243         m_adj(m, iphlen);
244
245         /* Sanity check */
246         if (m->m_pkthdr.len < sizeof(struct ip))  {
247                 ipipstat.ipips_hdrops++;
248                 m_freem(m);
249                 return;
250         }
251
252         m_copydata(m, 0, 1, &v);
253
254         switch (v >> 4) {
255 #ifdef INET
256         case 4:
257                 hlen = sizeof(struct ip);
258                 break;
259 #endif /* INET */
260
261 #ifdef INET6
262         case 6:
263                 hlen = sizeof(struct ip6_hdr);
264                 break;
265 #endif
266         default:
267                 DPRINTF(("_ipip_input: bad protocol version 0x%x (%u) "
268                         "for inner header\n", v, v>>4));
269                 ipipstat.ipips_family++;
270                 m_freem(m);
271                 return; /* EAFNOSUPPORT */
272         }
273
274         /*
275          * Bring the inner IP header in the first mbuf, if not there already.
276          */
277         if (m->m_len < hlen) {
278                 if ((m = m_pullup(m, hlen)) == NULL) {
279                         DPRINTF(("ipip_input: m_pullup (2) failed\n"));
280                         ipipstat.ipips_hdrops++;
281                         return;
282                 }
283         }
284
285         /*
286          * RFC 1853 specifies that the inner TTL should not be touched on
287          * decapsulation. There's no reason this comment should be here, but
288          * this is as good as any a position.
289          */
290
291         /* Some sanity checks in the inner IP header */
292         switch (v >> 4) {
293 #ifdef INET
294         case 4:
295                 ipo = mtod(m, struct ip *);
296                 nxt = ipo->ip_p;
297                 ip_ecn_egress(ip4_ipsec_ecn, &otos, &ipo->ip_tos);
298                 break;
299 #endif /* INET */
300 #ifdef INET6
301         case 6:
302                 ip6 = (struct ip6_hdr *) ipo;
303                 nxt = ip6->ip6_nxt;
304                 itos = (ntohl(ip6->ip6_flow) >> 20) & 0xff;
305                 ip_ecn_egress(ip6_ipsec_ecn, &otos, &itos);
306                 ip6->ip6_flow &= ~htonl(0xff << 20);
307                 ip6->ip6_flow |= htonl((u_int32_t) itos << 20);
308                 break;
309 #endif
310         default:
311                 panic("ipip_input: unknown ip version %u (inner)", v>>4);
312         }
313
314         /* Check for local address spoofing. */
315         if ((m->m_pkthdr.rcvif == NULL ||
316             !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) &&
317             ipip_allow != 2) {
318                 TAILQ_FOREACH(ifp, &ifnet, if_link) {
319                         TAILQ_FOREACH(ifa, &ifp->if_addrlist, ifa_link) {
320 #ifdef INET
321                                 if (ipo) {
322                                         if (ifa->ifa_addr->sa_family !=
323                                             AF_INET)
324                                                 continue;
325
326                                         sin = (struct sockaddr_in *) ifa->ifa_addr;
327
328                                         if (sin->sin_addr.s_addr ==
329                                             ipo->ip_src.s_addr) {
330                                                 ipipstat.ipips_spoof++;
331                                                 m_freem(m);
332                                                 return;
333                                         }
334                                 }
335 #endif /* INET */
336
337 #ifdef INET6
338                                 if (ip6) {
339                                         if (ifa->ifa_addr->sa_family !=
340                                             AF_INET6)
341                                                 continue;
342
343                                         sin6 = (struct sockaddr_in6 *) ifa->ifa_addr;
344
345                                         if (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_src)) {
346                                                 ipipstat.ipips_spoof++;
347                                                 m_freem(m);
348                                                 return;
349                                         }
350
351                                 }
352 #endif /* INET6 */
353                         }
354                 }
355         }
356
357         /* Statistics */
358         ipipstat.ipips_ibytes += m->m_pkthdr.len - iphlen;
359
360         /*
361          * Interface pointer stays the same; if no IPsec processing has
362          * been done (or will be done), this will point to a normal
363          * interface. Otherwise, it'll point to an enc interface, which
364          * will allow a packet filter to distinguish between secure and
365          * untrusted packets.
366          */
367
368         switch (v >> 4) {
369 #ifdef INET
370         case 4:
371                 isr = NETISR_IP;
372                 break;
373 #endif
374 #ifdef INET6
375         case 6:
376                 isr = NETISR_IPV6;
377                 break;
378 #endif
379         default:
380                 panic("ipip_input: should never reach here");
381         }
382
383         if (netisr_queue(isr, m)) {
384                 ipipstat.ipips_qfull++;
385
386                 DPRINTF(("ipip_input: packet dropped because of full queue\n"));
387         }
388 }
389
390 int
391 ipip_output(
392         struct mbuf *m,
393         struct ipsecrequest *isr,
394         struct mbuf **mp,
395         int skip,
396         int protoff
397 )
398 {
399         struct secasvar *sav;
400         u_int8_t tp, otos;
401         struct secasindex *saidx;
402         int error;
403 #ifdef INET
404         u_int8_t itos;
405         struct ip *ipo;
406 #endif /* INET */
407 #ifdef INET6
408         struct ip6_hdr *ip6, *ip6o;
409 #endif /* INET6 */
410
411         SPLASSERT(net, "ipip_output");
412
413         sav = isr->sav;
414         KASSERT(sav != NULL, ("ipip_output: null SA"));
415         KASSERT(sav->sah != NULL, ("ipip_output: null SAH"));
416
417         /* XXX Deal with empty TDB source/destination addresses. */
418
419         m_copydata(m, 0, 1, &tp);
420         tp = (tp >> 4) & 0xff;  /* Get the IP version number. */
421
422         saidx = &sav->sah->saidx;
423         switch (saidx->dst.sa.sa_family) {
424 #ifdef INET
425         case AF_INET:
426                 if (saidx->src.sa.sa_family != AF_INET ||
427                     saidx->src.sin.sin_addr.s_addr == INADDR_ANY ||
428                     saidx->dst.sin.sin_addr.s_addr == INADDR_ANY) {
429                         DPRINTF(("ipip_output: unspecified tunnel endpoint "
430                             "address in SA %s/%08lx\n",
431                             ipsec_address(&saidx->dst),
432                             (u_long) ntohl(sav->spi)));
433                         ipipstat.ipips_unspec++;
434                         error = EINVAL;
435                         goto bad;
436                 }
437
438                 M_PREPEND(m, sizeof(struct ip), MB_DONTWAIT);
439                 if (m == 0) {
440                         DPRINTF(("ipip_output: M_PREPEND failed\n"));
441                         ipipstat.ipips_hdrops++;
442                         error = ENOBUFS;
443                         goto bad;
444                 }
445
446                 ipo = mtod(m, struct ip *);
447
448                 ipo->ip_v = IPVERSION;
449                 ipo->ip_hl = 5;
450                 ipo->ip_len = htons(m->m_pkthdr.len);
451                 ipo->ip_ttl = ip_defttl;
452                 ipo->ip_sum = 0;
453                 ipo->ip_src = saidx->src.sin.sin_addr;
454                 ipo->ip_dst = saidx->dst.sin.sin_addr;
455
456 #ifdef RANDOM_IP_ID
457                 ipo->ip_id = ip_randomid();
458 #else
459                 ipo->ip_id = htons(ip_id++);
460 #endif
461
462                 /* If the inner protocol is IP... */
463                 if (tp == IPVERSION) {
464                         /* Save ECN notification */
465                         m_copydata(m, sizeof(struct ip) +
466                             offsetof(struct ip, ip_tos),
467                             sizeof(u_int8_t), (caddr_t) &itos);
468
469                         ipo->ip_p = IPPROTO_IPIP;
470
471                         /*
472                          * We should be keeping tunnel soft-state and
473                          * send back ICMPs if needed.
474                          */
475                         m_copydata(m, sizeof(struct ip) +
476                             offsetof(struct ip, ip_off),
477                             sizeof(u_int16_t), (caddr_t) &ipo->ip_off);
478                         ipo->ip_off = ntohs(ipo->ip_off);
479                         ipo->ip_off &= ~(IP_DF | IP_MF | IP_OFFMASK);
480                         ipo->ip_off = htons(ipo->ip_off);
481                 }
482 #ifdef INET6
483                 else if (tp == (IPV6_VERSION >> 4)) {
484                         u_int32_t itos32;
485
486                         /* Save ECN notification. */
487                         m_copydata(m, sizeof(struct ip) +
488                             offsetof(struct ip6_hdr, ip6_flow),
489                             sizeof(u_int32_t), (caddr_t) &itos32);
490                         itos = ntohl(itos32) >> 20;
491                         ipo->ip_p = IPPROTO_IPV6;
492                         ipo->ip_off = 0;
493                 }
494 #endif /* INET6 */
495                 else {
496                         goto nofamily;
497                 }
498
499                 otos = 0;
500                 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
501                 ipo->ip_tos = otos;
502                 break;
503 #endif /* INET */
504
505 #ifdef INET6
506         case AF_INET6:
507                 if (IN6_IS_ADDR_UNSPECIFIED(&saidx->dst.sin6.sin6_addr) ||
508                     saidx->src.sa.sa_family != AF_INET6 ||
509                     IN6_IS_ADDR_UNSPECIFIED(&saidx->src.sin6.sin6_addr)) {
510                         DPRINTF(("ipip_output: unspecified tunnel endpoint "
511                             "address in SA %s/%08lx\n",
512                             ipsec_address(&saidx->dst),
513                             (u_long) ntohl(sav->spi)));
514                         ipipstat.ipips_unspec++;
515                         error = ENOBUFS;
516                         goto bad;
517                 }
518
519                 /* scoped address handling */
520                 ip6 = mtod(m, struct ip6_hdr *);
521                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_src))
522                         ip6->ip6_src.s6_addr16[1] = 0;
523                 if (IN6_IS_SCOPE_LINKLOCAL(&ip6->ip6_dst))
524                         ip6->ip6_dst.s6_addr16[1] = 0;
525
526                 M_PREPEND(m, sizeof(struct ip6_hdr), MB_DONTWAIT);
527                 if (m == 0) {
528                         DPRINTF(("ipip_output: M_PREPEND failed\n"));
529                         ipipstat.ipips_hdrops++;
530                         *mp = NULL;
531                         error = ENOBUFS;
532                         goto bad;
533                 }
534
535                 /* Initialize IPv6 header */
536                 ip6o = mtod(m, struct ip6_hdr *);
537                 ip6o->ip6_flow = 0;
538                 ip6o->ip6_vfc &= ~IPV6_VERSION_MASK;
539                 ip6o->ip6_vfc |= IPV6_VERSION;
540                 ip6o->ip6_plen = htons(m->m_pkthdr.len);
541                 ip6o->ip6_hlim = ip_defttl;
542                 ip6o->ip6_dst = saidx->dst.sin6.sin6_addr;
543                 ip6o->ip6_src = saidx->src.sin6.sin6_addr;
544
545 #ifdef INET
546                 if (tp == IPVERSION) {
547                         /* Save ECN notification */
548                         m_copydata(m, sizeof(struct ip6_hdr) +
549                             offsetof(struct ip, ip_tos), sizeof(u_int8_t),
550                             (caddr_t) &itos);
551
552                         /* This is really IPVERSION. */
553                         ip6o->ip6_nxt = IPPROTO_IPIP;
554                 } else
555 #endif /* INET */
556                         if (tp == (IPV6_VERSION >> 4)) {
557                                 u_int32_t itos32;
558
559                                 /* Save ECN notification. */
560                                 m_copydata(m, sizeof(struct ip6_hdr) +
561                                     offsetof(struct ip6_hdr, ip6_flow),
562                                     sizeof(u_int32_t), (caddr_t) &itos32);
563                                 itos = ntohl(itos32) >> 20;
564
565                                 ip6o->ip6_nxt = IPPROTO_IPV6;
566                         } else {
567                                 goto nofamily;
568                         }
569
570                 otos = 0;
571                 ip_ecn_ingress(ECN_ALLOWED, &otos, &itos);
572                 ip6o->ip6_flow |= htonl((u_int32_t) otos << 20);
573                 break;
574 #endif /* INET6 */
575
576         default:
577 nofamily:
578                 DPRINTF(("ipip_output: unsupported protocol family %u\n",
579                     saidx->dst.sa.sa_family));
580                 ipipstat.ipips_family++;
581                 error = EAFNOSUPPORT;           /* XXX diffs from openbsd */
582                 goto bad;
583         }
584
585         ipipstat.ipips_opackets++;
586         *mp = m;
587
588 #ifdef INET
589         if (saidx->dst.sa.sa_family == AF_INET) {
590 #if 0
591                 if (sav->tdb_xform->xf_type == XF_IP4)
592                         tdb->tdb_cur_bytes +=
593                             m->m_pkthdr.len - sizeof(struct ip);
594 #endif
595                 ipipstat.ipips_obytes += m->m_pkthdr.len - sizeof(struct ip);
596         }
597 #endif /* INET */
598
599 #ifdef INET6
600         if (saidx->dst.sa.sa_family == AF_INET6) {
601 #if 0
602                 if (sav->tdb_xform->xf_type == XF_IP4)
603                         tdb->tdb_cur_bytes +=
604                             m->m_pkthdr.len - sizeof(struct ip6_hdr);
605 #endif
606                 ipipstat.ipips_obytes +=
607                     m->m_pkthdr.len - sizeof(struct ip6_hdr);
608         }
609 #endif /* INET6 */
610
611         return 0;
612 bad:
613         if (m)
614                 m_freem(m), *mp = NULL;
615         return (error);
616 }
617
618 #ifdef FAST_IPSEC
619 static int
620 ipe4_init(struct secasvar *sav, struct xformsw *xsp)
621 {
622         sav->tdb_xform = xsp;
623         return 0;
624 }
625
626 static int
627 ipe4_zeroize(struct secasvar *sav)
628 {
629         sav->tdb_xform = NULL;
630         return 0;
631 }
632
633 static int
634 ipe4_input(struct mbuf *m, struct secasvar *sav, int skip, int protoff)
635 {
636         /* This is a rather serious mistake, so no conditional printing. */
637         printf("ipe4_input: should never be called\n");
638         if (m)
639                 m_freem(m);
640         return EOPNOTSUPP;
641 }
642
643 static struct xformsw ipe4_xformsw = {
644         XF_IP4,         0,              "IPv4 Simple Encapsulation",
645         ipe4_init,      ipe4_zeroize,   ipe4_input,     ipip_output,
646 };
647
648 extern struct domain inetdomain;
649 static struct ipprotosw ipe4_protosw[] = {
650 { SOCK_RAW,     &inetdomain,    IPPROTO_IPV4,   PR_ATOMIC|PR_ADDR|PR_LASTHDR,
651   ip4_input,
652                 0,              0,              rip_ctloutput,
653   cpu0_soport,
654   0,            0,              0,              0,
655   &rip_usrreqs
656 },
657 #ifdef INET6
658 { SOCK_RAW,     &inetdomain,    IPPROTO_IPV6,   PR_ATOMIC|PR_ADDR|PR_LASTHDR,
659   ip4_input,
660                 0,              0,              rip_ctloutput,
661   cpu0_soport,
662   0,            0,              0,              0,
663   &rip_usrreqs
664 }
665 #endif
666 };
667
668 /*
669  * Check the encapsulated packet to see if we want it
670  */
671 static int
672 ipe4_encapcheck(const struct mbuf *m, int off, int proto, void *arg)
673 {
674         /*
675          * Only take packets coming from IPSEC tunnels; the rest
676          * must be handled by the gif tunnel code.  Note that we
677          * also return a minimum priority when we want the packet
678          * so any explicit gif tunnels take precedence.
679          */
680         return ((m->m_flags & M_IPSEC) != 0 ? 1 : 0);
681 }
682
683 static void
684 ipe4_attach(void)
685 {
686         xform_register(&ipe4_xformsw);
687         /* attach to encapsulation framework */
688         /* XXX save return cookie for detach on module remove */
689         (void) encap_attach_func(AF_INET, -1,
690                 ipe4_encapcheck, (struct protosw*) &ipe4_protosw[0], NULL);
691 #ifdef INET6
692         (void) encap_attach_func(AF_INET6, -1,
693                 ipe4_encapcheck, (struct protosw*) &ipe4_protosw[1], NULL);
694 #endif
695 }
696 SYSINIT(ipe4_xform_init, SI_SUB_PROTO_DOMAIN, SI_ORDER_MIDDLE, ipe4_attach, NULL);
697 #endif  /* FAST_IPSEC */