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