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