1/*-
2 * Copyright (c) 1998 The NetBSD Foundation, Inc.
3 * Copyright (c) 2014 Andrey V. Elsukov <ae@FreeBSD.org>
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to The NetBSD Foundation
7 * by Heiko W.Rupp <hwr@pilhuhn.de>
8 *
9 * IPv6-over-GRE contributed by Gert Doering <gert@greenie.muc.de>
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 *
32 * $NetBSD: if_gre.c,v 1.49 2003/12/11 00:22:29 itojun Exp $
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD$");
37
38#include "opt_inet.h"
39#include "opt_inet6.h"
40
41#include <sys/param.h>
42#include <sys/jail.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/libkern.h>
46#include <sys/malloc.h>
47#include <sys/module.h>
48#include <sys/mbuf.h>
49#include <sys/priv.h>
50#include <sys/proc.h>
51#include <sys/protosw.h>
52#include <sys/rmlock.h>
53#include <sys/socket.h>
54#include <sys/sockio.h>
55#include <sys/sx.h>
56#include <sys/sysctl.h>
57#include <sys/syslog.h>
58#include <sys/systm.h>
59
60#include <net/ethernet.h>
61#include <net/if.h>
62#include <net/if_clone.h>
63#include <net/if_var.h>
64#include <net/if_types.h>
65#include <net/netisr.h>
66#include <net/vnet.h>
67#include <net/route.h>
68
69#include <netinet/in.h>
70#ifdef INET
71#include <netinet/in_systm.h>
72#include <netinet/in_var.h>
73#include <netinet/ip.h>
74#include <netinet/ip_var.h>
75#endif
76
77#ifdef INET6
78#include <netinet/ip6.h>
79#include <netinet6/in6_var.h>
80#include <netinet6/ip6_var.h>
81#include <netinet6/scope6_var.h>
82#endif
83
84#include <netinet/ip_encap.h>
85#include <net/bpf.h>
86#include <net/if_gre.h>
87
88#include <machine/in_cksum.h>
89
90#include <security/mac/mac_framework.h>
91#define	GREMTU			1500
92static const char grename[] = "gre";
93static MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
94static VNET_DEFINE(struct mtx, gre_mtx);
95#define	V_gre_mtx	VNET(gre_mtx)
96#define	GRE_LIST_LOCK_INIT(x)		mtx_init(&V_gre_mtx, "gre_mtx", NULL, \
97					    MTX_DEF)
98#define	GRE_LIST_LOCK_DESTROY(x)	mtx_destroy(&V_gre_mtx)
99#define	GRE_LIST_LOCK(x)		mtx_lock(&V_gre_mtx)
100#define	GRE_LIST_UNLOCK(x)		mtx_unlock(&V_gre_mtx)
101
102static VNET_DEFINE(LIST_HEAD(, gre_softc), gre_softc_list);
103#define	V_gre_softc_list	VNET(gre_softc_list)
104static struct sx gre_ioctl_sx;
105SX_SYSINIT(gre_ioctl_sx, &gre_ioctl_sx, "gre_ioctl");
106
107static int	gre_clone_create(struct if_clone *, int, caddr_t);
108static void	gre_clone_destroy(struct ifnet *);
109static VNET_DEFINE(struct if_clone *, gre_cloner);
110#define	V_gre_cloner	VNET(gre_cloner)
111
112static void	gre_qflush(struct ifnet *);
113static int	gre_transmit(struct ifnet *, struct mbuf *);
114static int	gre_ioctl(struct ifnet *, u_long, caddr_t);
115static int	gre_output(struct ifnet *, struct mbuf *,
116		    const struct sockaddr *, struct route *);
117
118static void	gre_updatehdr(struct gre_softc *);
119static int	gre_set_tunnel(struct ifnet *, struct sockaddr *,
120    struct sockaddr *);
121static void	gre_delete_tunnel(struct ifnet *);
122
123SYSCTL_DECL(_net_link);
124static SYSCTL_NODE(_net_link, IFT_TUNNEL, gre, CTLFLAG_RW, 0,
125    "Generic Routing Encapsulation");
126#ifndef MAX_GRE_NEST
127/*
128 * This macro controls the default upper limitation on nesting of gre tunnels.
129 * Since, setting a large value to this macro with a careless configuration
130 * may introduce system crash, we don't allow any nestings by default.
131 * If you need to configure nested gre tunnels, you can define this macro
132 * in your kernel configuration file.  However, if you do so, please be
133 * careful to configure the tunnels so that it won't make a loop.
134 */
135#define MAX_GRE_NEST 1
136#endif
137
138static VNET_DEFINE(int, max_gre_nesting) = MAX_GRE_NEST;
139#define	V_max_gre_nesting	VNET(max_gre_nesting)
140SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET,
141    &VNET_NAME(max_gre_nesting), 0, "Max nested tunnels");
142
143static void
144vnet_gre_init(const void *unused __unused)
145{
146	LIST_INIT(&V_gre_softc_list);
147	GRE_LIST_LOCK_INIT();
148	V_gre_cloner = if_clone_simple(grename, gre_clone_create,
149	    gre_clone_destroy, 0);
150}
151VNET_SYSINIT(vnet_gre_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
152    vnet_gre_init, NULL);
153
154static void
155vnet_gre_uninit(const void *unused __unused)
156{
157
158	if_clone_detach(V_gre_cloner);
159	GRE_LIST_LOCK_DESTROY();
160}
161VNET_SYSUNINIT(vnet_gre_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
162    vnet_gre_uninit, NULL);
163
164static int
165gre_clone_create(struct if_clone *ifc, int unit, caddr_t params)
166{
167	struct gre_softc *sc;
168
169	sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK | M_ZERO);
170	sc->gre_fibnum = curthread->td_proc->p_fibnum;
171	GRE2IFP(sc) = if_alloc(IFT_TUNNEL);
172	GRE_LOCK_INIT(sc);
173	GRE2IFP(sc)->if_softc = sc;
174	if_initname(GRE2IFP(sc), grename, unit);
175
176	GRE2IFP(sc)->if_mtu = sc->gre_mtu = GREMTU;
177	GRE2IFP(sc)->if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
178	GRE2IFP(sc)->if_output = gre_output;
179	GRE2IFP(sc)->if_ioctl = gre_ioctl;
180	GRE2IFP(sc)->if_transmit = gre_transmit;
181	GRE2IFP(sc)->if_qflush = gre_qflush;
182	GRE2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE;
183	GRE2IFP(sc)->if_capenable |= IFCAP_LINKSTATE;
184	if_attach(GRE2IFP(sc));
185	bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
186	GRE_LIST_LOCK();
187	LIST_INSERT_HEAD(&V_gre_softc_list, sc, gre_list);
188	GRE_LIST_UNLOCK();
189	return (0);
190}
191
192static void
193gre_clone_destroy(struct ifnet *ifp)
194{
195	struct gre_softc *sc;
196
197	sx_xlock(&gre_ioctl_sx);
198	sc = ifp->if_softc;
199	gre_delete_tunnel(ifp);
200	GRE_LIST_LOCK();
201	LIST_REMOVE(sc, gre_list);
202	GRE_LIST_UNLOCK();
203	bpfdetach(ifp);
204	if_detach(ifp);
205	ifp->if_softc = NULL;
206	sx_xunlock(&gre_ioctl_sx);
207
208	if_free(ifp);
209	GRE_LOCK_DESTROY(sc);
210	free(sc, M_GRE);
211}
212
213static int
214gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
215{
216	GRE_RLOCK_TRACKER;
217	struct ifreq *ifr = (struct ifreq *)data;
218	struct sockaddr *src, *dst;
219	struct gre_softc *sc;
220#ifdef INET
221	struct sockaddr_in *sin = NULL;
222#endif
223#ifdef INET6
224	struct sockaddr_in6 *sin6 = NULL;
225#endif
226	uint32_t opt;
227	int error;
228
229	switch (cmd) {
230	case SIOCSIFMTU:
231		 /* XXX: */
232		if (ifr->ifr_mtu < 576)
233			return (EINVAL);
234		break;
235	case SIOCSIFADDR:
236		ifp->if_flags |= IFF_UP;
237	case SIOCSIFFLAGS:
238	case SIOCADDMULTI:
239	case SIOCDELMULTI:
240		return (0);
241	case GRESADDRS:
242	case GRESADDRD:
243	case GREGADDRS:
244	case GREGADDRD:
245	case GRESPROTO:
246	case GREGPROTO:
247		return (EOPNOTSUPP);
248	}
249	src = dst = NULL;
250	sx_xlock(&gre_ioctl_sx);
251	sc = ifp->if_softc;
252	if (sc == NULL) {
253		error = ENXIO;
254		goto end;
255	}
256	error = 0;
257	switch (cmd) {
258	case SIOCSIFMTU:
259		GRE_WLOCK(sc);
260		sc->gre_mtu = ifr->ifr_mtu;
261		gre_updatehdr(sc);
262		GRE_WUNLOCK(sc);
263		goto end;
264	case SIOCSIFPHYADDR:
265#ifdef INET6
266	case SIOCSIFPHYADDR_IN6:
267#endif
268		error = EINVAL;
269		switch (cmd) {
270#ifdef INET
271		case SIOCSIFPHYADDR:
272			src = (struct sockaddr *)
273				&(((struct in_aliasreq *)data)->ifra_addr);
274			dst = (struct sockaddr *)
275				&(((struct in_aliasreq *)data)->ifra_dstaddr);
276			break;
277#endif
278#ifdef INET6
279		case SIOCSIFPHYADDR_IN6:
280			src = (struct sockaddr *)
281				&(((struct in6_aliasreq *)data)->ifra_addr);
282			dst = (struct sockaddr *)
283				&(((struct in6_aliasreq *)data)->ifra_dstaddr);
284			break;
285#endif
286		default:
287			error = EAFNOSUPPORT;
288			goto end;
289		}
290		/* sa_family must be equal */
291		if (src->sa_family != dst->sa_family ||
292		    src->sa_len != dst->sa_len)
293			goto end;
294
295		/* validate sa_len */
296		switch (src->sa_family) {
297#ifdef INET
298		case AF_INET:
299			if (src->sa_len != sizeof(struct sockaddr_in))
300				goto end;
301			break;
302#endif
303#ifdef INET6
304		case AF_INET6:
305			if (src->sa_len != sizeof(struct sockaddr_in6))
306				goto end;
307			break;
308#endif
309		default:
310			error = EAFNOSUPPORT;
311			goto end;
312		}
313		/* check sa_family looks sane for the cmd */
314		error = EAFNOSUPPORT;
315		switch (cmd) {
316#ifdef INET
317		case SIOCSIFPHYADDR:
318			if (src->sa_family == AF_INET)
319				break;
320			goto end;
321#endif
322#ifdef INET6
323		case SIOCSIFPHYADDR_IN6:
324			if (src->sa_family == AF_INET6)
325				break;
326			goto end;
327#endif
328		}
329		error = EADDRNOTAVAIL;
330		switch (src->sa_family) {
331#ifdef INET
332		case AF_INET:
333			if (satosin(src)->sin_addr.s_addr == INADDR_ANY ||
334			    satosin(dst)->sin_addr.s_addr == INADDR_ANY)
335				goto end;
336			break;
337#endif
338#ifdef INET6
339		case AF_INET6:
340			if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr)
341			    ||
342			    IN6_IS_ADDR_UNSPECIFIED(&satosin6(dst)->sin6_addr))
343				goto end;
344			/*
345			 * Check validity of the scope zone ID of the
346			 * addresses, and convert it into the kernel
347			 * internal form if necessary.
348			 */
349			error = sa6_embedscope(satosin6(src), 0);
350			if (error != 0)
351				goto end;
352			error = sa6_embedscope(satosin6(dst), 0);
353			if (error != 0)
354				goto end;
355#endif
356		};
357		error = gre_set_tunnel(ifp, src, dst);
358		break;
359	case SIOCDIFPHYADDR:
360		gre_delete_tunnel(ifp);
361		break;
362	case SIOCGIFPSRCADDR:
363	case SIOCGIFPDSTADDR:
364#ifdef INET6
365	case SIOCGIFPSRCADDR_IN6:
366	case SIOCGIFPDSTADDR_IN6:
367#endif
368		if (sc->gre_family == 0) {
369			error = EADDRNOTAVAIL;
370			break;
371		}
372		GRE_RLOCK(sc);
373		switch (cmd) {
374#ifdef INET
375		case SIOCGIFPSRCADDR:
376		case SIOCGIFPDSTADDR:
377			if (sc->gre_family != AF_INET) {
378				error = EADDRNOTAVAIL;
379				break;
380			}
381			sin = (struct sockaddr_in *)&ifr->ifr_addr;
382			memset(sin, 0, sizeof(*sin));
383			sin->sin_family = AF_INET;
384			sin->sin_len = sizeof(*sin);
385			break;
386#endif
387#ifdef INET6
388		case SIOCGIFPSRCADDR_IN6:
389		case SIOCGIFPDSTADDR_IN6:
390			if (sc->gre_family != AF_INET6) {
391				error = EADDRNOTAVAIL;
392				break;
393			}
394			sin6 = (struct sockaddr_in6 *)
395				&(((struct in6_ifreq *)data)->ifr_addr);
396			memset(sin6, 0, sizeof(*sin6));
397			sin6->sin6_family = AF_INET6;
398			sin6->sin6_len = sizeof(*sin6);
399			break;
400#endif
401		}
402		if (error == 0) {
403			switch (cmd) {
404#ifdef INET
405			case SIOCGIFPSRCADDR:
406				sin->sin_addr = sc->gre_oip.ip_src;
407				break;
408			case SIOCGIFPDSTADDR:
409				sin->sin_addr = sc->gre_oip.ip_dst;
410				break;
411#endif
412#ifdef INET6
413			case SIOCGIFPSRCADDR_IN6:
414				sin6->sin6_addr = sc->gre_oip6.ip6_src;
415				break;
416			case SIOCGIFPDSTADDR_IN6:
417				sin6->sin6_addr = sc->gre_oip6.ip6_dst;
418				break;
419#endif
420			}
421		}
422		GRE_RUNLOCK(sc);
423		if (error != 0)
424			break;
425		switch (cmd) {
426#ifdef INET
427		case SIOCGIFPSRCADDR:
428		case SIOCGIFPDSTADDR:
429			error = prison_if(curthread->td_ucred,
430			    (struct sockaddr *)sin);
431			if (error != 0)
432				memset(sin, 0, sizeof(*sin));
433			break;
434#endif
435#ifdef INET6
436		case SIOCGIFPSRCADDR_IN6:
437		case SIOCGIFPDSTADDR_IN6:
438			error = prison_if(curthread->td_ucred,
439			    (struct sockaddr *)sin6);
440			if (error == 0)
441				error = sa6_recoverscope(sin6);
442			if (error != 0)
443				memset(sin6, 0, sizeof(*sin6));
444#endif
445		}
446		break;
447	case SIOCGTUNFIB:
448		ifr->ifr_fib = sc->gre_fibnum;
449		break;
450	case SIOCSTUNFIB:
451		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
452			break;
453		if (ifr->ifr_fib >= rt_numfibs)
454			error = EINVAL;
455		else
456			sc->gre_fibnum = ifr->ifr_fib;
457		break;
458	case GRESKEY:
459		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
460			break;
461		if ((error = copyin(ifr->ifr_data, &opt, sizeof(opt))) != 0)
462			break;
463		if (sc->gre_key != opt) {
464			GRE_WLOCK(sc);
465			sc->gre_key = opt;
466			gre_updatehdr(sc);
467			GRE_WUNLOCK(sc);
468		}
469		break;
470	case GREGKEY:
471		error = copyout(&sc->gre_key, ifr->ifr_data,
472		    sizeof(sc->gre_key));
473		break;
474	case GRESOPTS:
475		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
476			break;
477		if ((error = copyin(ifr->ifr_data, &opt, sizeof(opt))) != 0)
478			break;
479		if (opt & ~GRE_OPTMASK)
480			error = EINVAL;
481		else {
482			if (sc->gre_options != opt) {
483				GRE_WLOCK(sc);
484				sc->gre_options = opt;
485				gre_updatehdr(sc);
486				GRE_WUNLOCK(sc);
487			}
488		}
489		break;
490
491	case GREGOPTS:
492		error = copyout(&sc->gre_options, ifr->ifr_data,
493		    sizeof(sc->gre_options));
494		break;
495	default:
496		error = EINVAL;
497		break;
498	}
499end:
500	sx_xunlock(&gre_ioctl_sx);
501	return (error);
502}
503
504static void
505gre_updatehdr(struct gre_softc *sc)
506{
507	struct grehdr *gh = NULL;
508	uint32_t *opts;
509	uint16_t flags;
510
511	GRE_WLOCK_ASSERT(sc);
512	switch (sc->gre_family) {
513#ifdef INET
514	case AF_INET:
515		sc->gre_hlen = sizeof(struct greip);
516		sc->gre_oip.ip_v = IPPROTO_IPV4;
517		sc->gre_oip.ip_hl = sizeof(struct ip) >> 2;
518		sc->gre_oip.ip_p = IPPROTO_GRE;
519		gh = &sc->gre_gihdr->gi_gre;
520		break;
521#endif
522#ifdef INET6
523	case AF_INET6:
524		sc->gre_hlen = sizeof(struct greip6);
525		sc->gre_oip6.ip6_vfc = IPV6_VERSION;
526		sc->gre_oip6.ip6_nxt = IPPROTO_GRE;
527		gh = &sc->gre_gi6hdr->gi6_gre;
528		break;
529#endif
530	default:
531		return;
532	}
533	flags = 0;
534	opts = gh->gre_opts;
535	if (sc->gre_options & GRE_ENABLE_CSUM) {
536		flags |= GRE_FLAGS_CP;
537		sc->gre_hlen += 2 * sizeof(uint16_t);
538		*opts++ = 0;
539	}
540	if (sc->gre_key != 0) {
541		flags |= GRE_FLAGS_KP;
542		sc->gre_hlen += sizeof(uint32_t);
543		*opts++ = htonl(sc->gre_key);
544	}
545	if (sc->gre_options & GRE_ENABLE_SEQ) {
546		flags |= GRE_FLAGS_SP;
547		sc->gre_hlen += sizeof(uint32_t);
548		*opts++ = 0;
549	} else
550		sc->gre_oseq = 0;
551	gh->gre_flags = htons(flags);
552	GRE2IFP(sc)->if_mtu = sc->gre_mtu - sc->gre_hlen;
553}
554
555static void
556gre_detach(struct gre_softc *sc)
557{
558
559	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
560	if (sc->gre_ecookie != NULL)
561		encap_detach(sc->gre_ecookie);
562	sc->gre_ecookie = NULL;
563}
564
565static int
566gre_set_tunnel(struct ifnet *ifp, struct sockaddr *src,
567    struct sockaddr *dst)
568{
569	struct gre_softc *sc, *tsc;
570#ifdef INET6
571	struct ip6_hdr *ip6;
572#endif
573#ifdef INET
574	struct ip *ip;
575#endif
576	void *hdr;
577	int error;
578
579	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
580	GRE_LIST_LOCK();
581	sc = ifp->if_softc;
582	LIST_FOREACH(tsc, &V_gre_softc_list, gre_list) {
583		if (tsc == sc || tsc->gre_family != src->sa_family)
584			continue;
585#ifdef INET
586		if (tsc->gre_family == AF_INET &&
587		    tsc->gre_oip.ip_src.s_addr ==
588		    satosin(src)->sin_addr.s_addr &&
589		    tsc->gre_oip.ip_dst.s_addr ==
590		    satosin(dst)->sin_addr.s_addr) {
591			GRE_LIST_UNLOCK();
592			return (EADDRNOTAVAIL);
593		}
594#endif
595#ifdef INET6
596		if (tsc->gre_family == AF_INET6 &&
597		    IN6_ARE_ADDR_EQUAL(&tsc->gre_oip6.ip6_src,
598		    &satosin6(src)->sin6_addr) &&
599		    IN6_ARE_ADDR_EQUAL(&tsc->gre_oip6.ip6_dst,
600			&satosin6(dst)->sin6_addr)) {
601			GRE_LIST_UNLOCK();
602			return (EADDRNOTAVAIL);
603		}
604#endif
605	}
606	GRE_LIST_UNLOCK();
607
608	error = 0;
609	switch (src->sa_family) {
610#ifdef INET
611	case AF_INET:
612		hdr = ip = malloc(sizeof(struct greip) +
613		    3 * sizeof(uint32_t), M_GRE, M_WAITOK | M_ZERO);
614		ip->ip_src = satosin(src)->sin_addr;
615		ip->ip_dst = satosin(dst)->sin_addr;
616		break;
617#endif
618#ifdef INET6
619	case AF_INET6:
620		hdr = ip6 = malloc(sizeof(struct greip6) +
621		    3 * sizeof(uint32_t), M_GRE, M_WAITOK | M_ZERO);
622		ip6->ip6_src = satosin6(src)->sin6_addr;
623		ip6->ip6_dst = satosin6(dst)->sin6_addr;
624		break;
625#endif
626	default:
627		return (EAFNOSUPPORT);
628	}
629	if (sc->gre_family != 0)
630		gre_detach(sc);
631	GRE_WLOCK(sc);
632	if (sc->gre_family != 0)
633		free(sc->gre_hdr, M_GRE);
634	sc->gre_family = src->sa_family;
635	sc->gre_hdr = hdr;
636	sc->gre_oseq = 0;
637	sc->gre_iseq = UINT32_MAX;
638	gre_updatehdr(sc);
639	GRE_WUNLOCK(sc);
640
641	switch (src->sa_family) {
642#ifdef INET
643	case AF_INET:
644		error = in_gre_attach(sc);
645		break;
646#endif
647#ifdef INET6
648	case AF_INET6:
649		error = in6_gre_attach(sc);
650		break;
651#endif
652	}
653	if (error == 0) {
654		ifp->if_drv_flags |= IFF_DRV_RUNNING;
655		if_link_state_change(ifp, LINK_STATE_UP);
656	}
657	return (error);
658}
659
660static void
661gre_delete_tunnel(struct ifnet *ifp)
662{
663	struct gre_softc *sc = ifp->if_softc;
664	int family;
665
666	GRE_WLOCK(sc);
667	family = sc->gre_family;
668	sc->gre_family = 0;
669	GRE_WUNLOCK(sc);
670	if (family != 0) {
671		gre_detach(sc);
672		free(sc->gre_hdr, M_GRE);
673	}
674	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
675	if_link_state_change(ifp, LINK_STATE_DOWN);
676}
677
678int
679gre_input(struct mbuf **mp, int *offp, int proto)
680{
681	struct gre_softc *sc;
682	struct grehdr *gh;
683	struct ifnet *ifp;
684	struct mbuf *m;
685	uint32_t *opts;
686#ifdef notyet
687    uint32_t key;
688#endif
689	uint16_t flags;
690	int hlen, isr, af;
691
692	m = *mp;
693	sc = encap_getarg(m);
694	KASSERT(sc != NULL, ("encap_getarg returned NULL"));
695
696	ifp = GRE2IFP(sc);
697	hlen = *offp + sizeof(struct grehdr) + 4 * sizeof(uint32_t);
698	if (m->m_pkthdr.len < hlen)
699		goto drop;
700	if (m->m_len < hlen) {
701		m = m_pullup(m, hlen);
702		if (m == NULL)
703			goto drop;
704	}
705	gh = (struct grehdr *)mtodo(m, *offp);
706	flags = ntohs(gh->gre_flags);
707	if (flags & ~GRE_FLAGS_MASK)
708		goto drop;
709	opts = gh->gre_opts;
710	hlen = 2 * sizeof(uint16_t);
711	if (flags & GRE_FLAGS_CP) {
712		/* reserved1 field must be zero */
713		if (((uint16_t *)opts)[1] != 0)
714			goto drop;
715		if (in_cksum_skip(m, m->m_pkthdr.len, *offp) != 0)
716			goto drop;
717		hlen += 2 * sizeof(uint16_t);
718		opts++;
719	}
720	if (flags & GRE_FLAGS_KP) {
721#ifdef notyet
722        /*
723         * XXX: The current implementation uses the key only for outgoing
724         * packets. But we can check the key value here, or even in the
725         * encapcheck function.
726         */
727		key = ntohl(*opts);
728#endif
729		hlen += sizeof(uint32_t);
730		opts++;
731    }
732#ifdef notyet
733	} else
734		key = 0;
735	if (sc->gre_key != 0 && (key != sc->gre_key || key != 0))
736		goto drop;
737#endif
738	if (flags & GRE_FLAGS_SP) {
739#ifdef notyet
740		seq = ntohl(*opts);
741#endif
742		hlen += sizeof(uint32_t);
743	}
744	switch (ntohs(gh->gre_proto)) {
745	case ETHERTYPE_WCCP:
746		/*
747		 * For WCCP skip an additional 4 bytes if after GRE header
748		 * doesn't follow an IP header.
749		 */
750		if (flags == 0 && (*(uint8_t *)gh->gre_opts & 0xF0) != 0x40)
751			hlen += sizeof(uint32_t);
752		/* FALLTHROUGH */
753	case ETHERTYPE_IP:
754		isr = NETISR_IP;
755		af = AF_INET;
756		break;
757	case ETHERTYPE_IPV6:
758		isr = NETISR_IPV6;
759		af = AF_INET6;
760		break;
761	default:
762		goto drop;
763	}
764	m_adj(m, *offp + hlen);
765	m_clrprotoflags(m);
766	m->m_pkthdr.rcvif = ifp;
767	M_SETFIB(m, ifp->if_fib);
768#ifdef MAC
769	mac_ifnet_create_mbuf(ifp, m);
770#endif
771	BPF_MTAP2(ifp, &af, sizeof(af), m);
772	ifp->if_ipackets++;
773	ifp->if_ibytes += m->m_pkthdr.len;
774	if ((ifp->if_flags & IFF_MONITOR) != 0)
775		m_freem(m);
776	else
777		netisr_dispatch(isr, m);
778	return (IPPROTO_DONE);
779drop:
780	ifp->if_ierrors++;
781	m_freem(m);
782	return (IPPROTO_DONE);
783}
784
785#define	MTAG_GRE	1307983903
786static int
787gre_check_nesting(struct ifnet *ifp, struct mbuf *m)
788{
789	struct m_tag *mtag;
790	int count;
791
792	count = 1;
793	mtag = NULL;
794	while ((mtag = m_tag_locate(m, MTAG_GRE, 0, mtag)) != NULL) {
795		if (*(struct ifnet **)(mtag + 1) == ifp) {
796			log(LOG_NOTICE, "%s: loop detected\n", ifp->if_xname);
797			return (EIO);
798		}
799		count++;
800	}
801	if (count > V_max_gre_nesting) {
802		log(LOG_NOTICE,
803		    "%s: if_output recursively called too many times(%d)\n",
804		    ifp->if_xname, count);
805		return (EIO);
806	}
807	mtag = m_tag_alloc(MTAG_GRE, 0, sizeof(struct ifnet *), M_NOWAIT);
808	if (mtag == NULL)
809		return (ENOMEM);
810	*(struct ifnet **)(mtag + 1) = ifp;
811	m_tag_prepend(m, mtag);
812	return (0);
813}
814
815static int
816gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
817   struct route *ro)
818{
819	uint32_t af;
820	int error;
821
822#ifdef MAC
823	error = mac_ifnet_check_transmit(ifp, m);
824	if (error != 0)
825		goto drop;
826#endif
827	if ((ifp->if_flags & IFF_MONITOR) != 0 ||
828	    (ifp->if_flags & IFF_UP) == 0) {
829		error = ENETDOWN;
830		goto drop;
831	}
832
833	error = gre_check_nesting(ifp, m);
834	if (error != 0)
835		goto drop;
836
837	m->m_flags &= ~(M_BCAST|M_MCAST);
838	if (dst->sa_family == AF_UNSPEC)
839		bcopy(dst->sa_data, &af, sizeof(af));
840	else
841		af = dst->sa_family;
842	BPF_MTAP2(ifp, &af, sizeof(af), m);
843	m->m_pkthdr.csum_data = af;	/* save af for if_transmit */
844	return (ifp->if_transmit(ifp, m));
845drop:
846	m_freem(m);
847	ifp->if_oerrors++;
848	return (error);
849}
850
851static void
852gre_setseqn(struct grehdr *gh, uint32_t seq)
853{
854	uint32_t *opts;
855	uint16_t flags;
856
857	opts = gh->gre_opts;
858	flags = ntohs(gh->gre_flags);
859	KASSERT((flags & GRE_FLAGS_SP) != 0,
860	    ("gre_setseqn called, but GRE_FLAGS_SP isn't set "));
861	if (flags & GRE_FLAGS_CP)
862		opts++;
863	if (flags & GRE_FLAGS_KP)
864		opts++;
865	*opts = htonl(seq);
866}
867
868static int
869gre_transmit(struct ifnet *ifp, struct mbuf *m)
870{
871	GRE_RLOCK_TRACKER;
872	struct gre_softc *sc;
873	struct grehdr *gh;
874	uint32_t iaf, oaf, oseq;
875	int error, hlen, olen, plen;
876	int want_seq, want_csum;
877
878	plen = 0;
879	sc = ifp->if_softc;
880	if (sc == NULL) {
881		error = ENETDOWN;
882		m_freem(m);
883		goto drop;
884	}
885	GRE_RLOCK(sc);
886	if (sc->gre_family == 0) {
887		GRE_RUNLOCK(sc);
888		error = ENETDOWN;
889		m_freem(m);
890		goto drop;
891	}
892	iaf = m->m_pkthdr.csum_data;
893	oaf = sc->gre_family;
894	hlen = sc->gre_hlen;
895	want_seq = (sc->gre_options & GRE_ENABLE_SEQ) != 0;
896	if (want_seq)
897		oseq = sc->gre_oseq++;
898	else
899		oseq = 0;	/* Make compiler happy. */
900	want_csum = (sc->gre_options & GRE_ENABLE_CSUM) != 0;
901	M_SETFIB(m, sc->gre_fibnum);
902	M_PREPEND(m, hlen, M_NOWAIT);
903	if (m == NULL) {
904		GRE_RUNLOCK(sc);
905		error = ENOBUFS;
906		goto drop;
907	}
908	bcopy(sc->gre_hdr, mtod(m, void *), hlen);
909	GRE_RUNLOCK(sc);
910	switch (oaf) {
911#ifdef INET
912	case AF_INET:
913		olen = sizeof(struct ip);
914		break;
915#endif
916#ifdef INET6
917	case AF_INET6:
918		olen = sizeof(struct ip6_hdr);
919		break;
920#endif
921	default:
922		error = ENETDOWN;
923		goto drop;
924	}
925	gh = (struct grehdr *)mtodo(m, olen);
926	switch (iaf) {
927#ifdef INET
928	case AF_INET:
929		gh->gre_proto = htons(ETHERTYPE_IP);
930		break;
931#endif
932#ifdef INET6
933	case AF_INET6:
934		gh->gre_proto = htons(ETHERTYPE_IPV6);
935		break;
936#endif
937	default:
938		error = ENETDOWN;
939		goto drop;
940	}
941	if (want_seq)
942		gre_setseqn(gh, oseq);
943	if (want_csum) {
944		*(uint16_t *)gh->gre_opts = in_cksum_skip(m,
945		    m->m_pkthdr.len, olen);
946	}
947	plen = m->m_pkthdr.len - hlen;
948	switch (oaf) {
949#ifdef INET
950	case AF_INET:
951		error = in_gre_output(m, iaf, hlen);
952		break;
953#endif
954#ifdef INET6
955	case AF_INET6:
956		error = in6_gre_output(m, iaf, hlen);
957		break;
958#endif
959	default:
960		m_freem(m);
961		error = ENETDOWN;
962	};
963drop:
964	if (error)
965		ifp->if_oerrors++;
966	else {
967		ifp->if_opackets++;
968		ifp->if_obytes += plen;
969	}
970	return (error);
971}
972
973static void
974gre_qflush(struct ifnet *ifp __unused)
975{
976
977}
978
979static int
980gremodevent(module_t mod, int type, void *data)
981{
982
983	switch (type) {
984	case MOD_LOAD:
985	case MOD_UNLOAD:
986		break;
987	default:
988		return (EOPNOTSUPP);
989	}
990	return (0);
991}
992
993static moduledata_t gre_mod = {
994	"if_gre",
995	gremodevent,
996	0
997};
998
999DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
1000MODULE_VERSION(if_gre, 1);
1001