xref: /freebsd/sys/net/if_gre.c (revision eec4f5c034f649e873396125ec8d39826eb65135)
1  /*-
2   * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
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  __FBSDID("$FreeBSD$");
39  
40  #include "opt_inet.h"
41  #include "opt_inet6.h"
42  #include "opt_rss.h"
43  
44  #include <sys/param.h>
45  #include <sys/kernel.h>
46  #include <sys/lock.h>
47  #include <sys/malloc.h>
48  #include <sys/module.h>
49  #include <sys/mbuf.h>
50  #include <sys/priv.h>
51  #include <sys/proc.h>
52  #include <sys/socket.h>
53  #include <sys/socketvar.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_var.h>
63  #include <net/if_clone.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  #include <netinet/in_pcb.h>
71  #ifdef INET
72  #include <netinet/in_var.h>
73  #include <netinet/ip.h>
74  #include <netinet/ip_var.h>
75  #ifdef RSS
76  #include <netinet/in_rss.h>
77  #endif
78  #endif
79  
80  #ifdef INET6
81  #include <netinet/ip6.h>
82  #include <netinet6/in6_var.h>
83  #include <netinet6/ip6_var.h>
84  #ifdef RSS
85  #include <netinet6/in6_rss.h>
86  #endif
87  #endif
88  
89  #include <netinet/ip_encap.h>
90  #include <netinet/udp.h>
91  #include <net/bpf.h>
92  #include <net/if_gre.h>
93  
94  #include <machine/in_cksum.h>
95  #include <security/mac/mac_framework.h>
96  
97  #define	GREMTU			1476
98  
99  static const char grename[] = "gre";
100  MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation");
101  
102  static struct sx gre_ioctl_sx;
103  SX_SYSINIT(gre_ioctl_sx, &gre_ioctl_sx, "gre_ioctl");
104  
105  static int	gre_clone_create(struct if_clone *, int, caddr_t);
106  static void	gre_clone_destroy(struct ifnet *);
107  VNET_DEFINE_STATIC(struct if_clone *, gre_cloner);
108  #define	V_gre_cloner	VNET(gre_cloner)
109  
110  #ifdef VIMAGE
111  static void	gre_reassign(struct ifnet *, struct vnet *, char *);
112  #endif
113  static void	gre_qflush(struct ifnet *);
114  static int	gre_transmit(struct ifnet *, struct mbuf *);
115  static int	gre_ioctl(struct ifnet *, u_long, caddr_t);
116  static int	gre_output(struct ifnet *, struct mbuf *,
117  		    const struct sockaddr *, struct route *);
118  static void	gre_delete_tunnel(struct gre_softc *);
119  
120  SYSCTL_DECL(_net_link);
121  static SYSCTL_NODE(_net_link, IFT_TUNNEL, gre, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
122      "Generic Routing Encapsulation");
123  #ifndef MAX_GRE_NEST
124  /*
125   * This macro controls the default upper limitation on nesting of gre tunnels.
126   * Since, setting a large value to this macro with a careless configuration
127   * may introduce system crash, we don't allow any nestings by default.
128   * If you need to configure nested gre tunnels, you can define this macro
129   * in your kernel configuration file.  However, if you do so, please be
130   * careful to configure the tunnels so that it won't make a loop.
131   */
132  #define MAX_GRE_NEST 1
133  #endif
134  
135  VNET_DEFINE_STATIC(int, max_gre_nesting) = MAX_GRE_NEST;
136  #define	V_max_gre_nesting	VNET(max_gre_nesting)
137  SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET,
138      &VNET_NAME(max_gre_nesting), 0, "Max nested tunnels");
139  
140  static void
141  vnet_gre_init(const void *unused __unused)
142  {
143  
144  	V_gre_cloner = if_clone_simple(grename, gre_clone_create,
145  	    gre_clone_destroy, 0);
146  #ifdef INET
147  	in_gre_init();
148  #endif
149  #ifdef INET6
150  	in6_gre_init();
151  #endif
152  }
153  VNET_SYSINIT(vnet_gre_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
154      vnet_gre_init, NULL);
155  
156  static void
157  vnet_gre_uninit(const void *unused __unused)
158  {
159  
160  	if_clone_detach(V_gre_cloner);
161  #ifdef INET
162  	in_gre_uninit();
163  #endif
164  #ifdef INET6
165  	in6_gre_uninit();
166  #endif
167  	/* XXX: epoch_call drain */
168  }
169  VNET_SYSUNINIT(vnet_gre_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY,
170      vnet_gre_uninit, NULL);
171  
172  static int
173  gre_clone_create(struct if_clone *ifc, int unit, caddr_t params)
174  {
175  	struct gre_softc *sc;
176  
177  	sc = malloc(sizeof(struct gre_softc), M_GRE, M_WAITOK | M_ZERO);
178  	sc->gre_fibnum = curthread->td_proc->p_fibnum;
179  	GRE2IFP(sc) = if_alloc(IFT_TUNNEL);
180  	GRE2IFP(sc)->if_softc = sc;
181  	if_initname(GRE2IFP(sc), grename, unit);
182  
183  	GRE2IFP(sc)->if_mtu = GREMTU;
184  	GRE2IFP(sc)->if_flags = IFF_POINTOPOINT|IFF_MULTICAST;
185  	GRE2IFP(sc)->if_output = gre_output;
186  	GRE2IFP(sc)->if_ioctl = gre_ioctl;
187  	GRE2IFP(sc)->if_transmit = gre_transmit;
188  	GRE2IFP(sc)->if_qflush = gre_qflush;
189  #ifdef VIMAGE
190  	GRE2IFP(sc)->if_reassign = gre_reassign;
191  #endif
192  	GRE2IFP(sc)->if_capabilities |= IFCAP_LINKSTATE;
193  	GRE2IFP(sc)->if_capenable |= IFCAP_LINKSTATE;
194  	if_attach(GRE2IFP(sc));
195  	bpfattach(GRE2IFP(sc), DLT_NULL, sizeof(u_int32_t));
196  	return (0);
197  }
198  
199  #ifdef VIMAGE
200  static void
201  gre_reassign(struct ifnet *ifp, struct vnet *new_vnet __unused,
202      char *unused __unused)
203  {
204  	struct gre_softc *sc;
205  
206  	sx_xlock(&gre_ioctl_sx);
207  	sc = ifp->if_softc;
208  	if (sc != NULL)
209  		gre_delete_tunnel(sc);
210  	sx_xunlock(&gre_ioctl_sx);
211  }
212  #endif /* VIMAGE */
213  
214  static void
215  gre_clone_destroy(struct ifnet *ifp)
216  {
217  	struct gre_softc *sc;
218  
219  	sx_xlock(&gre_ioctl_sx);
220  	sc = ifp->if_softc;
221  	gre_delete_tunnel(sc);
222  	bpfdetach(ifp);
223  	if_detach(ifp);
224  	ifp->if_softc = NULL;
225  	sx_xunlock(&gre_ioctl_sx);
226  
227  	GRE_WAIT();
228  	if_free(ifp);
229  	free(sc, M_GRE);
230  }
231  
232  static int
233  gre_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
234  {
235  	struct ifreq *ifr = (struct ifreq *)data;
236  	struct gre_softc *sc;
237  	uint32_t opt;
238  	int error;
239  
240  	switch (cmd) {
241  	case SIOCSIFMTU:
242  		 /* XXX: */
243  		if (ifr->ifr_mtu < 576)
244  			return (EINVAL);
245  		ifp->if_mtu = ifr->ifr_mtu;
246  		return (0);
247  	case SIOCSIFADDR:
248  		ifp->if_flags |= IFF_UP;
249  	case SIOCSIFFLAGS:
250  	case SIOCADDMULTI:
251  	case SIOCDELMULTI:
252  		return (0);
253  	case GRESADDRS:
254  	case GRESADDRD:
255  	case GREGADDRS:
256  	case GREGADDRD:
257  	case GRESPROTO:
258  	case GREGPROTO:
259  		return (EOPNOTSUPP);
260  	}
261  	sx_xlock(&gre_ioctl_sx);
262  	sc = ifp->if_softc;
263  	if (sc == NULL) {
264  		error = ENXIO;
265  		goto end;
266  	}
267  	error = 0;
268  	switch (cmd) {
269  	case SIOCDIFPHYADDR:
270  		if (sc->gre_family == 0)
271  			break;
272  		gre_delete_tunnel(sc);
273  		break;
274  #ifdef INET
275  	case SIOCSIFPHYADDR:
276  	case SIOCGIFPSRCADDR:
277  	case SIOCGIFPDSTADDR:
278  		error = in_gre_ioctl(sc, cmd, data);
279  		break;
280  #endif
281  #ifdef INET6
282  	case SIOCSIFPHYADDR_IN6:
283  	case SIOCGIFPSRCADDR_IN6:
284  	case SIOCGIFPDSTADDR_IN6:
285  		error = in6_gre_ioctl(sc, cmd, data);
286  		break;
287  #endif
288  	case SIOCGTUNFIB:
289  		ifr->ifr_fib = sc->gre_fibnum;
290  		break;
291  	case SIOCSTUNFIB:
292  		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
293  			break;
294  		if (ifr->ifr_fib >= rt_numfibs)
295  			error = EINVAL;
296  		else
297  			sc->gre_fibnum = ifr->ifr_fib;
298  		break;
299  	case GRESKEY:
300  	case GRESOPTS:
301  	case GRESPORT:
302  		if ((error = priv_check(curthread, PRIV_NET_GRE)) != 0)
303  			break;
304  		if ((error = copyin(ifr_data_get_ptr(ifr), &opt,
305  		    sizeof(opt))) != 0)
306  			break;
307  		if (cmd == GRESKEY) {
308  			if (sc->gre_key == opt)
309  				break;
310  		} else if (cmd == GRESOPTS) {
311  			if (opt & ~GRE_OPTMASK) {
312  				error = EINVAL;
313  				break;
314  			}
315  			if (sc->gre_options == opt)
316  				break;
317  		} else if (cmd == GRESPORT) {
318  			if (opt != 0 && (opt < V_ipport_hifirstauto ||
319  			    opt > V_ipport_hilastauto)) {
320  				error = EINVAL;
321  				break;
322  			}
323  			if (sc->gre_port == opt)
324  				break;
325  			if ((sc->gre_options & GRE_UDPENCAP) == 0) {
326  				/*
327  				 * UDP encapsulation is not enabled, thus
328  				 * there is no need to reattach softc.
329  				 */
330  				sc->gre_port = opt;
331  				break;
332  			}
333  		}
334  		switch (sc->gre_family) {
335  #ifdef INET
336  		case AF_INET:
337  			error = in_gre_setopts(sc, cmd, opt);
338  			break;
339  #endif
340  #ifdef INET6
341  		case AF_INET6:
342  			error = in6_gre_setopts(sc, cmd, opt);
343  			break;
344  #endif
345  		default:
346  			/*
347  			 * Tunnel is not yet configured.
348  			 * We can just change any parameters.
349  			 */
350  			if (cmd == GRESKEY)
351  				sc->gre_key = opt;
352  			if (cmd == GRESOPTS)
353  				sc->gre_options = opt;
354  			if (cmd == GRESPORT)
355  				sc->gre_port = opt;
356  			break;
357  		}
358  		/*
359  		 * XXX: Do we need to initiate change of interface
360  		 * state here?
361  		 */
362  		break;
363  	case GREGKEY:
364  		error = copyout(&sc->gre_key, ifr_data_get_ptr(ifr),
365  		    sizeof(sc->gre_key));
366  		break;
367  	case GREGOPTS:
368  		error = copyout(&sc->gre_options, ifr_data_get_ptr(ifr),
369  		    sizeof(sc->gre_options));
370  		break;
371  	case GREGPORT:
372  		error = copyout(&sc->gre_port, ifr_data_get_ptr(ifr),
373  		    sizeof(sc->gre_port));
374  		break;
375  	default:
376  		error = EINVAL;
377  		break;
378  	}
379  	if (error == 0 && sc->gre_family != 0) {
380  		if (
381  #ifdef INET
382  		    cmd == SIOCSIFPHYADDR ||
383  #endif
384  #ifdef INET6
385  		    cmd == SIOCSIFPHYADDR_IN6 ||
386  #endif
387  		    0) {
388  			if_link_state_change(ifp, LINK_STATE_UP);
389  		}
390  	}
391  end:
392  	sx_xunlock(&gre_ioctl_sx);
393  	return (error);
394  }
395  
396  static void
397  gre_delete_tunnel(struct gre_softc *sc)
398  {
399  	struct gre_socket *gs;
400  
401  	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
402  	if (sc->gre_family != 0) {
403  		CK_LIST_REMOVE(sc, chain);
404  		CK_LIST_REMOVE(sc, srchash);
405  		GRE_WAIT();
406  		free(sc->gre_hdr, M_GRE);
407  		sc->gre_family = 0;
408  	}
409  	/*
410  	 * If this Tunnel was the last one that could use UDP socket,
411  	 * we should unlink socket from hash table and close it.
412  	 */
413  	if ((gs = sc->gre_so) != NULL && CK_LIST_EMPTY(&gs->list)) {
414  		CK_LIST_REMOVE(gs, chain);
415  		soclose(gs->so);
416  		NET_EPOCH_CALL(gre_sofree, &gs->epoch_ctx);
417  		sc->gre_so = NULL;
418  	}
419  	GRE2IFP(sc)->if_drv_flags &= ~IFF_DRV_RUNNING;
420  	if_link_state_change(GRE2IFP(sc), LINK_STATE_DOWN);
421  }
422  
423  struct gre_list *
424  gre_hashinit(void)
425  {
426  	struct gre_list *hash;
427  	int i;
428  
429  	hash = malloc(sizeof(struct gre_list) * GRE_HASH_SIZE,
430  	    M_GRE, M_WAITOK);
431  	for (i = 0; i < GRE_HASH_SIZE; i++)
432  		CK_LIST_INIT(&hash[i]);
433  
434  	return (hash);
435  }
436  
437  void
438  gre_hashdestroy(struct gre_list *hash)
439  {
440  
441  	free(hash, M_GRE);
442  }
443  
444  void
445  gre_sofree(epoch_context_t ctx)
446  {
447  	struct gre_socket *gs;
448  
449  	gs = __containerof(ctx, struct gre_socket, epoch_ctx);
450  	free(gs, M_GRE);
451  }
452  
453  static __inline uint16_t
454  gre_cksum_add(uint16_t sum, uint16_t a)
455  {
456  	uint16_t res;
457  
458  	res = sum + a;
459  	return (res + (res < a));
460  }
461  
462  void
463  gre_update_udphdr(struct gre_softc *sc, struct udphdr *udp, uint16_t csum)
464  {
465  
466  	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
467  	MPASS(sc->gre_options & GRE_UDPENCAP);
468  
469  	udp->uh_dport = htons(GRE_UDPPORT);
470  	udp->uh_sport = htons(sc->gre_port);
471  	udp->uh_sum = csum;
472  	udp->uh_ulen = 0;
473  }
474  
475  void
476  gre_update_hdr(struct gre_softc *sc, struct grehdr *gh)
477  {
478  	uint32_t *opts;
479  	uint16_t flags;
480  
481  	sx_assert(&gre_ioctl_sx, SA_XLOCKED);
482  
483  	flags = 0;
484  	opts = gh->gre_opts;
485  	if (sc->gre_options & GRE_ENABLE_CSUM) {
486  		flags |= GRE_FLAGS_CP;
487  		sc->gre_hlen += 2 * sizeof(uint16_t);
488  		*opts++ = 0;
489  	}
490  	if (sc->gre_key != 0) {
491  		flags |= GRE_FLAGS_KP;
492  		sc->gre_hlen += sizeof(uint32_t);
493  		*opts++ = htonl(sc->gre_key);
494  	}
495  	if (sc->gre_options & GRE_ENABLE_SEQ) {
496  		flags |= GRE_FLAGS_SP;
497  		sc->gre_hlen += sizeof(uint32_t);
498  		*opts++ = 0;
499  	} else
500  		sc->gre_oseq = 0;
501  	gh->gre_flags = htons(flags);
502  }
503  
504  int
505  gre_input(struct mbuf *m, int off, int proto, void *arg)
506  {
507  	struct gre_softc *sc = arg;
508  	struct grehdr *gh;
509  	struct ifnet *ifp;
510  	uint32_t *opts;
511  #ifdef notyet
512  	uint32_t key;
513  #endif
514  	uint16_t flags;
515  	int hlen, isr, af;
516  
517  	ifp = GRE2IFP(sc);
518  	hlen = off + sizeof(struct grehdr) + 4 * sizeof(uint32_t);
519  	if (m->m_pkthdr.len < hlen)
520  		goto drop;
521  	if (m->m_len < hlen) {
522  		m = m_pullup(m, hlen);
523  		if (m == NULL)
524  			goto drop;
525  	}
526  	gh = (struct grehdr *)mtodo(m, off);
527  	flags = ntohs(gh->gre_flags);
528  	if (flags & ~GRE_FLAGS_MASK)
529  		goto drop;
530  	opts = gh->gre_opts;
531  	hlen = 2 * sizeof(uint16_t);
532  	if (flags & GRE_FLAGS_CP) {
533  		/* reserved1 field must be zero */
534  		if (((uint16_t *)opts)[1] != 0)
535  			goto drop;
536  		if (in_cksum_skip(m, m->m_pkthdr.len, off) != 0)
537  			goto drop;
538  		hlen += 2 * sizeof(uint16_t);
539  		opts++;
540  	}
541  	if (flags & GRE_FLAGS_KP) {
542  #ifdef notyet
543          /*
544           * XXX: The current implementation uses the key only for outgoing
545           * packets. But we can check the key value here, or even in the
546           * encapcheck function.
547           */
548  		key = ntohl(*opts);
549  #endif
550  		hlen += sizeof(uint32_t);
551  		opts++;
552      }
553  #ifdef notyet
554  	} else
555  		key = 0;
556  
557  	if (sc->gre_key != 0 && (key != sc->gre_key || key != 0))
558  		goto drop;
559  #endif
560  	if (flags & GRE_FLAGS_SP) {
561  #ifdef notyet
562  		seq = ntohl(*opts);
563  #endif
564  		hlen += sizeof(uint32_t);
565  	}
566  	switch (ntohs(gh->gre_proto)) {
567  	case ETHERTYPE_WCCP:
568  		/*
569  		 * For WCCP skip an additional 4 bytes if after GRE header
570  		 * doesn't follow an IP header.
571  		 */
572  		if (flags == 0 && (*(uint8_t *)gh->gre_opts & 0xF0) != 0x40)
573  			hlen += sizeof(uint32_t);
574  		/* FALLTHROUGH */
575  	case ETHERTYPE_IP:
576  		isr = NETISR_IP;
577  		af = AF_INET;
578  		break;
579  	case ETHERTYPE_IPV6:
580  		isr = NETISR_IPV6;
581  		af = AF_INET6;
582  		break;
583  	default:
584  		goto drop;
585  	}
586  	m_adj(m, off + hlen);
587  	m_clrprotoflags(m);
588  	m->m_pkthdr.rcvif = ifp;
589  	M_SETFIB(m, ifp->if_fib);
590  #ifdef MAC
591  	mac_ifnet_create_mbuf(ifp, m);
592  #endif
593  	BPF_MTAP2(ifp, &af, sizeof(af), m);
594  	if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
595  	if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);
596  	if ((ifp->if_flags & IFF_MONITOR) != 0)
597  		m_freem(m);
598  	else
599  		netisr_dispatch(isr, m);
600  	return (IPPROTO_DONE);
601  drop:
602  	if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
603  	m_freem(m);
604  	return (IPPROTO_DONE);
605  }
606  
607  static int
608  gre_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst,
609     struct route *ro)
610  {
611  	uint32_t af;
612  
613  	if (dst->sa_family == AF_UNSPEC)
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  
626  static void
627  gre_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  
643  static uint32_t
644  gre_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
681  static int
682  gre_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  	}
794  drop:
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  
805  static void
806  gre_qflush(struct ifnet *ifp __unused)
807  {
808  
809  }
810  
811  static int
812  gremodevent(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  
825  static moduledata_t gre_mod = {
826  	"if_gre",
827  	gremodevent,
828  	0
829  };
830  
831  DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
832  MODULE_VERSION(if_gre, 1);
833