2 /* $KAME: if_gif.c,v 1.87 2001/10/19 08:50:27 itojun Exp $ */
5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the project nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 #include "opt_inet6.h"
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/kernel.h>
41 #include <sys/malloc.h>
43 #include <sys/socket.h>
44 #include <sys/sockio.h>
45 #include <sys/errno.h>
47 #include <sys/sysctl.h>
48 #include <sys/syslog.h>
49 #include <sys/protosw.h>
51 #include <machine/cpu.h>
54 #include <net/if_types.h>
55 #include <net/netisr.h>
56 #include <net/route.h>
59 #include <netinet/in.h>
60 #include <netinet/in_systm.h>
61 #include <netinet/ip.h>
63 #include <netinet/in_var.h>
64 #include <netinet/in_gif.h>
65 #include <netinet/ip_var.h>
70 #include <netinet/in.h>
72 #include <netinet6/in6_var.h>
73 #include <netinet/ip6.h>
74 #include <netinet6/ip6_var.h>
75 #include <netinet6/in6_gif.h>
76 #include <netinet6/ip6protosw.h>
79 #include <netinet/ip_encap.h>
80 #include <net/if_gif.h>
82 #include <net/net_osdep.h>
86 static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface");
87 static LIST_HEAD(, gif_softc) gif_softc_list;
89 void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af);
90 void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af);
91 void (*ng_gif_attach_p)(struct ifnet *ifp);
92 void (*ng_gif_detach_p)(struct ifnet *ifp);
94 int gif_clone_create(struct if_clone *, int);
95 void gif_clone_destroy(struct ifnet *);
97 struct if_clone gif_cloner = IF_CLONE_INITIALIZER("gif",
98 gif_clone_create, gif_clone_destroy, 0, IF_MAXUNIT);
100 static int gifmodevent(module_t, int, void *);
102 SYSCTL_DECL(_net_link);
103 SYSCTL_NODE(_net_link, IFT_GIF, gif, CTLFLAG_RW, 0,
104 "Generic Tunnel Interface");
107 * This macro controls the default upper limitation on nesting of gif tunnels.
108 * Since, setting a large value to this macro with a careless configuration
109 * may introduce system crash, we don't allow any nestings by default.
110 * If you need to configure nested gif tunnels, you can define this macro
111 * in your kernel configuration file. However, if you do so, please be
112 * careful to configure the tunnels so that it won't make a loop.
114 #define MAX_GIF_NEST 1
116 static int max_gif_nesting = MAX_GIF_NEST;
117 SYSCTL_INT(_net_link_gif, OID_AUTO, max_nesting, CTLFLAG_RW,
118 &max_gif_nesting, 0, "Max nested tunnels");
121 * By default, we disallow creation of multiple tunnels between the same
122 * pair of addresses. Some applications require this functionality so
123 * we allow control over this check here.
126 static int parallel_tunnels = 1;
128 static int parallel_tunnels = 0;
130 SYSCTL_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW,
131 ¶llel_tunnels, 0, "Allow parallel tunnels?");
134 gif_clone_create(ifc, unit)
135 struct if_clone *ifc;
138 struct gif_softc *sc;
140 sc = malloc (sizeof(struct gif_softc), M_GIF, M_WAITOK);
141 bzero(sc, sizeof(struct gif_softc));
143 sc->gif_if.if_softc = sc;
144 sc->gif_if.if_name = GIFNAME;
145 sc->gif_if.if_unit = unit;
149 LIST_INSERT_HEAD(&gif_softc_list, sc, gif_list);
155 struct gif_softc *sc;
158 sc->encap_cookie4 = sc->encap_cookie6 = NULL;
160 sc->gif_if.if_addrlen = 0;
161 sc->gif_if.if_mtu = GIF_MTU;
162 sc->gif_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
164 /* turn off ingress filter */
165 sc->gif_if.if_flags |= IFF_LINK2;
167 sc->gif_if.if_ioctl = gif_ioctl;
168 sc->gif_if.if_output = gif_output;
169 sc->gif_if.if_type = IFT_GIF;
170 sc->gif_if.if_snd.ifq_maxlen = IFQ_MAXLEN;
171 if_attach(&sc->gif_if);
172 bpfattach(&sc->gif_if, DLT_NULL, sizeof(u_int));
173 if (ng_gif_attach_p != NULL)
174 (*ng_gif_attach_p)(&sc->gif_if);
178 gif_clone_destroy(ifp)
182 struct gif_softc *sc = ifp->if_softc;
184 gif_delete_tunnel(&sc->gif_if);
185 LIST_REMOVE(sc, gif_list);
187 if (sc->encap_cookie6 != NULL) {
188 err = encap_detach(sc->encap_cookie6);
189 KASSERT(err == 0, ("Unexpected error detaching encap_cookie6"));
193 if (sc->encap_cookie4 != NULL) {
194 err = encap_detach(sc->encap_cookie4);
195 KASSERT(err == 0, ("Unexpected error detaching encap_cookie4"));
199 if (ng_gif_detach_p != NULL)
200 (*ng_gif_detach_p)(ifp);
208 gifmodevent(mod, type, data)
216 LIST_INIT(&gif_softc_list);
217 if_clone_attach(&gif_cloner);
220 ip6_gif_hlim = GIF_HLIM;
225 if_clone_detach(&gif_cloner);
227 while (!LIST_EMPTY(&gif_softc_list))
228 gif_clone_destroy(&LIST_FIRST(&gif_softc_list)->gif_if);
238 static moduledata_t gif_mod = {
244 DECLARE_MODULE(if_gif, gif_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
245 MODULE_VERSION(if_gif, 1);
248 gif_encapcheck(m, off, proto, arg)
249 const struct mbuf *m;
255 struct gif_softc *sc;
257 sc = (struct gif_softc *)arg;
261 if ((sc->gif_if.if_flags & IFF_UP) == 0)
264 /* no physical address */
265 if (!sc->gif_psrc || !sc->gif_pdst)
281 /* Bail on short packets */
282 if (m->m_pkthdr.len < sizeof(ip))
285 m_copydata(m, 0, sizeof(ip), (caddr_t)&ip);
290 if (sc->gif_psrc->sa_family != AF_INET ||
291 sc->gif_pdst->sa_family != AF_INET)
293 return gif_encapcheck4(m, off, proto, arg);
297 if (m->m_pkthdr.len < sizeof(struct ip6_hdr))
299 if (sc->gif_psrc->sa_family != AF_INET6 ||
300 sc->gif_pdst->sa_family != AF_INET6)
302 return gif_encapcheck6(m, off, proto, arg);
310 gif_output(ifp, m, dst, rt)
313 struct sockaddr *dst;
314 struct rtentry *rt; /* added in net2 */
316 struct gif_softc *sc = (struct gif_softc*)ifp;
318 static int called = 0; /* XXX: MUTEX */
321 error = mac_check_ifnet_transmit(ifp, m);
329 * gif may cause infinite recursion calls when misconfigured.
330 * We'll prevent this by introducing upper limit.
331 * XXX: this mechanism may introduce another problem about
332 * mutual exclusion of the variable CALLED, especially if we
335 if (++called > max_gif_nesting) {
337 "gif_output: recursively called too many times(%d)\n",
340 error = EIO; /* is there better errno? */
344 m->m_flags &= ~(M_BCAST|M_MCAST);
345 if (!(ifp->if_flags & IFF_UP) ||
346 sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
354 * We need to prepend the address family as
355 * a four byte field. Cons up a dummy header
356 * to pacify bpf. This is safe because bpf
357 * will only read from the mbuf (i.e., it won't
358 * try to free it or keep a pointer a to it).
361 u_int32_t af = dst->sa_family;
365 m0.m_data = (char *)⁡
370 ifp->if_obytes += m->m_pkthdr.len;
372 /* inner AF-specific encapsulation */
374 /* XXX should we check if our outer source is legal? */
376 /* dispatch to output logic based on outer AF */
377 switch (sc->gif_psrc->sa_family) {
380 error = in_gif_output(ifp, dst->sa_family, m);
385 error = in6_gif_output(ifp, dst->sa_family, m);
395 called = 0; /* reset recursion counter */
402 gif_input(m, af, ifp)
415 m->m_pkthdr.rcvif = ifp;
418 mac_create_mbuf_from_ifnet(ifp, m);
423 * We need to prepend the address family as
424 * a four byte field. Cons up a dummy header
425 * to pacify bpf. This is safe because bpf
426 * will only read from the mbuf (i.e., it won't
427 * try to free it or keep a pointer a to it).
434 m0.m_data = (char *)&af1;
439 if (ng_gif_input_p != NULL) {
440 (*ng_gif_input_p)(ifp, &m, af);
446 * Put the packet to the network layer input queue according to the
447 * specified address family.
448 * Note: older versions of gif_input directly called network layer
449 * input functions, e.g. ip6_input, here. We changed the policy to
450 * prevent too many recursive calls of such input functions, which
451 * might cause kernel panic. But the change may introduce another
452 * problem; if the input queue is full, packets are discarded.
453 * The kernel stack overflow really happened, and we believed
454 * queue-full rarely occurs, so we changed the policy.
468 if (ng_gif_input_orphan_p != NULL)
469 (*ng_gif_input_orphan_p)(ifp, m, af);
476 ifp->if_ibytes += m->m_pkthdr.len;
477 netisr_dispatch(isr, m);
480 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
482 gif_ioctl(ifp, cmd, data)
487 struct gif_softc *sc = (struct gif_softc*)ifp;
488 struct ifreq *ifr = (struct ifreq*)data;
490 struct sockaddr *dst, *src;
491 #ifdef SIOCSIFMTU /* xxx */
497 ifp->if_flags |= IFF_UP;
507 #ifdef SIOCSIFMTU /* xxx */
513 if (mtu < GIF_MTU_MIN || mtu > GIF_MTU_MAX)
517 #endif /* SIOCSIFMTU */
523 case SIOCSIFPHYADDR_IN6:
525 case SIOCSLIFPHYADDR:
529 src = (struct sockaddr *)
530 &(((struct in_aliasreq *)data)->ifra_addr);
531 dst = (struct sockaddr *)
532 &(((struct in_aliasreq *)data)->ifra_dstaddr);
536 case SIOCSIFPHYADDR_IN6:
537 src = (struct sockaddr *)
538 &(((struct in6_aliasreq *)data)->ifra_addr);
539 dst = (struct sockaddr *)
540 &(((struct in6_aliasreq *)data)->ifra_dstaddr);
543 case SIOCSLIFPHYADDR:
544 src = (struct sockaddr *)
545 &(((struct if_laddrreq *)data)->addr);
546 dst = (struct sockaddr *)
547 &(((struct if_laddrreq *)data)->dstaddr);
553 /* sa_family must be equal */
554 if (src->sa_family != dst->sa_family)
557 /* validate sa_len */
558 switch (src->sa_family) {
561 if (src->sa_len != sizeof(struct sockaddr_in))
567 if (src->sa_len != sizeof(struct sockaddr_in6))
574 switch (dst->sa_family) {
577 if (dst->sa_len != sizeof(struct sockaddr_in))
583 if (dst->sa_len != sizeof(struct sockaddr_in6))
591 /* check sa_family looks sane for the cmd */
594 if (src->sa_family == AF_INET)
598 case SIOCSIFPHYADDR_IN6:
599 if (src->sa_family == AF_INET6)
603 case SIOCSLIFPHYADDR:
604 /* checks done in the above */
608 error = gif_set_tunnel(&sc->gif_if, src, dst);
611 #ifdef SIOCDIFPHYADDR
613 gif_delete_tunnel(&sc->gif_if);
617 case SIOCGIFPSRCADDR:
619 case SIOCGIFPSRCADDR_IN6:
621 if (sc->gif_psrc == NULL) {
622 error = EADDRNOTAVAIL;
628 case SIOCGIFPSRCADDR:
629 dst = &ifr->ifr_addr;
630 size = sizeof(ifr->ifr_addr);
634 case SIOCGIFPSRCADDR_IN6:
635 dst = (struct sockaddr *)
636 &(((struct in6_ifreq *)data)->ifr_addr);
637 size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
641 error = EADDRNOTAVAIL;
644 if (src->sa_len > size)
646 bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
649 case SIOCGIFPDSTADDR:
651 case SIOCGIFPDSTADDR_IN6:
653 if (sc->gif_pdst == NULL) {
654 error = EADDRNOTAVAIL;
660 case SIOCGIFPDSTADDR:
661 dst = &ifr->ifr_addr;
662 size = sizeof(ifr->ifr_addr);
666 case SIOCGIFPDSTADDR_IN6:
667 dst = (struct sockaddr *)
668 &(((struct in6_ifreq *)data)->ifr_addr);
669 size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
673 error = EADDRNOTAVAIL;
676 if (src->sa_len > size)
678 bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
681 case SIOCGLIFPHYADDR:
682 if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
683 error = EADDRNOTAVAIL;
689 dst = (struct sockaddr *)
690 &(((struct if_laddrreq *)data)->addr);
691 size = sizeof(((struct if_laddrreq *)data)->addr);
692 if (src->sa_len > size)
694 bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
698 dst = (struct sockaddr *)
699 &(((struct if_laddrreq *)data)->dstaddr);
700 size = sizeof(((struct if_laddrreq *)data)->dstaddr);
701 if (src->sa_len > size)
703 bcopy((caddr_t)src, (caddr_t)dst, src->sa_len);
707 /* if_ioctl() takes care of it */
719 gif_set_tunnel(ifp, src, dst)
721 struct sockaddr *src;
722 struct sockaddr *dst;
724 struct gif_softc *sc = (struct gif_softc *)ifp;
725 struct gif_softc *sc2;
726 struct sockaddr *osrc, *odst, *sa;
732 LIST_FOREACH(sc2, &gif_softc_list, gif_list) {
735 if (!sc2->gif_pdst || !sc2->gif_psrc)
737 if (sc2->gif_pdst->sa_family != dst->sa_family ||
738 sc2->gif_pdst->sa_len != dst->sa_len ||
739 sc2->gif_psrc->sa_family != src->sa_family ||
740 sc2->gif_psrc->sa_len != src->sa_len)
744 * Disallow parallel tunnels unless instructed
747 if (!parallel_tunnels &&
748 bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 &&
749 bcmp(sc2->gif_psrc, src, src->sa_len) == 0) {
750 error = EADDRNOTAVAIL;
754 /* XXX both end must be valid? (I mean, not 0.0.0.0) */
757 /* XXX we can detach from both, but be polite just in case */
759 switch (sc->gif_psrc->sa_family) {
762 (void)in_gif_detach(sc);
767 (void)in6_gif_detach(sc);
773 sa = (struct sockaddr *)malloc(src->sa_len, M_IFADDR, M_WAITOK);
774 bcopy((caddr_t)src, (caddr_t)sa, src->sa_len);
778 sa = (struct sockaddr *)malloc(dst->sa_len, M_IFADDR, M_WAITOK);
779 bcopy((caddr_t)dst, (caddr_t)sa, dst->sa_len);
782 switch (sc->gif_psrc->sa_family) {
785 error = in_gif_attach(sc);
790 error = in6_gif_attach(sc);
796 free((caddr_t)sc->gif_psrc, M_IFADDR);
797 free((caddr_t)sc->gif_pdst, M_IFADDR);
804 free((caddr_t)osrc, M_IFADDR);
806 free((caddr_t)odst, M_IFADDR);
808 if (sc->gif_psrc && sc->gif_pdst)
809 ifp->if_flags |= IFF_RUNNING;
811 ifp->if_flags &= ~IFF_RUNNING;
817 if (sc->gif_psrc && sc->gif_pdst)
818 ifp->if_flags |= IFF_RUNNING;
820 ifp->if_flags &= ~IFF_RUNNING;
827 gif_delete_tunnel(ifp)
830 struct gif_softc *sc = (struct gif_softc *)ifp;
836 free((caddr_t)sc->gif_psrc, M_IFADDR);
840 free((caddr_t)sc->gif_pdst, M_IFADDR);
843 /* it is safe to detach from both */
845 (void)in_gif_detach(sc);
848 (void)in6_gif_detach(sc);
851 if (sc->gif_psrc && sc->gif_pdst)
852 ifp->if_flags |= IFF_RUNNING;
854 ifp->if_flags &= ~IFF_RUNNING;