1/*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 1998 The NetBSD Foundation, Inc.
5 * Copyright (c) 2014, 2018 Andrey V. Elsukov <ae@FreeBSD.org>
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Heiko W.Rupp <hwr@pilhuhn.de>
10 *
11 * IPv6-over-GRE contributed by Gert Doering <gert@greenie.muc.de>
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 *    notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 *    notice, this list of conditions and the following disclaimer in the
20 *    documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *
34 * $NetBSD: if_gre.c,v 1.49 2003/12/11 00:22:29 itojun Exp $
35 */
36
37#include <sys/cdefs.h>
38#include "opt_inet.h"
39#include "opt_inet6.h"
40#include "opt_rss.h"
41
42#include <sys/param.h>
43#include <sys/kernel.h>
44#include <sys/lock.h>
45#include <sys/malloc.h>
46#include <sys/module.h>
47#include <sys/mbuf.h>
48#include <sys/priv.h>
49#include <sys/proc.h>
50#include <sys/socket.h>
51#include <sys/socketvar.h>
52#include <sys/sockio.h>
53#include <sys/sx.h>
54#include <sys/sysctl.h>
55#include <sys/syslog.h>
56#include <sys/systm.h>
57
58#include <net/ethernet.h>
59#include <net/if.h>
60#include <net/if_var.h>
61#include <net/if_private.h>
62#include <net/if_clone.h>
63#include <net/if_types.h>
64#include <net/netisr.h>
65#include <net/vnet.h>
66#include <net/route.h>
67
68#include <netinet/in.h>
69#include <netinet/in_pcb.h>
70#ifdef INET
71#include <netinet/in_var.h>
72#include <netinet/ip.h>
73#include <netinet/ip_var.h>
74#ifdef RSS
75#include <netinet/in_rss.h>
76#endif
77#endif
78
79#ifdef INET6
80#include <netinet/ip6.h>
81#include <netinet6/in6_var.h>
82#include <netinet6/ip6_var.h>
83#ifdef RSS
84#include <netinet6/in6_rss.h>
85#endif
86#endif
87
88#include <netinet/ip_encap.h>
89#include <netinet/udp.h>
90#include <net/bpf.h>
91#include <net/if_gre.h>
92
93#include <machine/in_cksum.h>
94#include <security/mac/mac_framework.h>
95
96#define	GREMTU			1476
97
98static const char grename[] = "gre";
99MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
100
101static struct sx gre_ioctl_sx;
102SX_SYSINIT(gre_ioctl_sx, &gre_ioctl_sx, "gre_ioctl");
103
104static int	gre_clone_create(struct if_clone *, int, caddr_t);
105static void	gre_clone_destroy(struct ifnet *);
106VNET_DEFINE_STATIC(struct if_clone *, gre_cloner);
107#define	V_gre_cloner	VNET(gre_cloner)
108
109#ifdef VIMAGE
110static void	gre_reassign(struct ifnet *, struct vnet *, char *);
111#endif
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 *);
117static void	gre_delete_tunnel(struct gre_softc *);
118
119SYSCTL_DECL(_net_link);
120static SYSCTL_NODE(_net_link, IFT_TUNNEL, gre, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
121    "Generic Routing Encapsulation");
122#ifndef MAX_GRE_NEST
123/*
124 * This macro controls the default upper limitation on nesting of gre tunnels.
125 * Since, setting a large value to this macro with a careless configuration
126 * may introduce system crash, we don't allow any nestings by default.
127 * If you need to configure nested gre tunnels, you can define this macro
128 * in your kernel configuration file.  However, if you do so, please be
129 * careful to configure the tunnels so that it won't make a loop.
130 */
131#define MAX_GRE_NEST 1
132#endif
133
134VNET_DEFINE_STATIC(int, max_gre_nesting) = MAX_GRE_NEST;
135#define	V_max_gre_nesting	VNET(max_gre_nesting)
136SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET,
137    &VNET_NAME(max_gre_nesting), 0, "Max nested tunnels");
138
139static void
140vnet_gre_init(const void *unused __unused)
141{
142
143	V_gre_cloner = if_clone_simple(grename, gre_clone_create,
144	    gre_clone_destroy, 0);
145#ifdef INET
146	in_gre_init();
147#endif
148#ifdef INET6
149	in6_gre_init();
150#endif
151}
152VNET_SYSINIT(vnet_gre_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
153    vnet_gre_init, NULL);
154
155static void
156vnet_gre_uninit(const void *unused __unused)
157{
158
159	if_clone_detach(V_gre_cloner);
160#ifdef INET
161	in_gre_uninit();
162#endif
163#ifdef INET6
164	in6_gre_uninit();
165#endif
166	/* XXX: epoch_call drain */
167}
168VNET_SYSUNINIT(vnet_gre_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
169    vnet_gre_uninit, NULL);
170
171static int
172gre_clone_create(struct if_clone *ifc, int unit, caddr_t params)
173{
174	struct gre_softc *sc;
175
176	sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK | M_ZERO);
177	sc->gre_fibnum = curthread->td_proc->p_fibnum;
178	GRE2IFP(sc) = if_alloc(IFT_TUNNEL);
179	GRE2IFP(sc)->if_softc = sc;
180	if_initname(GRE2IFP(sc), grename, unit);
181
182	GRE2IFP(sc)->if_mtu = GREMTU;
183	GRE2IFP(sc)->if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
184	GRE2IFP(sc)->if_output = gre_output;
185	GRE2IFP(sc)->if_ioctl = gre_ioctl;
186	GRE2IFP(sc)->if_transmit = gre_transmit;
187	GRE2IFP(sc)->if_qflush = gre_qflush;
188#ifdef VIMAGE
189	GRE2IFP(sc)->if_reassign = gre_reassign;
190#endif
191	GRE2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE;
192	GRE2IFP(sc)->if_capenable |= IFCAP_LINKSTATE;
193	if_attach(GRE2IFP(sc));
194	bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
195	return (0);
196}
197
198#ifdef VIMAGE
199static void
200gre_reassign(struct ifnet *ifp, struct vnet *new_vnet __unused,
201    char *unused __unused)
202{
203	struct gre_softc *sc;
204
205	sx_xlock(&gre_ioctl_sx);
206	sc = ifp->if_softc;
207	if (sc != NULL)
208		gre_delete_tunnel(sc);
209	sx_xunlock(&gre_ioctl_sx);
210}
211#endif /* VIMAGE */
212
213static void
214gre_clone_destroy(struct ifnet *ifp)
215{
216	struct gre_softc *sc;
217
218	sx_xlock(&gre_ioctl_sx);
219	sc = ifp->if_softc;
220	gre_delete_tunnel(sc);
221	bpfdetach(ifp);
222	if_detach(ifp);
223	ifp->if_softc = NULL;
224	sx_xunlock(&gre_ioctl_sx);
225
226	GRE_WAIT();
227	if_free(ifp);
228	free(sc, M_GRE);
229}
230
231static int
232gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
233{
234	struct ifreq *ifr = (struct ifreq *)data;
235	struct gre_softc *sc;
236	uint32_t opt;
237	int error;
238
239	switch (cmd) {
240	case SIOCSIFMTU:
241		 /* XXX: */
242		if (ifr->ifr_mtu < 576)
243			return (EINVAL);
244		ifp->if_mtu = ifr->ifr_mtu;
245		return (0);
246	case SIOCSIFADDR:
247		ifp->if_flags |= IFF_UP;
248	case SIOCSIFFLAGS:
249	case SIOCADDMULTI:
250	case SIOCDELMULTI:
251		return (0);
252	case GRESADDRS:
253	case GRESADDRD:
254	case GREGADDRS:
255	case GREGADDRD:
256	case GRESPROTO:
257	case GREGPROTO:
258		return (EOPNOTSUPP);
259	}
260	sx_xlock(&gre_ioctl_sx);
261	sc = ifp->if_softc;
262	if (sc == NULL) {
263		error = ENXIO;
264		goto end;
265	}
266	error = 0;
267	switch (cmd) {
268	case SIOCDIFPHYADDR:
269		if (sc->gre_family == 0)
270			break;
271		gre_delete_tunnel(sc);
272		break;
273#ifdef INET
274	case SIOCSIFPHYADDR:
275	case SIOCGIFPSRCADDR:
276	case SIOCGIFPDSTADDR:
277		error = in_gre_ioctl(sc, cmd, data);
278		break;
279#endif
280#ifdef INET6
281	case SIOCSIFPHYADDR_IN6:
282	case SIOCGIFPSRCADDR_IN6:
283	case SIOCGIFPDSTADDR_IN6:
284		error = in6_gre_ioctl(sc, cmd, data);
285		break;
286#endif
287	case SIOCGTUNFIB:
288		ifr->ifr_fib = sc->gre_fibnum;
289		break;
290	case SIOCSTUNFIB:
291		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
292			break;
293		if (ifr->ifr_fib >= rt_numfibs)
294			error = EINVAL;
295		else
296			sc->gre_fibnum = ifr->ifr_fib;
297		break;
298	case GRESKEY:
299	case GRESOPTS:
300	case GRESPORT:
301		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
302			break;
303		if ((error = copyin(ifr_data_get_ptr(ifr), &opt,
304		    sizeof(opt))) != 0)
305			break;
306		if (cmd == GRESKEY) {
307			if (sc->gre_key == opt)
308				break;
309		} else if (cmd == GRESOPTS) {
310			if (opt & ~GRE_OPTMASK) {
311				error = EINVAL;
312				break;
313			}
314			if (sc->gre_options == opt)
315				break;
316		} else if (cmd == GRESPORT) {
317			if (opt != 0 && (opt < V_ipport_hifirstauto ||
318			    opt > V_ipport_hilastauto)) {
319				error = EINVAL;
320				break;
321			}
322			if (sc->gre_port == opt)
323				break;
324			if ((sc->gre_options & GRE_UDPENCAP) == 0) {
325				/*
326				 * UDP encapsulation is not enabled, thus
327				 * there is no need to reattach softc.
328				 */
329				sc->gre_port = opt;
330				break;
331			}
332		}
333		switch (sc->gre_family) {
334#ifdef INET
335		case AF_INET:
336			error = in_gre_setopts(sc, cmd, opt);
337			break;
338#endif
339#ifdef INET6
340		case AF_INET6:
341			error = in6_gre_setopts(sc, cmd, opt);
342			break;
343#endif
344		default:
345			/*
346			 * Tunnel is not yet configured.
347			 * We can just change any parameters.
348			 */
349			if (cmd == GRESKEY)
350				sc->gre_key = opt;
351			if (cmd == GRESOPTS)
352				sc->gre_options = opt;
353			if (cmd == GRESPORT)
354				sc->gre_port = opt;
355			break;
356		}
357		/*
358		 * XXX: Do we need to initiate change of interface
359		 * state here?
360		 */
361		break;
362	case GREGKEY:
363		error = copyout(&sc->gre_key, ifr_data_get_ptr(ifr),
364		    sizeof(sc->gre_key));
365		break;
366	case GREGOPTS:
367		error = copyout(&sc->gre_options, ifr_data_get_ptr(ifr),
368		    sizeof(sc->gre_options));
369		break;
370	case GREGPORT:
371		error = copyout(&sc->gre_port, ifr_data_get_ptr(ifr),
372		    sizeof(sc->gre_port));
373		break;
374	default:
375		error = EINVAL;
376		break;
377	}
378	if (error == 0 && sc->gre_family != 0) {
379		if (
380#ifdef INET
381		    cmd == SIOCSIFPHYADDR ||
382#endif
383#ifdef INET6
384		    cmd == SIOCSIFPHYADDR_IN6 ||
385#endif
386		    0) {
387			if_link_state_change(ifp, LINK_STATE_UP);
388		}
389	}
390end:
391	sx_xunlock(&gre_ioctl_sx);
392	return (error);
393}
394
395static void
396gre_delete_tunnel(struct gre_softc *sc)
397{
398	struct gre_socket *gs;
399
400	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
401	if (sc->gre_family != 0) {
402		CK_LIST_REMOVE(sc, chain);
403		CK_LIST_REMOVE(sc, srchash);
404		GRE_WAIT();
405		free(sc->gre_hdr, M_GRE);
406		sc->gre_family = 0;
407	}
408	/*
409	 * If this Tunnel was the last one that could use UDP socket,
410	 * we should unlink socket from hash table and close it.
411	 */
412	if ((gs = sc->gre_so) != NULL && CK_LIST_EMPTY(&gs->list)) {
413		CK_LIST_REMOVE(gs, chain);
414		soclose(gs->so);
415		NET_EPOCH_CALL(gre_sofree, &gs->epoch_ctx);
416		sc->gre_so = NULL;
417	}
418	GRE2IFP(sc)->if_drv_flags &= ~IFF_DRV_RUNNING;
419	if_link_state_change(GRE2IFP(sc), LINK_STATE_DOWN);
420}
421
422struct gre_list *
423gre_hashinit(void)
424{
425	struct gre_list *hash;
426	int i;
427
428	hash = malloc(sizeof(struct gre_list) * GRE_HASH_SIZE,
429	    M_GRE, M_WAITOK);
430	for (i = 0; i < GRE_HASH_SIZE; i++)
431		CK_LIST_INIT(&hash[i]);
432
433	return (hash);
434}
435
436void
437gre_hashdestroy(struct gre_list *hash)
438{
439
440	free(hash, M_GRE);
441}
442
443void
444gre_sofree(epoch_context_t ctx)
445{
446	struct gre_socket *gs;
447
448	gs = __containerof(ctx, struct gre_socket, epoch_ctx);
449	free(gs, M_GRE);
450}
451
452static __inline uint16_t
453gre_cksum_add(uint16_t sum, uint16_t a)
454{
455	uint16_t res;
456
457	res = sum + a;
458	return (res + (res < a));
459}
460
461void
462gre_update_udphdr(struct gre_softc *sc, struct udphdr *udp, uint16_t csum)
463{
464
465	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
466	MPASS(sc->gre_options & GRE_UDPENCAP);
467
468	udp->uh_dport = htons(GRE_UDPPORT);
469	udp->uh_sport = htons(sc->gre_port);
470	udp->uh_sum = csum;
471	udp->uh_ulen = 0;
472}
473
474void
475gre_update_hdr(struct gre_softc *sc, struct grehdr *gh)
476{
477	uint32_t *opts;
478	uint16_t flags;
479
480	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
481
482	flags = 0;
483	opts = gh->gre_opts;
484	if (sc->gre_options & GRE_ENABLE_CSUM) {
485		flags |= GRE_FLAGS_CP;
486		sc->gre_hlen += 2 * sizeof(uint16_t);
487		*opts++ = 0;
488	}
489	if (sc->gre_key != 0) {
490		flags |= GRE_FLAGS_KP;
491		sc->gre_hlen += sizeof(uint32_t);
492		*opts++ = htonl(sc->gre_key);
493	}
494	if (sc->gre_options & GRE_ENABLE_SEQ) {
495		flags |= GRE_FLAGS_SP;
496		sc->gre_hlen += sizeof(uint32_t);
497		*opts++ = 0;
498	} else
499		sc->gre_oseq = 0;
500	gh->gre_flags = htons(flags);
501}
502
503int
504gre_input(struct mbuf *m, int off, int proto, void *arg)
505{
506	struct gre_softc *sc = arg;
507	struct grehdr *gh;
508	struct ifnet *ifp;
509	uint32_t *opts;
510#ifdef notyet
511	uint32_t key;
512#endif
513	uint16_t flags;
514	int hlen, isr, af;
515
516	ifp = GRE2IFP(sc);
517	hlen = off + sizeof(struct grehdr) + 4 * sizeof(uint32_t);
518	if (m->m_pkthdr.len < hlen)
519		goto drop;
520	if (m->m_len < hlen) {
521		m = m_pullup(m, hlen);
522		if (m == NULL)
523			goto drop;
524	}
525	gh = (struct grehdr *)mtodo(m, off);
526	flags = ntohs(gh->gre_flags);
527	if (flags & ~GRE_FLAGS_MASK)
528		goto drop;
529	opts = gh->gre_opts;
530	hlen = 2 * sizeof(uint16_t);
531	if (flags & GRE_FLAGS_CP) {
532		/* reserved1 field must be zero */
533		if (((uint16_t *)opts)[1] != 0)
534			goto drop;
535		if (in_cksum_skip(m, m->m_pkthdr.len, off) != 0)
536			goto drop;
537		hlen += 2 * sizeof(uint16_t);
538		opts++;
539	}
540	if (flags & GRE_FLAGS_KP) {
541#ifdef notyet
542        /*
543         * XXX: The current implementation uses the key only for outgoing
544         * packets. But we can check the key value here, or even in the
545         * encapcheck function.
546         */
547		key = ntohl(*opts);
548#endif
549		hlen += sizeof(uint32_t);
550		opts++;
551    }
552#ifdef notyet
553	} else
554		key = 0;
555
556	if (sc->gre_key != 0 && (key != sc->gre_key || key != 0))
557		goto drop;
558#endif
559	if (flags & GRE_FLAGS_SP) {
560#ifdef notyet
561		seq = ntohl(*opts);
562#endif
563		hlen += sizeof(uint32_t);
564	}
565	switch (ntohs(gh->gre_proto)) {
566	case ETHERTYPE_WCCP:
567		/*
568		 * For WCCP skip an additional 4 bytes if after GRE header
569		 * doesn't follow an IP header.
570		 */
571		if (flags == 0 && (*(uint8_t *)gh->gre_opts & 0xF0) != 0x40)
572			hlen += sizeof(uint32_t);
573		/* FALLTHROUGH */
574	case ETHERTYPE_IP:
575		isr = NETISR_IP;
576		af = AF_INET;
577		break;
578	case ETHERTYPE_IPV6:
579		isr = NETISR_IPV6;
580		af = AF_INET6;
581		break;
582	default:
583		goto drop;
584	}
585	m_adj(m, off + hlen);
586	m_clrprotoflags(m);
587	m->m_pkthdr.rcvif = ifp;
588	M_SETFIB(m, ifp->if_fib);
589#ifdef MAC
590	mac_ifnet_create_mbuf(ifp, m);
591#endif
592	BPF_MTAP2(ifp, &af, sizeof(af), m);
593	if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
594	if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
595	if ((ifp->if_flags & IFF_MONITOR) != 0)
596		m_freem(m);
597	else
598		netisr_dispatch(isr, m);
599	return (IPPROTO_DONE);
600drop:
601	if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
602	m_freem(m);
603	return (IPPROTO_DONE);
604}
605
606static int
607gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
608   struct route *ro)
609{
610	uint32_t af;
611
612	/* BPF writes need to be handled specially. */
613	if (dst->sa_family == AF_UNSPEC || dst->sa_family == pseudo_AF_HDRCMPLT)
614		bcopy(dst->sa_data, &af, sizeof(af));
615	else
616		af = RO_GET_FAMILY(ro, dst);
617	/*
618	 * Now save the af in the inbound pkt csum data, this is a cheat since
619	 * we are using the inbound csum_data field to carry the af over to
620	 * the gre_transmit() routine, avoiding using yet another mtag.
621	 */
622	m->m_pkthdr.csum_data = af;
623	return (ifp->if_transmit(ifp, m));
624}
625
626static void
627gre_setseqn(struct grehdr *gh, uint32_t seq)
628{
629	uint32_t *opts;
630	uint16_t flags;
631
632	opts = gh->gre_opts;
633	flags = ntohs(gh->gre_flags);
634	KASSERT((flags & GRE_FLAGS_SP) != 0,
635	    ("gre_setseqn called, but GRE_FLAGS_SP isn't set "));
636	if (flags & GRE_FLAGS_CP)
637		opts++;
638	if (flags & GRE_FLAGS_KP)
639		opts++;
640	*opts = htonl(seq);
641}
642
643static uint32_t
644gre_flowid(struct gre_softc *sc, struct mbuf *m, uint32_t af)
645{
646	uint32_t flowid = 0;
647
648	if ((sc->gre_options & GRE_UDPENCAP) == 0 || sc->gre_port != 0)
649		return (flowid);
650	switch (af) {
651#ifdef INET
652	case AF_INET:
653#ifdef RSS
654		flowid = rss_hash_ip4_2tuple(mtod(m, struct ip *)->ip_src,
655		    mtod(m, struct ip *)->ip_dst);
656		break;
657#endif
658		flowid = mtod(m, struct ip *)->ip_src.s_addr ^
659		    mtod(m, struct ip *)->ip_dst.s_addr;
660		break;
661#endif
662#ifdef INET6
663	case AF_INET6:
664#ifdef RSS
665		flowid = rss_hash_ip6_2tuple(
666		    &mtod(m, struct ip6_hdr *)->ip6_src,
667		    &mtod(m, struct ip6_hdr *)->ip6_dst);
668		break;
669#endif
670		flowid = mtod(m, struct ip6_hdr *)->ip6_src.s6_addr32[3] ^
671		    mtod(m, struct ip6_hdr *)->ip6_dst.s6_addr32[3];
672		break;
673#endif
674	default:
675		break;
676	}
677	return (flowid);
678}
679
680#define	MTAG_GRE	1307983903
681static int
682gre_transmit(struct ifnet *ifp, struct mbuf *m)
683{
684	GRE_RLOCK_TRACKER;
685	struct gre_softc *sc;
686	struct grehdr *gh;
687	struct udphdr *uh;
688	uint32_t af, flowid;
689	int error, len;
690	uint16_t proto;
691
692	len = 0;
693	GRE_RLOCK();
694#ifdef MAC
695	error = mac_ifnet_check_transmit(ifp, m);
696	if (error) {
697		m_freem(m);
698		goto drop;
699	}
700#endif
701	error = ENETDOWN;
702	sc = ifp->if_softc;
703	if ((ifp->if_flags & IFF_MONITOR) != 0 ||
704	    (ifp->if_flags & IFF_UP) == 0 ||
705	    (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
706	    sc->gre_family == 0 ||
707	    (error = if_tunnel_check_nesting(ifp, m, MTAG_GRE,
708		V_max_gre_nesting)) != 0) {
709		m_freem(m);
710		goto drop;
711	}
712	af = m->m_pkthdr.csum_data;
713	BPF_MTAP2(ifp, &af, sizeof(af), m);
714	m->m_flags &= ~(M_BCAST|M_MCAST);
715	flowid = gre_flowid(sc, m, af);
716	M_SETFIB(m, sc->gre_fibnum);
717	M_PREPEND(m, sc->gre_hlen, M_NOWAIT);
718	if (m == NULL) {
719		error = ENOBUFS;
720		goto drop;
721	}
722	bcopy(sc->gre_hdr, mtod(m, void *), sc->gre_hlen);
723	/* Determine GRE proto */
724	switch (af) {
725#ifdef INET
726	case AF_INET:
727		proto = htons(ETHERTYPE_IP);
728		break;
729#endif
730#ifdef INET6
731	case AF_INET6:
732		proto = htons(ETHERTYPE_IPV6);
733		break;
734#endif
735	default:
736		m_freem(m);
737		error = ENETDOWN;
738		goto drop;
739	}
740	/* Determine offset of GRE header */
741	switch (sc->gre_family) {
742#ifdef INET
743	case AF_INET:
744		len = sizeof(struct ip);
745		break;
746#endif
747#ifdef INET6
748	case AF_INET6:
749		len = sizeof(struct ip6_hdr);
750		break;
751#endif
752	default:
753		m_freem(m);
754		error = ENETDOWN;
755		goto drop;
756	}
757	if (sc->gre_options & GRE_UDPENCAP) {
758		uh = (struct udphdr *)mtodo(m, len);
759		uh->uh_sport |= htons(V_ipport_hifirstauto) |
760		    (flowid >> 16) | (flowid & 0xFFFF);
761		uh->uh_sport = htons(ntohs(uh->uh_sport) %
762		    V_ipport_hilastauto);
763		uh->uh_ulen = htons(m->m_pkthdr.len - len);
764		uh->uh_sum = gre_cksum_add(uh->uh_sum,
765		    htons(m->m_pkthdr.len - len + IPPROTO_UDP));
766		m->m_pkthdr.csum_flags = sc->gre_csumflags;
767		m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum);
768		len += sizeof(struct udphdr);
769	}
770	gh = (struct grehdr *)mtodo(m, len);
771	gh->gre_proto = proto;
772	if (sc->gre_options & GRE_ENABLE_SEQ)
773		gre_setseqn(gh, sc->gre_oseq++);
774	if (sc->gre_options & GRE_ENABLE_CSUM) {
775		*(uint16_t *)gh->gre_opts = in_cksum_skip(m,
776		    m->m_pkthdr.len, len);
777	}
778	len = m->m_pkthdr.len - len;
779	switch (sc->gre_family) {
780#ifdef INET
781	case AF_INET:
782		error = in_gre_output(m, af, sc->gre_hlen);
783		break;
784#endif
785#ifdef INET6
786	case AF_INET6:
787		error = in6_gre_output(m, af, sc->gre_hlen, flowid);
788		break;
789#endif
790	default:
791		m_freem(m);
792		error = ENETDOWN;
793	}
794drop:
795	if (error)
796		if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
797	else {
798		if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
799		if_inc_counter(ifp, IFCOUNTER_OBYTES, len);
800	}
801	GRE_RUNLOCK();
802	return (error);
803}
804
805static void
806gre_qflush(struct ifnet *ifp __unused)
807{
808
809}
810
811static int
812gremodevent(module_t mod, int type, void *data)
813{
814
815	switch (type) {
816	case MOD_LOAD:
817	case MOD_UNLOAD:
818		break;
819	default:
820		return (EOPNOTSUPP);
821	}
822	return (0);
823}
824
825static moduledata_t gre_mod = {
826	"if_gre",
827	gremodevent,
828	0
829};
830
831DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
832MODULE_VERSION(if_gre, 1);
833