2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
22 /* $KAME: if_gif.c,v 1.15 2000/02/22 14:01:46 itojun Exp $ */
25 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
26 * All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. Neither the name of the project nor the names of its contributors
37 * may be used to endorse or promote products derived from this software
38 * without specific prior written permission.
40 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
41 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
42 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
43 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
44 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
45 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
46 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
48 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
49 * 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 <kern/cpu_number.h>
73 #include <net/if_types.h>
74 #include <net/netisr.h>
75 #include <net/route.h>
79 #include <netinet/in.h>
80 #include <netinet/in_systm.h>
81 #include <netinet/in_var.h>
82 #include <netinet/ip.h>
83 #include <netinet/in_gif.h>
88 #include <netinet/in.h>
90 #include <netinet6/in6_var.h>
91 #include <netinet/ip6.h>
92 #include <netinet6/ip6_var.h>
93 #include <netinet6/in6_gif.h>
94 #include <netinet6/ip6protosw.h>
97 #include <netinet/ip_encap.h>
99 #include <net/if_gif.h>
102 #include "bpfilter.h"
104 #include <net/net_osdep.h>
108 void gifattach
__P((void *));
109 int gif_pre_output
__P((struct ifnet
*, register struct mbuf
**, struct sockaddr
*,
110 register struct rtentry
*, char *, char *, u_long
));
113 * gif global variable definitions
115 int ngif
= NGIF
; /* number of interfaces */
116 struct gif_softc
*gif
= 0;
117 static struct if_proto
*gif_array
[NGIF
];
118 static gif_count
= 0 ;
121 * This macro controls the upper limitation on nesting of gif tunnels.
122 * Since, setting a large value to this macro with a careless configuration
123 * may introduce system crash, we don't allow any nestings by default.
124 * If you need to configure nested gif tunnels, you can define this macro
125 * in your kernel configuration file. However, if you do so, please be
126 * careful to configure the tunnels so that it won't make a loop.
128 #define MAX_GIF_NEST 1
130 static int max_gif_nesting
= MAX_GIF_NEST
;
135 int gif_demux(ifp
, m
, frame_header
, proto
)
139 struct if_proto
**proto
;
145 int gif_framer(ifp
, m
, dest
, dest_linkaddr
, frame_type
)
148 struct sockaddr
*dest
;
159 int gif_add_if(struct ifnet
*ifp
)
167 int gif_del_if(struct ifnet
*ifp
)
173 int gif_add_proto(struct ddesc_head_str
*desc_head
, struct if_proto
*proto
, u_long dl_tag
)
177 for (i
=0; i
< gif_count
; i
++)
178 if (gif_array
[i
] == 0) {
179 gif_array
[gif_count
] = proto
;
183 if ((i
== gif_count
) && (gif_count
== NGIF
))
184 panic("gif_add_proto -- Too many attachments\n");
186 gif_array
[gif_count
++] = proto
;
192 int gif_del_proto(struct if_proto
*proto
, u_long dl_tag
)
196 for (i
=0; i
< gif_count
; i
++)
197 if (gif_array
[i
] == proto
) {
210 void gif_reg_if_mods()
212 struct dlil_ifmod_reg_str gif_ifmod
;
214 gif_ifmod
.add_if
= gif_add_if
;
215 gif_ifmod
.del_if
= gif_del_if
;
216 gif_ifmod
.add_proto
= gif_add_proto
;
217 gif_ifmod
.del_proto
= gif_del_proto
;
218 gif_ifmod
.ifmod_ioctl
= 0;
219 gif_ifmod
.shutdown
= gif_shutdown
;
221 if (dlil_reg_if_modules(APPLE_IF_FAM_GIF
, &gif_ifmod
))
222 panic("Couldn't register gif modules\n");
226 u_long
gif_attach_inet(struct ifnet
*ifp
)
228 struct dlil_proto_reg_str reg
;
229 struct dlil_demux_desc desc
;
235 for (i
=0; i
< gif_count
; i
++) {
236 if (gif_array
[i
] && (gif_array
[i
]->ifp
== ifp
) &&
237 (gif_array
[i
]->protocol_family
== PF_INET
)) {
239 kprintf("gif_attach for %s%d found dl_tag=%d\n",
240 ifp
->if_name
, ifp
->if_unit
, gif_array
[i
]->dl_tag
);
242 return gif_array
[i
]->dl_tag
;
247 TAILQ_INIT(®
.demux_desc_head
);
248 desc
.type
= DLIL_DESC_RAW
;
249 desc
.variants
.bitmask
.proto_id_length
= 0;
250 desc
.variants
.bitmask
.proto_id
= 0;
251 desc
.variants
.bitmask
.proto_id_mask
= 0;
252 desc
.native_type
= (char *) &native
;
253 TAILQ_INSERT_TAIL(®
.demux_desc_head
, &desc
, next
);
254 reg
.interface_family
= ifp
->if_family
;
255 reg
.unit_number
= ifp
->if_unit
;
256 reg
.input
= gif_input
;
257 reg
.pre_output
= gif_pre_output
;
260 reg
.ioctl
= gif_ioctl
;
261 reg
.default_proto
= 0;
262 reg
.protocol_family
= PF_INET
;
264 stat
= dlil_attach_protocol(®
, &dl_tag
);
266 panic("gif_attach_inet can't attach interface\n");
276 register struct gif_softc
*sc
;
279 gif_reg_if_mods(); /* DLIL modules */
281 gif
= sc
= _MALLOC (ngif
* sizeof(struct gif_softc
), M_DEVBUF
, M_WAITOK
);
282 bzero(sc
, ngif
* sizeof(struct gif_softc
));
283 for (i
= 0; i
< ngif
; sc
++, i
++) {
284 sc
->gif_if
.if_name
= "gif";
285 sc
->gif_if
.if_unit
= i
;
286 sc
->gif_if
.if_family
= APPLE_IF_FAM_GIF
;
287 sc
->gif_if
.if_mtu
= GIF_MTU
;
288 sc
->gif_if
.if_flags
= IFF_POINTOPOINT
| IFF_MULTICAST
;
289 sc
->gif_if
.if_ioctl
= gif_ioctl
;
290 sc
->gif_if
.if_output
= NULL
;
291 sc
->gif_if
.if_type
= IFT_GIF
;
292 dlil_if_attach(&sc
->gif_if
);
294 kprintf("gifattach: Attaching gif%d sc=%x gif_if=%x\n", i
, sc
, &sc
->gif_if
);
298 bpfattach(&sc
->gif_if
, DLT_NULL
, sizeof(u_int
));
300 bpfattach(&sc
->gif_if
.if_bpf
, &sc
->gif_if
, DLT_NULL
, sizeof(u_int
));
307 PSEUDO_SET(gifattach
, if_gif
);
311 gif_pre_output(ifp
, m0
, dst
, rt
, frame
, address
, dl_tag
)
314 struct sockaddr
*dst
;
315 struct rtentry
*rt
; /* added in net2 */
320 register struct gif_softc
*sc
= (struct gif_softc
*)ifp
;
321 register struct mbuf
* m
= *m0
;
323 static int called
= 0; /* XXX: MUTEX */
326 * gif may cause infinite recursion calls when misconfigured.
327 * We'll prevent this by introducing upper limit.
328 * XXX: this mechanism may introduce another problem about
329 * mutual exclusion of the variable CALLED, especially if we
332 if (++called
> max_gif_nesting
) {
334 "gif_output: recursively called too many times(%d)\n",
337 error
= EIO
; /* is there better errno? */
341 getmicrotime(&ifp
->if_lastchange
);
342 m
->m_flags
&= ~(M_BCAST
|M_MCAST
);
343 if (!(ifp
->if_flags
& IFF_UP
) ||
345 sc
->gif_flags
& GIFF_INUSE
||
347 sc
->gif_psrc
== NULL
|| sc
->gif_pdst
== NULL
) {
350 printf("gif_output: packed discarded ENETDOWN\n");
357 * We need to prepend the address family as
358 * a four byte field. Cons up a dummy header
359 * to pacify bpf. This is safe because bpf
360 * will only read from the mbuf (i.e., it won't
361 * try to free it or keep a pointer a to it).
364 u_int af
= dst
->sa_family
;
368 m0
.m_data
= (char *)&af
;
373 bpf_mtap(ifp
->if_bpf
, &m0
);
378 ifp
->if_obytes
+= m
->m_pkthdr
.len
;
381 sc
->gif_flags
|= GIFF_INUSE
;
384 switch (sc
->gif_psrc
->sa_family
) {
387 error
= in_gif_output(ifp
, dst
->sa_family
, m
, rt
);
389 printf("in_gif_output returned error=%d\n", error
);
394 error
= in6_gif_output(ifp
, dst
->sa_family
, m
, rt
);
396 printf("in6_gif_output returned error=%d\n", error
);
404 sc
->gif_flags
&= ~GIFF_INUSE
;
409 called
= 0; /* reset recursion counter */
410 if (error
) ifp
->if_oerrors
++;
415 gif_input(m
, af
, gifp
)
421 register struct ifqueue
*ifq
= 0;
429 if (m
->m_pkthdr
.rcvif
)
430 m
->m_pkthdr
.rcvif
= gifp
;
435 * We need to prepend the address family as
436 * a four byte field. Cons up a dummy header
437 * to pacify bpf. This is safe because bpf
438 * will only read from the mbuf (i.e., it won't
439 * try to free it or keep a pointer a to it).
446 m0
.m_data
= (char *)&af
;
451 bpf_mtap(gifp
->if_bpf
, &m0
);
454 #endif /*NBPFILTER > 0*/
457 * Put the packet to the network layer input queue according to the
458 * specified address family.
459 * Note: older versions of gif_input directly called network layer
460 * input functions, e.g. ip6_input, here. We changed the policy to
461 * prevent too many recursive calls of such input functions, which
462 * might cause kernel panic. But the change may introduce another
463 * problem; if the input queue is full, packets are discarded.
464 * We believed it rarely occurs and changed the policy. If we find
465 * it occurs more times than we thought, we may change the policy
488 IF_DROP(ifq
); /* update statistics */
494 /* we need schednetisr since the address family may change */
497 gifp
->if_ibytes
+= m
->m_pkthdr
.len
;
503 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
505 gif_ioctl(ifp
, cmd
, data
)
510 struct gif_softc
*sc
= (struct gif_softc
*)ifp
;
511 struct ifreq
*ifr
= (struct ifreq
*)data
;
513 struct sockaddr
*dst
, *src
;
515 struct gif_softc
*sc2
;
526 /* Called from if_addmulti() with data == NULL if __FreeBSD__ >= 3 */
527 #if !defined(__APPLE__)
528 switch (ifr
->ifr_addr
.sa_family
) {
530 case AF_INET
: /* IP supports Multicast */
534 case AF_INET6
: /* IP6 supports Multicast */
537 default: /* Other protocols doesn't support Multicast */
538 error
= EAFNOSUPPORT
;
541 #endif /*not FreeBSD3*/
544 #ifdef SIOCSIFMTU /* xxx */
552 mtu
= *(short *)ifr
->ifr_data
;
557 if (mtu
< GIF_MTU_MIN
|| mtu
> GIF_MTU_MAX
) {
564 #endif /* SIOCSIFMTU */
568 case SIOCSIFPHYADDR_IN6
:
570 /* can't configure same pair of address onto two gif */
571 src
= (struct sockaddr
*)
572 &(((struct in_aliasreq
*)data
)->ifra_addr
);
573 dst
= (struct sockaddr
*)
574 &(((struct in_aliasreq
*)data
)->ifra_dstaddr
);
575 for (i
= 0; i
< ngif
; i
++) {
579 if (!sc2
->gif_pdst
|| !sc2
->gif_psrc
)
581 if (sc2
->gif_pdst
->sa_family
== dst
->sa_family
&&
582 sc2
->gif_pdst
->sa_len
== dst
->sa_family
&&
583 bcmp(sc2
->gif_pdst
, dst
, dst
->sa_len
) == 0 &&
584 sc2
->gif_psrc
->sa_family
== src
->sa_family
&&
585 sc2
->gif_psrc
->sa_len
== src
->sa_family
&&
586 bcmp(sc2
->gif_psrc
, src
, src
->sa_len
) == 0) {
587 error
= EADDRNOTAVAIL
;
592 switch (ifr
->ifr_addr
.sa_family
) {
595 return in_gif_ioctl(ifp
, cmd
, data
);
599 return in6_gif_ioctl(ifp
, cmd
, data
);
608 case SIOCGIFPSRCADDR
:
610 case SIOCGIFPSRCADDR_IN6
:
612 if (sc
->gif_psrc
== NULL
) {
613 error
= EADDRNOTAVAIL
;
617 switch (sc
->gif_psrc
->sa_family
) {
620 dst
= &ifr
->ifr_addr
;
621 size
= sizeof(struct sockaddr_in
);
626 dst
= (struct sockaddr
*)
627 &(((struct in6_ifreq
*)data
)->ifr_addr
);
628 size
= sizeof(struct sockaddr_in6
);
632 error
= EADDRNOTAVAIL
;
635 bcopy((caddr_t
)src
, (caddr_t
)dst
, size
);
638 case SIOCGIFPDSTADDR
:
640 case SIOCGIFPDSTADDR_IN6
:
642 if (sc
->gif_pdst
== NULL
) {
643 error
= EADDRNOTAVAIL
;
647 switch (sc
->gif_pdst
->sa_family
) {
650 dst
= &ifr
->ifr_addr
;
651 size
= sizeof(struct sockaddr_in
);
656 dst
= (struct sockaddr
*)
657 &(((struct in6_ifreq
*)data
)->ifr_addr
);
658 size
= sizeof(struct sockaddr_in6
);
662 error
= EADDRNOTAVAIL
;
665 bcopy((caddr_t
)src
, (caddr_t
)dst
, size
);
669 if (sc
->gif_psrc
== NULL
)
671 switch (sc
->gif_psrc
->sa_family
) {
674 return in_gif_ioctl(ifp
, cmd
, data
);
678 return in6_gif_ioctl(ifp
, cmd
, data
);