2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
28 /* $FreeBSD: src/sys/net/if_gif.c,v 1.4.2.6 2001/07/24 19:10:18 brooks Exp $ */
29 /* $KAME: if_gif.c,v 1.47 2001/05/01 05:28:42 itojun Exp $ */
32 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
33 * All rights reserved.
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. Neither the name of the project nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
47 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 #include <sys/param.h>
61 #include <sys/systm.h>
62 #include <sys/kernel.h>
63 #include <sys/malloc.h>
65 #include <sys/socket.h>
66 #include <sys/sockio.h>
67 #include <sys/errno.h>
69 #include <sys/syslog.h>
70 #include <sys/protosw.h>
71 #include <kern/cpu_number.h>
74 #include <net/if_types.h>
75 #include <net/route.h>
78 #include <netinet/in.h>
79 #include <netinet/in_systm.h>
80 #include <netinet/ip.h>
82 #include <netinet/in_var.h>
83 #include <netinet/in_gif.h>
84 #include <netinet/ip_var.h>
88 #include <netinet6/in6_var.h>
89 #include <netinet/ip6.h>
90 #include <netinet6/ip6_var.h>
91 #include <netinet6/in6_gif.h>
92 #include <netinet6/ip6protosw.h>
95 #include <netinet/ip_encap.h>
97 #include <net/if_gif.h>
99 #include <net/net_osdep.h>
101 #define GIFNAME "gif"
102 #define GIFDEV "if_gif"
103 #define GIF_MAXUNIT 0x7fff /* ifp->if_unit is only 15 bits */
106 static MALLOC_DEFINE(M_GIF
, "gif", "Generic Tunnel Interface");
109 TAILQ_HEAD(gifhead
, gif_softc
) gifs
= TAILQ_HEAD_INITIALIZER(gifs
);
112 void gifattach(void);
113 int gif_pre_output(struct ifnet
*ifp
, u_long protocol_family
, struct mbuf
**m0
,
114 const struct sockaddr
*dst
, caddr_t rt
, char *frame
, char *address
);
115 static void gif_create_dev(void);
116 static int gif_encapcheck(const struct mbuf
*, int, int, void*);
119 int ngif
= 0; /* number of interfaces */
123 struct protosw in_gif_protosw
=
124 { SOCK_RAW
, 0, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC
|PR_ADDR
,
125 in_gif_input
, 0, 0, 0,
134 struct ip6protosw in6_gif_protosw
=
135 { SOCK_RAW
, 0, 0/*IPPROTO_IPV[46]*/, PR_ATOMIC
|PR_ADDR
,
136 in6_gif_input
, 0, 0, 0,
148 * This macro controls the upper limitation on nesting of gif tunnels.
149 * Since, setting a large value to this macro with a careless configuration
150 * may introduce system crash, we don't allow any nestings by default.
151 * If you need to configure nested gif tunnels, you can define this macro
152 * in your kernel configuration file. However, if you do so, please be
153 * careful to configure the tunnels so that it won't make a loop.
155 #define MAX_GIF_NEST 1
157 static int max_gif_nesting
= MAX_GIF_NEST
;
163 * Theory of operation: initially, one gif interface is created.
164 * Any time a gif interface is configured, if there are no other
165 * unconfigured gif interfaces, a new gif interface is created.
166 * BSD uses the clone mechanism to dynamically create more
169 * We have some extra glue to support DLIL.
172 /* GIF interface module support */
177 u_long
*protocol_family
)
179 struct gif_softc
* gif
= (struct gif_softc
*)ifp
->if_softc
;
181 /* Only one protocol may be attached to a gif interface. */
182 *protocol_family
= gif
->gif_proto
;
188 int gif_add_proto(struct ifnet
*ifp
, u_long protocol_family
, struct ddesc_head_str
*desc_head
)
190 /* Only one protocol may be attached at a time */
191 struct gif_softc
* gif
= (struct gif_softc
*)ifp
->if_softc
;
193 if (gif
->gif_proto
!= 0)
194 printf("gif_add_proto: request add_proto for gif%d\n", gif
->gif_if
.if_unit
);
196 gif
->gif_proto
= protocol_family
;
202 int gif_del_proto(struct ifnet
*ifp
, u_long protocol_family
)
204 if (((struct gif_softc
*)ifp
)->gif_proto
== protocol_family
)
205 ((struct gif_softc
*)ifp
)->gif_proto
= 0;
212 /* Glue code to attach inet to a gif interface through DLIL */
214 gif_attach_proto_family(
216 u_long protocol_family
)
218 struct dlil_proto_reg_str reg
;
221 bzero(®
, sizeof(reg
));
222 TAILQ_INIT(®
.demux_desc_head
);
223 reg
.interface_family
= ifp
->if_family
;
224 reg
.unit_number
= ifp
->if_unit
;
225 reg
.input
= gif_input
;
226 reg
.pre_output
= gif_pre_output
;
227 reg
.protocol_family
= protocol_family
;
229 stat
= dlil_attach_protocol(®
);
230 if (stat
&& stat
!= EEXIST
) {
231 panic("gif_attach_proto_family can't attach interface fam=%d\n", protocol_family
);
239 /* Function to setup the first gif interface */
245 /* Init the list of interfaces */
248 /* Register protocol registration functions */
249 if ( error
= dlil_reg_proto_module(AF_INET
, APPLE_IF_FAM_GIF
, gif_attach_proto_family
, NULL
) != 0)
250 printf("dlil_reg_proto_module failed for AF_INET error=%d\n", error
);
252 if ( error
= dlil_reg_proto_module(AF_INET6
, APPLE_IF_FAM_GIF
, gif_attach_proto_family
, NULL
) != 0)
253 printf("dlil_reg_proto_module failed for AF_INET6 error=%d\n", error
);
255 /* Create first device */
259 /* Creates another gif device if there are none free */
263 struct gif_softc
*sc
;
266 /* Can't create more than GIF_MAXUNIT */
267 if (ngif
>= GIF_MAXUNIT
)
270 /* Check for unused gif interface */
271 TAILQ_FOREACH(sc
, &gifs
, gif_link
) {
272 /* If unused, return, no need to create a new interface */
273 if ((sc
->gif_if
.if_flags
& IFF_RUNNING
) == 0)
277 sc
= _MALLOC(sizeof(struct gif_softc
), M_DEVBUF
, M_WAITOK
);
279 log(LOG_ERR
, "gifattach: failed to allocate gif%d\n", ngif
);
283 bzero(sc
, sizeof(struct gif_softc
));
284 sc
->gif_if
.if_softc
= sc
;
285 sc
->gif_if
.if_name
= GIFNAME
;
286 sc
->gif_if
.if_unit
= ngif
;
288 sc
->encap_cookie4
= sc
->encap_cookie6
= NULL
;
290 sc
->encap_cookie4
= encap_attach_func(AF_INET
, -1,
291 gif_encapcheck
, &in_gif_protosw
, sc
);
292 if (sc
->encap_cookie4
== NULL
) {
293 printf("%s: unable to attach encap4\n", if_name(&sc
->gif_if
));
299 sc
->encap_cookie6
= encap_attach_func(AF_INET6
, -1,
300 gif_encapcheck
, (struct protosw
*)&in6_gif_protosw
, sc
);
301 if (sc
->encap_cookie6
== NULL
) {
302 if (sc
->encap_cookie4
) {
303 encap_detach(sc
->encap_cookie4
);
304 sc
->encap_cookie4
= NULL
;
306 printf("%s: unable to attach encap6\n", if_name(&sc
->gif_if
));
313 sc
->gif_if
.if_family
= APPLE_IF_FAM_GIF
;
314 sc
->gif_if
.if_mtu
= GIF_MTU
;
315 sc
->gif_if
.if_flags
= IFF_POINTOPOINT
| IFF_MULTICAST
;
317 /* turn off ingress filter */
318 sc
->gif_if
.if_flags
|= IFF_LINK2
;
320 sc
->gif_if
.if_demux
= gif_demux
;
321 sc
->gif_if
.if_ioctl
= gif_ioctl
;
322 sc
->gif_if
.if_output
= NULL
; /* pre_output returns error or EJUSTRETURN */
323 sc
->gif_if
.if_type
= IFT_GIF
;
324 sc
->gif_if
.if_add_proto
= gif_add_proto
;
325 sc
->gif_if
.if_del_proto
= gif_del_proto
;
326 dlil_if_attach(&sc
->gif_if
);
327 bpfattach(&sc
->gif_if
, DLT_NULL
, sizeof(u_int
));
328 TAILQ_INSERT_TAIL(&gifs
, sc
, gif_link
);
333 gif_encapcheck(m
, off
, proto
, arg
)
334 const struct mbuf
*m
;
340 struct gif_softc
*sc
;
342 sc
= (struct gif_softc
*)arg
;
346 if ((sc
->gif_if
.if_flags
& IFF_UP
) == 0)
349 /* no physical address */
350 if (!sc
->gif_psrc
|| !sc
->gif_pdst
)
366 /* LINTED const cast */
367 m_copydata((struct mbuf
*)m
, 0, sizeof(ip
), (caddr_t
)&ip
);
372 if (sc
->gif_psrc
->sa_family
!= AF_INET
||
373 sc
->gif_pdst
->sa_family
!= AF_INET
)
375 return gif_encapcheck4(m
, off
, proto
, arg
);
379 if (sc
->gif_psrc
->sa_family
!= AF_INET6
||
380 sc
->gif_pdst
->sa_family
!= AF_INET6
)
382 return gif_encapcheck6(m
, off
, proto
, arg
);
392 u_long protocol_family
,
394 const struct sockaddr
*dst
,
399 struct gif_softc
*sc
= (struct gif_softc
*)ifp
;
400 register struct mbuf
* m
= *m0
;
404 * gif may cause infinite recursion calls when misconfigured.
405 * We'll prevent this by introducing upper limit.
406 * XXX: this mechanism may introduce another problem about
407 * mutual exclusion of the variable CALLED, especially if we
410 if (++sc
->gif_called
> max_gif_nesting
) {
412 "gif_output: recursively called too many times(%d)\n",
414 m_freem(m
); /* free it here not in dlil_output*/
415 error
= EIO
; /* is there better errno? */
419 ifnet_touch_lastchange(ifp
);
420 m
->m_flags
&= ~(M_BCAST
|M_MCAST
);
421 if (!(ifp
->if_flags
& IFF_UP
) ||
422 sc
->gif_psrc
== NULL
|| sc
->gif_pdst
== NULL
) {
423 m_freem(m
); /* free it here not in dlil_output */
430 * We need to prepend the address family as
431 * a four byte field. Cons up a dummy header
432 * to pacify bpf. This is safe because bpf
433 * will only read from the mbuf (i.e., it won't
434 * try to free it or keep a pointer a to it).
437 u_int32_t protocol_family
= dst
->sa_family
;
441 m0
.m_data
= (char *)&protocol_family
;
446 ifp
->if_obytes
+= m
->m_pkthdr
.len
;
448 /* inner AF-specific encapsulation */
450 /* XXX should we check if our outer source is legal? */
452 /* dispatch to output logic based on outer AF */
453 switch (sc
->gif_psrc
->sa_family
) {
456 error
= in_gif_output(ifp
, dst
->sa_family
, m
, (struct rtentry
*)rt
);
461 error
= in6_gif_output(ifp
, dst
->sa_family
, m
, (struct rtentry
*)rt
);
470 sc
->gif_called
= 0; /* reset recursion counter */
472 /* the mbuf was freed either by in_gif_output or in here */
473 *m0
= NULL
; /* avoid getting dlil_output freeing it */
477 error
= EJUSTRETURN
; /* if no error, packet got sent already */
486 u_long protocol_family
,
496 if (m
->m_pkthdr
.rcvif
)
497 m
->m_pkthdr
.rcvif
= gifp
;
501 * We need to prepend the address family as
502 * a four byte field. Cons up a dummy header
503 * to pacify bpf. This is safe because bpf
504 * will only read from the mbuf (i.e., it won't
505 * try to free it or keep a pointer a to it).
508 u_int32_t protocol_family1
= protocol_family
;
512 m0
.m_data
= (char *)&protocol_family1
;
518 * Put the packet to the network layer input queue according to the
519 * specified address family.
520 * Note: older versions of gif_input directly called network layer
521 * input functions, e.g. ip6_input, here. We changed the policy to
522 * prevent too many recursive calls of such input functions, which
523 * might cause kernel panic. But the change may introduce another
524 * problem; if the input queue is full, packets are discarded.
525 * We believed it rarely occurs and changed the policy. If we find
526 * it occurs more times than we thought, we may change the policy
529 proto_input(protocol_family
, m
);
531 gifp
->if_ibytes
+= m
->m_pkthdr
.len
;
536 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
538 gif_ioctl(ifp
, cmd
, data
)
543 struct gif_softc
*sc
= (struct gif_softc
*)ifp
;
544 struct ifreq
*ifr
= (struct ifreq
*)data
;
546 struct sockaddr
*dst
, *src
;
550 struct gif_softc
*sc2
;
563 #ifdef SIOCSIFMTU /* xxx */
571 if (mtu
< GIF_MTU_MIN
|| mtu
> GIF_MTU_MAX
) {
577 #endif /* SIOCSIFMTU */
581 case SIOCSIFPHYADDR_IN6
:
583 case SIOCSLIFPHYADDR
:
587 src
= (struct sockaddr
*)
588 &(((struct in_aliasreq
*)data
)->ifra_addr
);
589 dst
= (struct sockaddr
*)
590 &(((struct in_aliasreq
*)data
)->ifra_dstaddr
);
594 case SIOCSIFPHYADDR_IN6
:
595 src
= (struct sockaddr
*)
596 &(((struct in6_aliasreq
*)data
)->ifra_addr
);
597 dst
= (struct sockaddr
*)
598 &(((struct in6_aliasreq
*)data
)->ifra_dstaddr
);
601 case SIOCSLIFPHYADDR
:
602 src
= (struct sockaddr
*)
603 &(((struct if_laddrreq
*)data
)->addr
);
604 dst
= (struct sockaddr
*)
605 &(((struct if_laddrreq
*)data
)->dstaddr
);
608 /* sa_family must be equal */
609 if (src
->sa_family
!= dst
->sa_family
)
612 /* validate sa_len */
613 switch (src
->sa_family
) {
616 if (src
->sa_len
!= sizeof(struct sockaddr_in
))
622 if (src
->sa_len
!= sizeof(struct sockaddr_in6
))
629 switch (dst
->sa_family
) {
632 if (dst
->sa_len
!= sizeof(struct sockaddr_in
))
638 if (dst
->sa_len
!= sizeof(struct sockaddr_in6
))
646 /* check sa_family looks sane for the cmd */
649 if (src
->sa_family
== AF_INET
)
653 case SIOCSIFPHYADDR_IN6
:
654 if (src
->sa_family
== AF_INET6
)
658 case SIOCSLIFPHYADDR
:
659 /* checks done in the above */
663 ifnet_head_lock_shared();
664 TAILQ_FOREACH(ifp2
, &ifnet_head
, if_link
) {
665 if (strcmp(ifp2
->if_name
, GIFNAME
) != 0)
667 sc2
= ifp2
->if_softc
;
670 if (!sc2
->gif_pdst
|| !sc2
->gif_psrc
)
672 if (sc2
->gif_pdst
->sa_family
!= dst
->sa_family
||
673 sc2
->gif_pdst
->sa_len
!= dst
->sa_len
||
674 sc2
->gif_psrc
->sa_family
!= src
->sa_family
||
675 sc2
->gif_psrc
->sa_len
!= src
->sa_len
)
678 /* can't configure same pair of address onto two gifs */
679 if (bcmp(sc2
->gif_pdst
, dst
, dst
->sa_len
) == 0 &&
680 bcmp(sc2
->gif_psrc
, src
, src
->sa_len
) == 0) {
681 error
= EADDRNOTAVAIL
;
687 /* can't configure multiple multi-dest interfaces */
688 #define multidest(x) \
689 (((struct sockaddr_in *)(x))->sin_addr.s_addr == INADDR_ANY)
691 #define multidest6(x) \
692 (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)(x))->sin6_addr))
694 if (dst
->sa_family
== AF_INET
&&
695 multidest(dst
) && multidest(sc2
->gif_pdst
)) {
696 error
= EADDRNOTAVAIL
;
701 if (dst
->sa_family
== AF_INET6
&&
702 multidest6(dst
) && multidest6(sc2
->gif_pdst
)) {
703 error
= EADDRNOTAVAIL
;
712 FREE((caddr_t
)sc
->gif_psrc
, M_IFADDR
);
713 sa
= (struct sockaddr
*)_MALLOC(src
->sa_len
, M_IFADDR
, M_WAITOK
);
714 bcopy((caddr_t
)src
, (caddr_t
)sa
, src
->sa_len
);
718 FREE((caddr_t
)sc
->gif_pdst
, M_IFADDR
);
719 sa
= (struct sockaddr
*)_MALLOC(dst
->sa_len
, M_IFADDR
, M_WAITOK
);
720 bcopy((caddr_t
)dst
, (caddr_t
)sa
, dst
->sa_len
);
723 ifp
->if_flags
|= IFF_RUNNING
;
726 if_up(ifp
); /* mark interface UP and send up RTM_IFINFO */
728 /* Make sure at least one unused device is still available */
736 #ifdef SIOCDIFPHYADDR
739 FREE((caddr_t
)sc
->gif_psrc
, M_IFADDR
);
743 FREE((caddr_t
)sc
->gif_pdst
, M_IFADDR
);
746 /* change the IFF_{UP, RUNNING} flag as well? */
750 case SIOCGIFPSRCADDR
:
752 case SIOCGIFPSRCADDR_IN6
:
754 if (sc
->gif_psrc
== NULL
) {
755 error
= EADDRNOTAVAIL
;
761 case SIOCGIFPSRCADDR
:
762 dst
= &ifr
->ifr_addr
;
763 size
= sizeof(ifr
->ifr_addr
);
767 case SIOCGIFPSRCADDR_IN6
:
768 dst
= (struct sockaddr
*)
769 &(((struct in6_ifreq
*)data
)->ifr_addr
);
770 size
= sizeof(((struct in6_ifreq
*)data
)->ifr_addr
);
774 error
= EADDRNOTAVAIL
;
777 if (src
->sa_len
> size
)
779 bcopy((caddr_t
)src
, (caddr_t
)dst
, src
->sa_len
);
782 case SIOCGIFPDSTADDR
:
784 case SIOCGIFPDSTADDR_IN6
:
786 if (sc
->gif_pdst
== NULL
) {
787 error
= EADDRNOTAVAIL
;
793 case SIOCGIFPDSTADDR
:
794 dst
= &ifr
->ifr_addr
;
795 size
= sizeof(ifr
->ifr_addr
);
799 case SIOCGIFPDSTADDR_IN6
:
800 dst
= (struct sockaddr
*)
801 &(((struct in6_ifreq
*)data
)->ifr_addr
);
802 size
= sizeof(((struct in6_ifreq
*)data
)->ifr_addr
);
806 error
= EADDRNOTAVAIL
;
809 if (src
->sa_len
> size
)
811 bcopy((caddr_t
)src
, (caddr_t
)dst
, src
->sa_len
);
814 case SIOCGLIFPHYADDR
:
815 if (sc
->gif_psrc
== NULL
|| sc
->gif_pdst
== NULL
) {
816 error
= EADDRNOTAVAIL
;
822 dst
= (struct sockaddr
*)
823 &(((struct if_laddrreq
*)data
)->addr
);
824 size
= sizeof(((struct if_laddrreq
*)data
)->addr
);
825 if (src
->sa_len
> size
)
827 bcopy((caddr_t
)src
, (caddr_t
)dst
, src
->sa_len
);
831 dst
= (struct sockaddr
*)
832 &(((struct if_laddrreq
*)data
)->dstaddr
);
833 size
= sizeof(((struct if_laddrreq
*)data
)->dstaddr
);
834 if (src
->sa_len
> size
)
836 bcopy((caddr_t
)src
, (caddr_t
)dst
, src
->sa_len
);
840 /* if_ioctl() takes care of it */
852 /* This function is not used in our stack */
854 gif_delete_tunnel(sc
)
855 struct gif_softc
*sc
;
857 /* XXX: NetBSD protects this function with splsoftnet() */
860 FREE((caddr_t
)sc
->gif_psrc
, M_IFADDR
);
864 FREE((caddr_t
)sc
->gif_pdst
, M_IFADDR
);
867 /* change the IFF_UP flag as well? */