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 = dst->sa_family; 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; 647 648 if ((sc->gre_options & GRE_UDPENCAP) == 0 || sc->gre_port != 0) 649 return (0); 650 #ifndef RSS 651 switch (af) { 652 #ifdef INET 653 case AF_INET: 654 flowid = mtod(m, struct ip *)->ip_src.s_addr ^ 655 mtod(m, struct ip *)->ip_dst.s_addr; 656 break; 657 #endif 658 #ifdef INET6 659 case AF_INET6: 660 flowid = mtod(m, struct ip6_hdr *)->ip6_src.s6_addr32[3] ^ 661 mtod(m, struct ip6_hdr *)->ip6_dst.s6_addr32[3]; 662 break; 663 #endif 664 default: 665 flowid = 0; 666 } 667 #else /* RSS */ 668 switch (af) { 669 #ifdef INET 670 case AF_INET: 671 flowid = rss_hash_ip4_2tuple(mtod(m, struct ip *)->ip_src, 672 mtod(m, struct ip *)->ip_dst); 673 break; 674 #endif 675 #ifdef INET6 676 case AF_INET6: 677 flowid = rss_hash_ip6_2tuple( 678 &mtod(m, struct ip6_hdr *)->ip6_src, 679 &mtod(m, struct ip6_hdr *)->ip6_dst); 680 break; 681 #endif 682 default: 683 flowid = 0; 684 } 685 #endif 686 return (flowid); 687 } 688 689 #define MTAG_GRE 1307983903 690 static int 691 gre_transmit(struct ifnet *ifp, struct mbuf *m) 692 { 693 GRE_RLOCK_TRACKER; 694 struct gre_softc *sc; 695 struct grehdr *gh; 696 struct udphdr *uh; 697 uint32_t af, flowid; 698 int error, len; 699 uint16_t proto; 700 701 len = 0; 702 GRE_RLOCK(); 703 #ifdef MAC 704 error = mac_ifnet_check_transmit(ifp, m); 705 if (error) { 706 m_freem(m); 707 goto drop; 708 } 709 #endif 710 error = ENETDOWN; 711 sc = ifp->if_softc; 712 if ((ifp->if_flags & IFF_MONITOR) != 0 || 713 (ifp->if_flags & IFF_UP) == 0 || 714 (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 715 sc->gre_family == 0 || 716 (error = if_tunnel_check_nesting(ifp, m, MTAG_GRE, 717 V_max_gre_nesting)) != 0) { 718 m_freem(m); 719 goto drop; 720 } 721 af = m->m_pkthdr.csum_data; 722 BPF_MTAP2(ifp, &af, sizeof(af), m); 723 m->m_flags &= ~(M_BCAST|M_MCAST); 724 flowid = gre_flowid(sc, m, af); 725 M_SETFIB(m, sc->gre_fibnum); 726 M_PREPEND(m, sc->gre_hlen, M_NOWAIT); 727 if (m == NULL) { 728 error = ENOBUFS; 729 goto drop; 730 } 731 bcopy(sc->gre_hdr, mtod(m, void *), sc->gre_hlen); 732 /* Determine GRE proto */ 733 switch (af) { 734 #ifdef INET 735 case AF_INET: 736 proto = htons(ETHERTYPE_IP); 737 break; 738 #endif 739 #ifdef INET6 740 case AF_INET6: 741 proto = htons(ETHERTYPE_IPV6); 742 break; 743 #endif 744 default: 745 m_freem(m); 746 error = ENETDOWN; 747 goto drop; 748 } 749 /* Determine offset of GRE header */ 750 switch (sc->gre_family) { 751 #ifdef INET 752 case AF_INET: 753 len = sizeof(struct ip); 754 break; 755 #endif 756 #ifdef INET6 757 case AF_INET6: 758 len = sizeof(struct ip6_hdr); 759 break; 760 #endif 761 default: 762 m_freem(m); 763 error = ENETDOWN; 764 goto drop; 765 } 766 if (sc->gre_options & GRE_UDPENCAP) { 767 uh = (struct udphdr *)mtodo(m, len); 768 uh->uh_sport |= htons(V_ipport_hifirstauto) | 769 (flowid >> 16) | (flowid & 0xFFFF); 770 uh->uh_sport = htons(ntohs(uh->uh_sport) % 771 V_ipport_hilastauto); 772 uh->uh_ulen = htons(m->m_pkthdr.len - len); 773 uh->uh_sum = gre_cksum_add(uh->uh_sum, 774 htons(m->m_pkthdr.len - len + IPPROTO_UDP)); 775 m->m_pkthdr.csum_flags = sc->gre_csumflags; 776 m->m_pkthdr.csum_data = offsetof(struct udphdr, uh_sum); 777 len += sizeof(struct udphdr); 778 } 779 gh = (struct grehdr *)mtodo(m, len); 780 gh->gre_proto = proto; 781 if (sc->gre_options & GRE_ENABLE_SEQ) 782 gre_setseqn(gh, sc->gre_oseq++); 783 if (sc->gre_options & GRE_ENABLE_CSUM) { 784 *(uint16_t *)gh->gre_opts = in_cksum_skip(m, 785 m->m_pkthdr.len, len); 786 } 787 len = m->m_pkthdr.len - len; 788 switch (sc->gre_family) { 789 #ifdef INET 790 case AF_INET: 791 error = in_gre_output(m, af, sc->gre_hlen); 792 break; 793 #endif 794 #ifdef INET6 795 case AF_INET6: 796 error = in6_gre_output(m, af, sc->gre_hlen, flowid); 797 break; 798 #endif 799 default: 800 m_freem(m); 801 error = ENETDOWN; 802 } 803 drop: 804 if (error) 805 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 806 else { 807 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 808 if_inc_counter(ifp, IFCOUNTER_OBYTES, len); 809 } 810 GRE_RUNLOCK(); 811 return (error); 812 } 813 814 static void 815 gre_qflush(struct ifnet *ifp __unused) 816 { 817 818 } 819 820 static int 821 gremodevent(module_t mod, int type, void *data) 822 { 823 824 switch (type) { 825 case MOD_LOAD: 826 case MOD_UNLOAD: 827 break; 828 default: 829 return (EOPNOTSUPP); 830 } 831 return (0); 832 } 833 834 static moduledata_t gre_mod = { 835 "if_gre", 836 gremodevent, 837 0 838 }; 839 840 DECLARE_MODULE(if_gre, gre_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 841 MODULE_VERSION(if_gre, 1); 842