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