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 98 static const char grename[] = "gre"; 99 MALLOC_DEFINE(M_GRE, grename, "Generic Routing Encapsulation"); 100 101 static struct sx gre_ioctl_sx; 102 SX_SYSINIT(gre_ioctl_sx, &gre_ioctl_sx, "gre_ioctl"); 103 104 static int gre_clone_create(struct if_clone *, int, caddr_t); 105 static void gre_clone_destroy(struct ifnet *); 106 VNET_DEFINE_STATIC(struct if_clone *, gre_cloner); 107 #define V_gre_cloner VNET(gre_cloner) 108 109 #ifdef VIMAGE 110 static void gre_reassign(struct ifnet *, struct vnet *, char *); 111 #endif 112 static void gre_qflush(struct ifnet *); 113 static int gre_transmit(struct ifnet *, struct mbuf *); 114 static int gre_ioctl(struct ifnet *, u_long, caddr_t); 115 static int gre_output(struct ifnet *, struct mbuf *, 116 const struct sockaddr *, struct route *); 117 static void gre_delete_tunnel(struct gre_softc *); 118 119 SYSCTL_DECL(_net_link); 120 static 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 134 VNET_DEFINE_STATIC(int, max_gre_nesting) = MAX_GRE_NEST; 135 #define V_max_gre_nesting VNET(max_gre_nesting) 136 SYSCTL_INT(_net_link_gre, OID_AUTO, max_nesting, CTLFLAG_RW | CTLFLAG_VNET, 137 &VNET_NAME(max_gre_nesting), 0, "Max nested tunnels"); 138 139 static void 140 vnet_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 } 152 VNET_SYSINIT(vnet_gre_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 153 vnet_gre_init, NULL); 154 155 static void 156 vnet_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 } 168 VNET_SYSUNINIT(vnet_gre_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 169 vnet_gre_uninit, NULL); 170 171 static int 172 gre_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 199 static void 200 gre_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 213 static void 214 gre_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 231 static int 232 gre_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 } 390 end: 391 sx_xunlock(&gre_ioctl_sx); 392 return (error); 393 } 394 395 static void 396 gre_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 422 struct gre_list * 423 gre_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 436 void 437 gre_hashdestroy(struct gre_list *hash) 438 { 439 440 free(hash, M_GRE); 441 } 442 443 void 444 gre_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 452 static __inline uint16_t 453 gre_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 461 void 462 gre_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 474 void 475 gre_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 503 int 504 gre_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); 600 drop: 601 if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); 602 m_freem(m); 603 return (IPPROTO_DONE); 604 } 605 606 static int 607 gre_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 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