Home | History | Annotate | Line # | Download | only in net
if_gif.c revision 1.132
      1 /*	$NetBSD: if_gif.c,v 1.132 2017/11/16 03:07:18 ozaki-r Exp $	*/
      2 /*	$KAME: if_gif.c,v 1.76 2001/08/20 02:01:02 kjc Exp $	*/
      3 
      4 /*
      5  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     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.
     19  *
     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
     30  * SUCH DAMAGE.
     31  */
     32 
     33 #include <sys/cdefs.h>
     34 __KERNEL_RCSID(0, "$NetBSD: if_gif.c,v 1.132 2017/11/16 03:07:18 ozaki-r Exp $");
     35 
     36 #ifdef _KERNEL_OPT
     37 #include "opt_inet.h"
     38 #include "opt_net_mpsafe.h"
     39 #endif
     40 
     41 #include <sys/param.h>
     42 #include <sys/systm.h>
     43 #include <sys/kernel.h>
     44 #include <sys/mbuf.h>
     45 #include <sys/socket.h>
     46 #include <sys/sockio.h>
     47 #include <sys/errno.h>
     48 #include <sys/ioctl.h>
     49 #include <sys/time.h>
     50 #include <sys/socketvar.h>
     51 #include <sys/syslog.h>
     52 #include <sys/proc.h>
     53 #include <sys/cpu.h>
     54 #include <sys/intr.h>
     55 #include <sys/kmem.h>
     56 #include <sys/sysctl.h>
     57 #include <sys/xcall.h>
     58 #include <sys/device.h>
     59 #include <sys/module.h>
     60 
     61 #include <net/if.h>
     62 #include <net/if_types.h>
     63 #include <net/netisr.h>
     64 #include <net/route.h>
     65 #include <net/bpf.h>
     66 
     67 #include <netinet/in.h>
     68 #include <netinet/in_systm.h>
     69 #include <netinet/ip.h>
     70 #ifdef	INET
     71 #include <netinet/in_var.h>
     72 #endif	/* INET */
     73 #include <netinet/in_gif.h>
     74 
     75 #ifdef INET6
     76 #ifndef INET
     77 #include <netinet/in.h>
     78 #endif
     79 #include <netinet6/in6_var.h>
     80 #include <netinet/ip6.h>
     81 #include <netinet6/ip6_var.h>
     82 #include <netinet6/in6_gif.h>
     83 #endif /* INET6 */
     84 
     85 #include <netinet/ip_encap.h>
     86 #include <net/if_gif.h>
     87 
     88 #include <net/net_osdep.h>
     89 
     90 #include "ioconf.h"
     91 
     92 #ifdef NET_MPSAFE
     93 #define GIF_MPSAFE	1
     94 #endif
     95 
     96 /*
     97  * gif global variable definitions
     98  */
     99 LIST_HEAD(gif_sclist, gif_softc);
    100 static struct {
    101 	struct gif_sclist list;
    102 	kmutex_t lock;
    103 } gif_softcs __cacheline_aligned;
    104 
    105 static void	gif_ro_init_pc(void *, void *, struct cpu_info *);
    106 static void	gif_ro_fini_pc(void *, void *, struct cpu_info *);
    107 
    108 static int	gifattach0(struct gif_softc *);
    109 static int	gif_output(struct ifnet *, struct mbuf *,
    110 			   const struct sockaddr *, const struct rtentry *);
    111 static void	gif_start(struct ifnet *);
    112 static int	gif_transmit(struct ifnet *, struct mbuf *);
    113 static int	gif_ioctl(struct ifnet *, u_long, void *);
    114 static int	gif_set_tunnel(struct ifnet *, struct sockaddr *,
    115 			       struct sockaddr *);
    116 static void	gif_delete_tunnel(struct ifnet *);
    117 
    118 static int	gif_clone_create(struct if_clone *, int);
    119 static int	gif_clone_destroy(struct ifnet *);
    120 static int	gif_check_nesting(struct ifnet *, struct mbuf *);
    121 
    122 static int	gif_encap_attach(struct gif_softc *);
    123 static int	gif_encap_detach(struct gif_softc *);
    124 static void	gif_encap_pause(struct gif_softc *);
    125 
    126 static struct if_clone gif_cloner =
    127     IF_CLONE_INITIALIZER("gif", gif_clone_create, gif_clone_destroy);
    128 
    129 #ifndef MAX_GIF_NEST
    130 /*
    131  * This macro controls the upper limitation on nesting of gif tunnels.
    132  * Since, setting a large value to this macro with a careless configuration
    133  * may introduce system crash, we don't allow any nestings by default.
    134  * If you need to configure nested gif tunnels, you can define this macro
    135  * in your kernel configuration file.  However, if you do so, please be
    136  * careful to configure the tunnels so that it won't make a loop.
    137  */
    138 #define MAX_GIF_NEST 1
    139 #endif
    140 static int max_gif_nesting = MAX_GIF_NEST;
    141 
    142 static struct sysctllog *gif_sysctl;
    143 
    144 static void
    145 gif_sysctl_setup(void)
    146 {
    147 	gif_sysctl = NULL;
    148 
    149 #ifdef INET
    150 	/*
    151 	 * Previously create "net.inet.ip" entry to avoid sysctl_createv error.
    152 	 */
    153 	sysctl_createv(NULL, 0, NULL, NULL,
    154 		       CTLFLAG_PERMANENT,
    155 		       CTLTYPE_NODE, "inet",
    156 		       SYSCTL_DESCR("PF_INET related settings"),
    157 		       NULL, 0, NULL, 0,
    158 		       CTL_NET, PF_INET, CTL_EOL);
    159 	sysctl_createv(NULL, 0, NULL, NULL,
    160 		       CTLFLAG_PERMANENT,
    161 		       CTLTYPE_NODE, "ip",
    162 		       SYSCTL_DESCR("IPv4 related settings"),
    163 		       NULL, 0, NULL, 0,
    164 		       CTL_NET, PF_INET, IPPROTO_IP, CTL_EOL);
    165 
    166 	sysctl_createv(&gif_sysctl, 0, NULL, NULL,
    167 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
    168 		       CTLTYPE_INT, "gifttl",
    169 		       SYSCTL_DESCR("Default TTL for a gif tunnel datagram"),
    170 		       NULL, 0, &ip_gif_ttl, 0,
    171 		       CTL_NET, PF_INET, IPPROTO_IP,
    172 		       IPCTL_GIF_TTL, CTL_EOL);
    173 #endif
    174 #ifdef INET6
    175 	/*
    176 	 * Previously create "net.inet6.ip6" entry to avoid sysctl_createv error.
    177 	 */
    178 	sysctl_createv(NULL, 0, NULL, NULL,
    179 		       CTLFLAG_PERMANENT,
    180 		       CTLTYPE_NODE, "inet6",
    181 		       SYSCTL_DESCR("PF_INET6 related settings"),
    182 		       NULL, 0, NULL, 0,
    183 		       CTL_NET, PF_INET6, CTL_EOL);
    184 	sysctl_createv(NULL, 0, NULL, NULL,
    185 		       CTLFLAG_PERMANENT,
    186 		       CTLTYPE_NODE, "ip6",
    187 		       SYSCTL_DESCR("IPv6 related settings"),
    188 		       NULL, 0, NULL, 0,
    189 		       CTL_NET, PF_INET6, IPPROTO_IPV6, CTL_EOL);
    190 
    191 	sysctl_createv(&gif_sysctl, 0, NULL, NULL,
    192 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
    193 		       CTLTYPE_INT, "gifhlim",
    194 		       SYSCTL_DESCR("Default hop limit for a gif tunnel datagram"),
    195 		       NULL, 0, &ip6_gif_hlim, 0,
    196 		       CTL_NET, PF_INET6, IPPROTO_IPV6,
    197 		       IPV6CTL_GIF_HLIM, CTL_EOL);
    198 #endif
    199 }
    200 
    201 /* ARGSUSED */
    202 void
    203 gifattach(int count)
    204 {
    205 	/*
    206 	 * Nothing to do here, initialization is handled by the
    207 	 * module initialization code in gifinit() below).
    208 	 */
    209 }
    210 
    211 static void
    212 gifinit(void)
    213 {
    214 
    215 	mutex_init(&gif_softcs.lock, MUTEX_DEFAULT, IPL_NONE);
    216 	LIST_INIT(&gif_softcs.list);
    217 	if_clone_attach(&gif_cloner);
    218 
    219 	gif_sysctl_setup();
    220 }
    221 
    222 static int
    223 gifdetach(void)
    224 {
    225 	int error = 0;
    226 
    227 	mutex_enter(&gif_softcs.lock);
    228 	if (!LIST_EMPTY(&gif_softcs.list)) {
    229 		mutex_exit(&gif_softcs.lock);
    230 		error = EBUSY;
    231 	}
    232 
    233 	if (error == 0) {
    234 		if_clone_detach(&gif_cloner);
    235 		sysctl_teardown(&gif_sysctl);
    236 	}
    237 
    238 	return error;
    239 }
    240 
    241 static int
    242 gif_clone_create(struct if_clone *ifc, int unit)
    243 {
    244 	struct gif_softc *sc;
    245 	int rv;
    246 
    247 	sc = kmem_zalloc(sizeof(struct gif_softc), KM_SLEEP);
    248 
    249 	if_initname(&sc->gif_if, ifc->ifc_name, unit);
    250 
    251 	rv = gifattach0(sc);
    252 	if (rv != 0) {
    253 		kmem_free(sc, sizeof(struct gif_softc));
    254 		return rv;
    255 	}
    256 
    257 	sc->gif_ro_percpu = percpu_alloc(sizeof(struct gif_ro));
    258 	percpu_foreach(sc->gif_ro_percpu, gif_ro_init_pc, NULL);
    259 
    260 	mutex_enter(&gif_softcs.lock);
    261 	LIST_INSERT_HEAD(&gif_softcs.list, sc, gif_list);
    262 	mutex_exit(&gif_softcs.lock);
    263 	return 0;
    264 }
    265 
    266 static int
    267 gifattach0(struct gif_softc *sc)
    268 {
    269 	int rv;
    270 
    271 	sc->encap_cookie4 = sc->encap_cookie6 = NULL;
    272 
    273 	sc->gif_if.if_addrlen = 0;
    274 	sc->gif_if.if_mtu    = GIF_MTU;
    275 	sc->gif_if.if_flags  = IFF_POINTOPOINT | IFF_MULTICAST;
    276 	sc->gif_if.if_extflags  = IFEF_NO_LINK_STATE_CHANGE;
    277 #ifdef GIF_MPSAFE
    278 	sc->gif_if.if_extflags  |= IFEF_MPSAFE;
    279 #endif
    280 	sc->gif_if.if_ioctl  = gif_ioctl;
    281 	sc->gif_if.if_output = gif_output;
    282 	sc->gif_if.if_start = gif_start;
    283 	sc->gif_if.if_transmit = gif_transmit;
    284 	sc->gif_if.if_type   = IFT_GIF;
    285 	sc->gif_if.if_dlt    = DLT_NULL;
    286 	sc->gif_if.if_softc  = sc;
    287 	IFQ_SET_READY(&sc->gif_if.if_snd);
    288 	rv = if_initialize(&sc->gif_if);
    289 	if (rv != 0)
    290 		return rv;
    291 
    292 	if_register(&sc->gif_if);
    293 	if_alloc_sadl(&sc->gif_if);
    294 	bpf_attach(&sc->gif_if, DLT_NULL, sizeof(u_int));
    295 	return 0;
    296 }
    297 
    298 static void
    299 gif_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
    300 {
    301 	struct gif_ro *gro = p;
    302 
    303 	mutex_init(&gro->gr_lock, MUTEX_DEFAULT, IPL_NONE);
    304 }
    305 
    306 static void
    307 gif_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
    308 {
    309 	struct gif_ro *gro = p;
    310 
    311 	rtcache_free(&gro->gr_ro);
    312 
    313 	mutex_destroy(&gro->gr_lock);
    314 }
    315 
    316 void
    317 gif_rtcache_free_pc(void *p, void *arg __unused, struct cpu_info *ci __unused)
    318 {
    319 	struct gif_ro *gro = p;
    320 
    321 	rtcache_free(&gro->gr_ro);
    322 }
    323 
    324 static int
    325 gif_clone_destroy(struct ifnet *ifp)
    326 {
    327 	struct gif_softc *sc = (void *) ifp;
    328 
    329 	LIST_REMOVE(sc, gif_list);
    330 
    331 	gif_delete_tunnel(&sc->gif_if);
    332 	bpf_detach(ifp);
    333 	if_detach(ifp);
    334 
    335 	percpu_foreach(sc->gif_ro_percpu, gif_ro_fini_pc, NULL);
    336 	percpu_free(sc->gif_ro_percpu, sizeof(struct gif_ro));
    337 
    338 	kmem_free(sc, sizeof(struct gif_softc));
    339 
    340 	return 0;
    341 }
    342 
    343 #ifdef GIF_ENCAPCHECK
    344 int
    345 gif_encapcheck(struct mbuf *m, int off, int proto, void *arg)
    346 {
    347 	struct ip ip;
    348 	struct gif_softc *sc;
    349 
    350 	sc = arg;
    351 	if (sc == NULL)
    352 		return 0;
    353 
    354 	if ((sc->gif_if.if_flags & (IFF_UP|IFF_RUNNING))
    355 	    != (IFF_UP|IFF_RUNNING))
    356 		return 0;
    357 
    358 	/* no physical address */
    359 	if (!sc->gif_psrc || !sc->gif_pdst)
    360 		return 0;
    361 
    362 	switch (proto) {
    363 #ifdef INET
    364 	case IPPROTO_IPV4:
    365 		break;
    366 #endif
    367 #ifdef INET6
    368 	case IPPROTO_IPV6:
    369 		break;
    370 #endif
    371 	default:
    372 		return 0;
    373 	}
    374 
    375 	/* Bail on short packets */
    376 	KASSERT(m->m_flags & M_PKTHDR);
    377 	if (m->m_pkthdr.len < sizeof(ip))
    378 		return 0;
    379 
    380 	m_copydata(m, 0, sizeof(ip), &ip);
    381 
    382 	switch (ip.ip_v) {
    383 #ifdef INET
    384 	case 4:
    385 		if (sc->gif_psrc->sa_family != AF_INET ||
    386 		    sc->gif_pdst->sa_family != AF_INET)
    387 			return 0;
    388 		return gif_encapcheck4(m, off, proto, arg);
    389 #endif
    390 #ifdef INET6
    391 	case 6:
    392 		if (m->m_pkthdr.len < sizeof(struct ip6_hdr))
    393 			return 0;
    394 		if (sc->gif_psrc->sa_family != AF_INET6 ||
    395 		    sc->gif_pdst->sa_family != AF_INET6)
    396 			return 0;
    397 		return gif_encapcheck6(m, off, proto, arg);
    398 #endif
    399 	default:
    400 		return 0;
    401 	}
    402 }
    403 #endif
    404 
    405 /*
    406  * gif may cause infinite recursion calls when misconfigured.
    407  * We'll prevent this by introducing upper limit.
    408  */
    409 static int
    410 gif_check_nesting(struct ifnet *ifp, struct mbuf *m)
    411 {
    412 	struct m_tag *mtag;
    413 	int *count;
    414 
    415 	mtag = m_tag_find(m, PACKET_TAG_TUNNEL_INFO, NULL);
    416 	if (mtag != NULL) {
    417 		count = (int *)(mtag + 1);
    418 		if (++(*count) > max_gif_nesting) {
    419 			log(LOG_NOTICE,
    420 			    "%s: recursively called too many times(%d)\n",
    421 			    if_name(ifp),
    422 			    *count);
    423 			return EIO;
    424 		}
    425 	} else {
    426 		mtag = m_tag_get(PACKET_TAG_TUNNEL_INFO, sizeof(*count),
    427 		    M_NOWAIT);
    428 		if (mtag != NULL) {
    429 			m_tag_prepend(m, mtag);
    430 			count = (int *)(mtag + 1);
    431 			*count = 0;
    432 		} else {
    433 			log(LOG_DEBUG,
    434 			    "%s: m_tag_get() failed, recursion calls are not prevented.\n",
    435 			    if_name(ifp));
    436 		}
    437 	}
    438 
    439 	return 0;
    440 }
    441 
    442 static int
    443 gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
    444     const struct rtentry *rt)
    445 {
    446 	struct gif_softc *sc = ifp->if_softc;
    447 	int error = 0;
    448 
    449 	IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family);
    450 
    451 	if ((error = gif_check_nesting(ifp, m)) != 0) {
    452 		m_free(m);
    453 		goto end;
    454 	}
    455 
    456 	m->m_flags &= ~(M_BCAST|M_MCAST);
    457 	if (((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) ||
    458 	    sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
    459 		m_freem(m);
    460 		error = ENETDOWN;
    461 		goto end;
    462 	}
    463 
    464 	/* XXX should we check if our outer source is legal? */
    465 
    466 	/* use DLT_NULL encapsulation here to pass inner af type */
    467 	M_PREPEND(m, sizeof(int), M_DONTWAIT);
    468 	if (!m) {
    469 		error = ENOBUFS;
    470 		goto end;
    471 	}
    472 	*mtod(m, int *) = dst->sa_family;
    473 
    474 	/* Clear checksum-offload flags. */
    475 	m->m_pkthdr.csum_flags = 0;
    476 	m->m_pkthdr.csum_data = 0;
    477 
    478 	error = if_transmit_lock(ifp, m);
    479   end:
    480 	if (error)
    481 		ifp->if_oerrors++;
    482 	return error;
    483 }
    484 
    485 static void
    486 gif_start(struct ifnet *ifp)
    487 {
    488 	struct gif_softc *sc;
    489 	struct mbuf *m;
    490 	int family;
    491 	int len;
    492 	int error;
    493 
    494 	sc = ifp->if_softc;
    495 
    496 	/* output processing */
    497 	while (1) {
    498 		IFQ_DEQUEUE(&sc->gif_if.if_snd, m);
    499 		if (m == NULL)
    500 			break;
    501 
    502 		/* grab and chop off inner af type */
    503 		if (sizeof(int) > m->m_len) {
    504 			m = m_pullup(m, sizeof(int));
    505 			if (!m) {
    506 				ifp->if_oerrors++;
    507 				continue;
    508 			}
    509 		}
    510 		family = *mtod(m, int *);
    511 		bpf_mtap(ifp, m);
    512 		m_adj(m, sizeof(int));
    513 
    514 		len = m->m_pkthdr.len;
    515 
    516 		/* dispatch to output logic based on outer AF */
    517 		switch (sc->gif_psrc->sa_family) {
    518 #ifdef INET
    519 		case AF_INET:
    520 			/* XXX
    521 			 * To add mutex_enter(softnet_lock) or
    522 			 * KASSERT(mutex_owned(softnet_lock)) here, we shold
    523 			 * coordinate softnet_lock between in6_if_up() and
    524 			 * in6_purgeif().
    525 			 */
    526 			error = in_gif_output(ifp, family, m);
    527 			break;
    528 #endif
    529 #ifdef INET6
    530 		case AF_INET6:
    531 			/* XXX
    532 			 * the same as in_gif_output()
    533 			 */
    534 			error = in6_gif_output(ifp, family, m);
    535 			break;
    536 #endif
    537 		default:
    538 			m_freem(m);
    539 			error = ENETDOWN;
    540 			break;
    541 		}
    542 
    543 		if (error)
    544 			ifp->if_oerrors++;
    545 		else {
    546 			ifp->if_opackets++;
    547 			ifp->if_obytes += len;
    548 		}
    549 	}
    550 }
    551 
    552 static int
    553 gif_transmit(struct ifnet *ifp, struct mbuf *m)
    554 {
    555 	struct gif_softc *sc;
    556 	int family;
    557 	int len;
    558 	int error;
    559 
    560 	sc = ifp->if_softc;
    561 
    562 	/* output processing */
    563 	if (m == NULL)
    564 		return EINVAL;
    565 
    566 	/* grab and chop off inner af type */
    567 	if (sizeof(int) > m->m_len) {
    568 		m = m_pullup(m, sizeof(int));
    569 		if (!m) {
    570 			ifp->if_oerrors++;
    571 			return ENOBUFS;
    572 		}
    573 	}
    574 	family = *mtod(m, int *);
    575 	bpf_mtap(ifp, m);
    576 	m_adj(m, sizeof(int));
    577 
    578 	len = m->m_pkthdr.len;
    579 
    580 	/* dispatch to output logic based on outer AF */
    581 	switch (sc->gif_psrc->sa_family) {
    582 #ifdef INET
    583 	case AF_INET:
    584 		/* XXX
    585 		 * To add mutex_enter(softnet_lock) or
    586 		 * KASSERT(mutex_owned(softnet_lock)) here, we shold
    587 		 * coordinate softnet_lock between in6_if_up() and
    588 		 * in6_purgeif().
    589 		 */
    590 		error = in_gif_output(ifp, family, m);
    591 		break;
    592 #endif
    593 #ifdef INET6
    594 	case AF_INET6:
    595 		/* XXX
    596 		 * the same as in_gif_output()
    597 		 */
    598 		error = in6_gif_output(ifp, family, m);
    599 		break;
    600 #endif
    601 	default:
    602 		m_freem(m);
    603 		error = ENETDOWN;
    604 		break;
    605 	}
    606 
    607 	if (error)
    608 		ifp->if_oerrors++;
    609 	else {
    610 		ifp->if_opackets++;
    611 		ifp->if_obytes += len;
    612 	}
    613 
    614 	return error;
    615 }
    616 
    617 void
    618 gif_input(struct mbuf *m, int af, struct ifnet *ifp)
    619 {
    620 	pktqueue_t *pktq;
    621 	size_t pktlen;
    622 
    623 	if (ifp == NULL) {
    624 		/* just in case */
    625 		m_freem(m);
    626 		return;
    627 	}
    628 
    629 	m_set_rcvif(m, ifp);
    630 	pktlen = m->m_pkthdr.len;
    631 
    632 	bpf_mtap_af(ifp, af, m);
    633 
    634 	/*
    635 	 * Put the packet to the network layer input queue according to the
    636 	 * specified address family.  Note: we avoid direct call to the
    637 	 * input function of the network layer in order to avoid recursion.
    638 	 * This may be revisited in the future.
    639 	 */
    640 	switch (af) {
    641 #ifdef INET
    642 	case AF_INET:
    643 		pktq = ip_pktq;
    644 		break;
    645 #endif
    646 #ifdef INET6
    647 	case AF_INET6:
    648 		pktq = ip6_pktq;
    649 		break;
    650 #endif
    651 	default:
    652 		m_freem(m);
    653 		return;
    654 	}
    655 
    656 #ifdef GIF_MPSAFE
    657 	const u_int h = curcpu()->ci_index;
    658 #else
    659 	const uint32_t h = pktq_rps_hash(m);
    660 #endif
    661 	if (__predict_true(pktq_enqueue(pktq, m, h))) {
    662 		ifp->if_ibytes += pktlen;
    663 		ifp->if_ipackets++;
    664 	} else {
    665 		m_freem(m);
    666 	}
    667 }
    668 
    669 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */
    670 static int
    671 gif_ioctl(struct ifnet *ifp, u_long cmd, void *data)
    672 {
    673 	struct gif_softc *sc  = ifp->if_softc;
    674 	struct ifreq     *ifr = (struct ifreq*)data;
    675 	struct ifaddr    *ifa = (struct ifaddr*)data;
    676 	int error = 0, size;
    677 	struct sockaddr *dst, *src;
    678 
    679 	switch (cmd) {
    680 	case SIOCINITIFADDR:
    681 		ifp->if_flags |= IFF_UP;
    682 		ifa->ifa_rtrequest = p2p_rtrequest;
    683 		break;
    684 
    685 	case SIOCADDMULTI:
    686 	case SIOCDELMULTI:
    687 		switch (ifr->ifr_addr.sa_family) {
    688 #ifdef INET
    689 		case AF_INET:	/* IP supports Multicast */
    690 			break;
    691 #endif /* INET */
    692 #ifdef INET6
    693 		case AF_INET6:	/* IP6 supports Multicast */
    694 			break;
    695 #endif /* INET6 */
    696 		default:  /* Other protocols doesn't support Multicast */
    697 			error = EAFNOSUPPORT;
    698 			break;
    699 		}
    700 		break;
    701 
    702 	case SIOCSIFMTU:
    703 		if (ifr->ifr_mtu < GIF_MTU_MIN || ifr->ifr_mtu > GIF_MTU_MAX)
    704 			return EINVAL;
    705 		else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET)
    706 			error = 0;
    707 		break;
    708 
    709 #ifdef INET
    710 	case SIOCSIFPHYADDR:
    711 #endif
    712 #ifdef INET6
    713 	case SIOCSIFPHYADDR_IN6:
    714 #endif /* INET6 */
    715 	case SIOCSLIFPHYADDR:
    716 		switch (cmd) {
    717 #ifdef INET
    718 		case SIOCSIFPHYADDR:
    719 			src = (struct sockaddr *)
    720 				&(((struct in_aliasreq *)data)->ifra_addr);
    721 			dst = (struct sockaddr *)
    722 				&(((struct in_aliasreq *)data)->ifra_dstaddr);
    723 			break;
    724 #endif
    725 #ifdef INET6
    726 		case SIOCSIFPHYADDR_IN6:
    727 			src = (struct sockaddr *)
    728 				&(((struct in6_aliasreq *)data)->ifra_addr);
    729 			dst = (struct sockaddr *)
    730 				&(((struct in6_aliasreq *)data)->ifra_dstaddr);
    731 			break;
    732 #endif
    733 		case SIOCSLIFPHYADDR:
    734 			src = (struct sockaddr *)
    735 				&(((struct if_laddrreq *)data)->addr);
    736 			dst = (struct sockaddr *)
    737 				&(((struct if_laddrreq *)data)->dstaddr);
    738 			break;
    739 		default:
    740 			return EINVAL;
    741 		}
    742 
    743 		/* sa_family must be equal */
    744 		if (src->sa_family != dst->sa_family)
    745 			return EINVAL;
    746 
    747 		/* validate sa_len */
    748 		switch (src->sa_family) {
    749 #ifdef INET
    750 		case AF_INET:
    751 			if (src->sa_len != sizeof(struct sockaddr_in))
    752 				return EINVAL;
    753 			break;
    754 #endif
    755 #ifdef INET6
    756 		case AF_INET6:
    757 			if (src->sa_len != sizeof(struct sockaddr_in6))
    758 				return EINVAL;
    759 			break;
    760 #endif
    761 		default:
    762 			return EAFNOSUPPORT;
    763 		}
    764 		switch (dst->sa_family) {
    765 #ifdef INET
    766 		case AF_INET:
    767 			if (dst->sa_len != sizeof(struct sockaddr_in))
    768 				return EINVAL;
    769 			break;
    770 #endif
    771 #ifdef INET6
    772 		case AF_INET6:
    773 			if (dst->sa_len != sizeof(struct sockaddr_in6))
    774 				return EINVAL;
    775 			break;
    776 #endif
    777 		default:
    778 			return EAFNOSUPPORT;
    779 		}
    780 
    781 		/* check sa_family looks sane for the cmd */
    782 		switch (cmd) {
    783 		case SIOCSIFPHYADDR:
    784 			if (src->sa_family == AF_INET)
    785 				break;
    786 			return EAFNOSUPPORT;
    787 #ifdef INET6
    788 		case SIOCSIFPHYADDR_IN6:
    789 			if (src->sa_family == AF_INET6)
    790 				break;
    791 			return EAFNOSUPPORT;
    792 #endif /* INET6 */
    793 		case SIOCSLIFPHYADDR:
    794 			/* checks done in the above */
    795 			break;
    796 		}
    797 
    798 		error = gif_set_tunnel(&sc->gif_if, src, dst);
    799 		break;
    800 
    801 #ifdef SIOCDIFPHYADDR
    802 	case SIOCDIFPHYADDR:
    803 		gif_delete_tunnel(&sc->gif_if);
    804 		break;
    805 #endif
    806 
    807 	case SIOCGIFPSRCADDR:
    808 #ifdef INET6
    809 	case SIOCGIFPSRCADDR_IN6:
    810 #endif /* INET6 */
    811 		if (sc->gif_psrc == NULL) {
    812 			error = EADDRNOTAVAIL;
    813 			goto bad;
    814 		}
    815 		src = sc->gif_psrc;
    816 		switch (cmd) {
    817 #ifdef INET
    818 		case SIOCGIFPSRCADDR:
    819 			dst = &ifr->ifr_addr;
    820 			size = sizeof(ifr->ifr_addr);
    821 			break;
    822 #endif /* INET */
    823 #ifdef INET6
    824 		case SIOCGIFPSRCADDR_IN6:
    825 			dst = (struct sockaddr *)
    826 				&(((struct in6_ifreq *)data)->ifr_addr);
    827 			size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
    828 			break;
    829 #endif /* INET6 */
    830 		default:
    831 			error = EADDRNOTAVAIL;
    832 			goto bad;
    833 		}
    834 		if (src->sa_len > size)
    835 			return EINVAL;
    836 		memcpy(dst, src, src->sa_len);
    837 		break;
    838 
    839 	case SIOCGIFPDSTADDR:
    840 #ifdef INET6
    841 	case SIOCGIFPDSTADDR_IN6:
    842 #endif /* INET6 */
    843 		if (sc->gif_pdst == NULL) {
    844 			error = EADDRNOTAVAIL;
    845 			goto bad;
    846 		}
    847 		src = sc->gif_pdst;
    848 		switch (cmd) {
    849 #ifdef INET
    850 		case SIOCGIFPDSTADDR:
    851 			dst = &ifr->ifr_addr;
    852 			size = sizeof(ifr->ifr_addr);
    853 			break;
    854 #endif /* INET */
    855 #ifdef INET6
    856 		case SIOCGIFPDSTADDR_IN6:
    857 			dst = (struct sockaddr *)
    858 				&(((struct in6_ifreq *)data)->ifr_addr);
    859 			size = sizeof(((struct in6_ifreq *)data)->ifr_addr);
    860 			break;
    861 #endif /* INET6 */
    862 		default:
    863 			error = EADDRNOTAVAIL;
    864 			goto bad;
    865 		}
    866 		if (src->sa_len > size)
    867 			return EINVAL;
    868 		memcpy(dst, src, src->sa_len);
    869 		break;
    870 
    871 	case SIOCGLIFPHYADDR:
    872 		if (sc->gif_psrc == NULL || sc->gif_pdst == NULL) {
    873 			error = EADDRNOTAVAIL;
    874 			goto bad;
    875 		}
    876 
    877 		/* copy src */
    878 		src = sc->gif_psrc;
    879 		dst = (struct sockaddr *)
    880 			&(((struct if_laddrreq *)data)->addr);
    881 		size = sizeof(((struct if_laddrreq *)data)->addr);
    882 		if (src->sa_len > size)
    883 			return EINVAL;
    884 		memcpy(dst, src, src->sa_len);
    885 
    886 		/* copy dst */
    887 		src = sc->gif_pdst;
    888 		dst = (struct sockaddr *)
    889 			&(((struct if_laddrreq *)data)->dstaddr);
    890 		size = sizeof(((struct if_laddrreq *)data)->dstaddr);
    891 		if (src->sa_len > size)
    892 			return EINVAL;
    893 		memcpy(dst, src, src->sa_len);
    894 		break;
    895 
    896 	default:
    897 		return ifioctl_common(ifp, cmd, data);
    898 	}
    899  bad:
    900 	return error;
    901 }
    902 
    903 static int
    904 gif_encap_attach(struct gif_softc *sc)
    905 {
    906 	int error;
    907 
    908 	if (sc == NULL || sc->gif_psrc == NULL)
    909 		return EINVAL;
    910 
    911 	switch (sc->gif_psrc->sa_family) {
    912 #ifdef INET
    913 	case AF_INET:
    914 		error = in_gif_attach(sc);
    915 		break;
    916 #endif
    917 #ifdef INET6
    918 	case AF_INET6:
    919 		error = in6_gif_attach(sc);
    920 		break;
    921 #endif
    922 	default:
    923 		error = EINVAL;
    924 		break;
    925 	}
    926 
    927 	return error;
    928 }
    929 
    930 static int
    931 gif_encap_detach(struct gif_softc *sc)
    932 {
    933 	int error;
    934 
    935 	if (sc == NULL || sc->gif_psrc == NULL)
    936 		return EINVAL;
    937 
    938 	switch (sc->gif_psrc->sa_family) {
    939 #ifdef INET
    940 	case AF_INET:
    941 		error = in_gif_detach(sc);
    942 		break;
    943 #endif
    944 #ifdef INET6
    945 	case AF_INET6:
    946 		error = in6_gif_detach(sc);
    947 		break;
    948 #endif
    949 	default:
    950 		error = EINVAL;
    951 		break;
    952 	}
    953 
    954 	return error;
    955 }
    956 
    957 static void
    958 gif_encap_pause(struct gif_softc *sc)
    959 {
    960 	struct ifnet *ifp;
    961 	uint64_t where;
    962 
    963 	if (sc == NULL || sc->gif_psrc == NULL)
    964 		return;
    965 
    966 	ifp = &sc->gif_if;
    967 	if ((ifp->if_flags & IFF_RUNNING) == 0)
    968 		return;
    969 
    970 	switch (sc->gif_psrc->sa_family) {
    971 #ifdef INET
    972 	case AF_INET:
    973 		(void)in_gif_pause(sc);
    974 		break;
    975 #endif
    976 #ifdef INET6
    977 	case AF_INET6:
    978 		(void)in6_gif_pause(sc);
    979 		break;
    980 #endif
    981 	}
    982 
    983 	ifp->if_flags &= ~IFF_RUNNING;
    984 	/* membar_sync() is done in xc_broadcast(). */
    985 
    986 	/*
    987 	 * Wait for softint_execute()(ipintr() or ip6intr())
    988 	 * completion done by other CPUs which already run over if_flags
    989 	 * check in in_gif_input() or in6_gif_input().
    990 	 * Furthermore, wait for gif_output() completion too.
    991 	 */
    992 	where = xc_broadcast(0, (xcfunc_t)nullop, NULL, NULL);
    993 	xc_wait(where);
    994 }
    995 
    996 static int
    997 gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst)
    998 {
    999 	struct gif_softc *sc = ifp->if_softc;
   1000 	struct gif_softc *sc2;
   1001 	struct sockaddr *osrc, *odst;
   1002 	struct sockaddr *nsrc, *ndst;
   1003 	int error;
   1004 #ifndef GIF_MPSAFE
   1005 	int s;
   1006 
   1007 	s = splsoftnet();
   1008 #endif
   1009 	error = encap_lock_enter();
   1010 	if (error) {
   1011 #ifndef GIF_MPSAFE
   1012 		splx(s);
   1013 #endif
   1014 		return error;
   1015 	}
   1016 
   1017 	mutex_enter(&gif_softcs.lock);
   1018 	LIST_FOREACH(sc2, &gif_softcs.list, gif_list) {
   1019 		if (sc2 == sc)
   1020 			continue;
   1021 		if (!sc2->gif_pdst || !sc2->gif_psrc)
   1022 			continue;
   1023 		/* can't configure same pair of address onto two gifs */
   1024 		if (sockaddr_cmp(sc2->gif_pdst, dst) == 0 &&
   1025 		    sockaddr_cmp(sc2->gif_psrc, src) == 0) {
   1026 			/* continue to use the old configureation. */
   1027 			mutex_exit(&gif_softcs.lock);
   1028 			error =  EADDRNOTAVAIL;
   1029 			goto out;
   1030 		}
   1031 
   1032 		/* XXX both end must be valid? (I mean, not 0.0.0.0) */
   1033 	}
   1034 	mutex_exit(&gif_softcs.lock);
   1035 
   1036 	nsrc = sockaddr_dup(src, M_WAITOK);
   1037 	ndst = sockaddr_dup(dst, M_WAITOK);
   1038 
   1039 	gif_encap_pause(sc);
   1040 
   1041 	/* Firstly, clear old configurations. */
   1042 	/* XXX we can detach from both, but be polite just in case */
   1043 	if (sc->gif_psrc)
   1044 		(void)gif_encap_detach(sc);
   1045 
   1046 	/*
   1047 	 * Secondly, try to set new configurations.
   1048 	 */
   1049 	osrc = sc->gif_psrc;
   1050 	odst = sc->gif_pdst;
   1051 	sc->gif_psrc = nsrc;
   1052 	sc->gif_pdst = ndst;
   1053 	error = gif_encap_attach(sc);
   1054 	if (error && osrc != NULL && odst != NULL) {
   1055 		/*
   1056 		 * Thirdly, when error occured, rollback to old configurations,
   1057 		 * if last setting is valid.
   1058 		 */
   1059 		sc->gif_psrc = osrc;
   1060 		sc->gif_pdst = odst;
   1061 		osrc = nsrc; /* to free */
   1062 		odst = ndst; /* to free */
   1063 		error = gif_encap_attach(sc);
   1064 	}
   1065 	if (error) {
   1066 		/*
   1067 		 * Fourthly, even rollback failed or last setting is not valid,
   1068 		 * clear configurations.
   1069 		 */
   1070 		osrc = sc->gif_psrc; /* to free */
   1071 		odst = sc->gif_pdst; /* to free */
   1072 		sc->gif_psrc = NULL;
   1073 		sc->gif_pdst = NULL;
   1074 		sockaddr_free(nsrc);
   1075 		sockaddr_free(ndst);
   1076 	}
   1077 
   1078 	if (osrc)
   1079 		sockaddr_free(osrc);
   1080 	if (odst)
   1081 		sockaddr_free(odst);
   1082 
   1083 	if (sc->gif_psrc && sc->gif_pdst)
   1084 		ifp->if_flags |= IFF_RUNNING;
   1085 	else
   1086 		ifp->if_flags &= ~IFF_RUNNING;
   1087 
   1088  out:
   1089 	encap_lock_exit();
   1090 #ifndef GIF_MPSAFE
   1091 	splx(s);
   1092 #endif
   1093 	return error;
   1094 }
   1095 
   1096 static void
   1097 gif_delete_tunnel(struct ifnet *ifp)
   1098 {
   1099 	struct gif_softc *sc = ifp->if_softc;
   1100 	int error;
   1101 #ifndef GIF_MPSAFE
   1102 	int s;
   1103 
   1104 	s = splsoftnet();
   1105 #endif
   1106 	error = encap_lock_enter();
   1107 	if (error) {
   1108 #ifndef GIF_MPSAFE
   1109 		splx(s);
   1110 #endif
   1111 		return;
   1112 	}
   1113 
   1114 	gif_encap_pause(sc);
   1115 	if (sc->gif_psrc) {
   1116 		sockaddr_free(sc->gif_psrc);
   1117 		sc->gif_psrc = NULL;
   1118 	}
   1119 	if (sc->gif_pdst) {
   1120 		sockaddr_free(sc->gif_pdst);
   1121 		sc->gif_pdst = NULL;
   1122 	}
   1123 	/* it is safe to detach from both */
   1124 #ifdef INET
   1125 	(void)in_gif_detach(sc);
   1126 #endif
   1127 #ifdef INET6
   1128 	(void)in6_gif_detach(sc);
   1129 #endif
   1130 
   1131 	if (sc->gif_psrc && sc->gif_pdst)
   1132 		ifp->if_flags |= IFF_RUNNING;
   1133 	else
   1134 		ifp->if_flags &= ~IFF_RUNNING;
   1135 
   1136 	encap_lock_exit();
   1137 #ifndef GIF_MPSAFE
   1138 	splx(s);
   1139 #endif
   1140 }
   1141 
   1142 /*
   1143  * Module infrastructure
   1144  */
   1145 #include "if_module.h"
   1146 
   1147 IF_MODULE(MODULE_CLASS_DRIVER, gif, "")
   1148