1 /* $FreeBSD$ */ 2 /* $KAME: if_gif.c,v 1.87 2001/10/19 08:50:27 itojun Exp $ */ 3 4 /*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. Neither the name of the project nor the names of its contributors 17 * may be used to endorse or promote products derived from this software 18 * without specific prior written permission. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #include "opt_inet.h" 34 #include "opt_inet6.h" 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/jail.h> 39 #include <sys/kernel.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/module.h> 43 #include <sys/socket.h> 44 #include <sys/sockio.h> 45 #include <sys/errno.h> 46 #include <sys/time.h> 47 #include <sys/sysctl.h> 48 #include <sys/syslog.h> 49 #include <sys/priv.h> 50 #include <sys/proc.h> 51 #include <sys/protosw.h> 52 #include <sys/conf.h> 53 #include <machine/cpu.h> 54 55 #include <net/if.h> 56 #include <net/if_var.h> 57 #include <net/if_clone.h> 58 #include <net/if_types.h> 59 #include <net/netisr.h> 60 #include <net/route.h> 61 #include <net/bpf.h> 62 #include <net/vnet.h> 63 64 #include <netinet/in.h> 65 #include <netinet/in_systm.h> 66 #include <netinet/ip.h> 67 #ifdef INET 68 #include <netinet/in_var.h> 69 #include <netinet/in_gif.h> 70 #include <netinet/ip_var.h> 71 #endif /* INET */ 72 73 #ifdef INET6 74 #ifndef INET 75 #include <netinet/in.h> 76 #endif 77 #include <netinet6/in6_var.h> 78 #include <netinet/ip6.h> 79 #include <netinet6/ip6_var.h> 80 #include <netinet6/scope6_var.h> 81 #include <netinet6/in6_gif.h> 82 #include <netinet6/ip6protosw.h> 83 #endif /* INET6 */ 84 85 #include <netinet/ip_encap.h> 86 #include <net/ethernet.h> 87 #include <net/if_bridgevar.h> 88 #include <net/if_gif.h> 89 90 #include <security/mac/mac_framework.h> 91 92 static const char gifname[] = "gif"; 93 94 /* 95 * gif_mtx protects the global gif_softc_list. 96 */ 97 static struct mtx gif_mtx; 98 static MALLOC_DEFINE(M_GIF, "gif", "Generic Tunnel Interface"); 99 static VNET_DEFINE(LIST_HEAD(, gif_softc), gif_softc_list); 100 #define V_gif_softc_list VNET(gif_softc_list) 101 102 void (*ng_gif_input_p)(struct ifnet *ifp, struct mbuf **mp, int af); 103 void (*ng_gif_input_orphan_p)(struct ifnet *ifp, struct mbuf *m, int af); 104 void (*ng_gif_attach_p)(struct ifnet *ifp); 105 void (*ng_gif_detach_p)(struct ifnet *ifp); 106 107 static void gif_start(struct ifnet *); 108 static int gif_clone_create(struct if_clone *, int, caddr_t); 109 static void gif_clone_destroy(struct ifnet *); 110 static struct if_clone *gif_cloner; 111 112 static int gifmodevent(module_t, int, void *); 113 114 SYSCTL_DECL(_net_link); 115 static SYSCTL_NODE(_net_link, IFT_GIF, gif, CTLFLAG_RW, 0, 116 "Generic Tunnel Interface"); 117 #ifndef MAX_GIF_NEST 118 /* 119 * This macro controls the default upper limitation on nesting of gif tunnels. 120 * Since, setting a large value to this macro with a careless configuration 121 * may introduce system crash, we don't allow any nestings by default. 122 * If you need to configure nested gif tunnels, you can define this macro 123 * in your kernel configuration file. However, if you do so, please be 124 * careful to configure the tunnels so that it won't make a loop. 125 */ 126 #define MAX_GIF_NEST 1 127 #endif 128 static VNET_DEFINE(int, max_gif_nesting) = MAX_GIF_NEST; 129 #define V_max_gif_nesting VNET(max_gif_nesting) 130 SYSCTL_VNET_INT(_net_link_gif, OID_AUTO, max_nesting, CTLFLAG_RW, 131 &VNET_NAME(max_gif_nesting), 0, "Max nested tunnels"); 132 133 /* 134 * By default, we disallow creation of multiple tunnels between the same 135 * pair of addresses. Some applications require this functionality so 136 * we allow control over this check here. 137 */ 138 #ifdef XBONEHACK 139 static VNET_DEFINE(int, parallel_tunnels) = 1; 140 #else 141 static VNET_DEFINE(int, parallel_tunnels) = 0; 142 #endif 143 #define V_parallel_tunnels VNET(parallel_tunnels) 144 SYSCTL_VNET_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW, 145 &VNET_NAME(parallel_tunnels), 0, "Allow parallel tunnels?"); 146 147 /* copy from src/sys/net/if_ethersubr.c */ 148 static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] = 149 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 150 #ifndef ETHER_IS_BROADCAST 151 #define ETHER_IS_BROADCAST(addr) \ 152 (bcmp(etherbroadcastaddr, (addr), ETHER_ADDR_LEN) == 0) 153 #endif 154 155 static int 156 gif_clone_create(struct if_clone *ifc, int unit, caddr_t params) 157 { 158 struct gif_softc *sc; 159 160 sc = malloc(sizeof(struct gif_softc), M_GIF, M_WAITOK | M_ZERO); 161 sc->gif_fibnum = curthread->td_proc->p_fibnum; 162 GIF2IFP(sc) = if_alloc(IFT_GIF); 163 if (GIF2IFP(sc) == NULL) { 164 free(sc, M_GIF); 165 return (ENOSPC); 166 } 167 168 GIF_LOCK_INIT(sc); 169 170 GIF2IFP(sc)->if_softc = sc; 171 if_initname(GIF2IFP(sc), gifname, unit); 172 173 sc->encap_cookie4 = sc->encap_cookie6 = NULL; 174 sc->gif_options = 0; 175 176 GIF2IFP(sc)->if_addrlen = 0; 177 GIF2IFP(sc)->if_mtu = GIF_MTU; 178 GIF2IFP(sc)->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 179 #if 0 180 /* turn off ingress filter */ 181 GIF2IFP(sc)->if_flags |= IFF_LINK2; 182 #endif 183 GIF2IFP(sc)->if_ioctl = gif_ioctl; 184 GIF2IFP(sc)->if_start = gif_start; 185 GIF2IFP(sc)->if_output = gif_output; 186 GIF2IFP(sc)->if_snd.ifq_maxlen = ifqmaxlen; 187 if_attach(GIF2IFP(sc)); 188 bpfattach(GIF2IFP(sc), DLT_NULL, sizeof(u_int32_t)); 189 if (ng_gif_attach_p != NULL) 190 (*ng_gif_attach_p)(GIF2IFP(sc)); 191 192 mtx_lock(&gif_mtx); 193 LIST_INSERT_HEAD(&V_gif_softc_list, sc, gif_list); 194 mtx_unlock(&gif_mtx); 195 196 return (0); 197 } 198 199 static void 200 gif_clone_destroy(struct ifnet *ifp) 201 { 202 #if defined(INET) || defined(INET6) 203 int err; 204 #endif 205 struct gif_softc *sc = ifp->if_softc; 206 207 mtx_lock(&gif_mtx); 208 LIST_REMOVE(sc, gif_list); 209 mtx_unlock(&gif_mtx); 210 211 gif_delete_tunnel(ifp); 212 #ifdef INET6 213 if (sc->encap_cookie6 != NULL) { 214 err = encap_detach(sc->encap_cookie6); 215 KASSERT(err == 0, ("Unexpected error detaching encap_cookie6")); 216 } 217 #endif 218 #ifdef INET 219 if (sc->encap_cookie4 != NULL) { 220 err = encap_detach(sc->encap_cookie4); 221 KASSERT(err == 0, ("Unexpected error detaching encap_cookie4")); 222 } 223 #endif 224 225 if (ng_gif_detach_p != NULL) 226 (*ng_gif_detach_p)(ifp); 227 bpfdetach(ifp); 228 if_detach(ifp); 229 if_free(ifp); 230 231 GIF_LOCK_DESTROY(sc); 232 233 free(sc, M_GIF); 234 } 235 236 static void 237 vnet_gif_init(const void *unused __unused) 238 { 239 240 LIST_INIT(&V_gif_softc_list); 241 } 242 VNET_SYSINIT(vnet_gif_init, SI_SUB_PSEUDO, SI_ORDER_MIDDLE, vnet_gif_init, 243 NULL); 244 245 static int 246 gifmodevent(module_t mod, int type, void *data) 247 { 248 249 switch (type) { 250 case MOD_LOAD: 251 mtx_init(&gif_mtx, "gif_mtx", NULL, MTX_DEF); 252 gif_cloner = if_clone_simple(gifname, gif_clone_create, 253 gif_clone_destroy, 0); 254 break; 255 256 case MOD_UNLOAD: 257 if_clone_detach(gif_cloner); 258 mtx_destroy(&gif_mtx); 259 break; 260 default: 261 return EOPNOTSUPP; 262 } 263 return 0; 264 } 265 266 static moduledata_t gif_mod = { 267 "if_gif", 268 gifmodevent, 269 0 270 }; 271 272 DECLARE_MODULE(if_gif, gif_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 273 MODULE_VERSION(if_gif, 1); 274 275 int 276 gif_encapcheck(const struct mbuf *m, int off, int proto, void *arg) 277 { 278 struct ip ip; 279 struct gif_softc *sc; 280 281 sc = (struct gif_softc *)arg; 282 if (sc == NULL) 283 return 0; 284 285 if ((GIF2IFP(sc)->if_flags & IFF_UP) == 0) 286 return 0; 287 288 /* no physical address */ 289 if (!sc->gif_psrc || !sc->gif_pdst) 290 return 0; 291 292 switch (proto) { 293 #ifdef INET 294 case IPPROTO_IPV4: 295 break; 296 #endif 297 #ifdef INET6 298 case IPPROTO_IPV6: 299 break; 300 #endif 301 case IPPROTO_ETHERIP: 302 break; 303 304 default: 305 return 0; 306 } 307 308 /* Bail on short packets */ 309 if (m->m_pkthdr.len < sizeof(ip)) 310 return 0; 311 312 m_copydata(m, 0, sizeof(ip), (caddr_t)&ip); 313 314 switch (ip.ip_v) { 315 #ifdef INET 316 case 4: 317 if (sc->gif_psrc->sa_family != AF_INET || 318 sc->gif_pdst->sa_family != AF_INET) 319 return 0; 320 return gif_encapcheck4(m, off, proto, arg); 321 #endif 322 #ifdef INET6 323 case 6: 324 if (m->m_pkthdr.len < sizeof(struct ip6_hdr)) 325 return 0; 326 if (sc->gif_psrc->sa_family != AF_INET6 || 327 sc->gif_pdst->sa_family != AF_INET6) 328 return 0; 329 return gif_encapcheck6(m, off, proto, arg); 330 #endif 331 default: 332 return 0; 333 } 334 } 335 #ifdef INET 336 #define GIF_HDR_LEN (ETHER_HDR_LEN + sizeof (struct ip)) 337 #endif 338 #ifdef INET6 339 #define GIF_HDR_LEN6 (ETHER_HDR_LEN + sizeof (struct ip6_hdr)) 340 #endif 341 342 static void 343 gif_start(struct ifnet *ifp) 344 { 345 struct gif_softc *sc; 346 struct mbuf *m; 347 uint32_t af; 348 int error = 0; 349 350 sc = ifp->if_softc; 351 GIF_LOCK(sc); 352 ifp->if_drv_flags |= IFF_DRV_OACTIVE; 353 while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) { 354 355 IFQ_DRV_DEQUEUE(&ifp->if_snd, m); 356 if (m == 0) 357 break; 358 359 #ifdef ALTQ 360 /* Take out those altq bytes we add in gif_output */ 361 #ifdef INET 362 if (sc->gif_psrc->sa_family == AF_INET) 363 m->m_pkthdr.len -= GIF_HDR_LEN; 364 #endif 365 #ifdef INET6 366 if (sc->gif_psrc->sa_family == AF_INET6) 367 m->m_pkthdr.len -= GIF_HDR_LEN6; 368 #endif 369 #endif 370 /* 371 * Now pull back the af that we 372 * stashed in the csum_data. 373 */ 374 af = m->m_pkthdr.csum_data; 375 376 if (ifp->if_bridge) 377 af = AF_LINK; 378 379 BPF_MTAP2(ifp, &af, sizeof(af), m); 380 ifp->if_opackets++; 381 382 /* Done by IFQ_HANDOFF */ 383 /* ifp->if_obytes += m->m_pkthdr.len;*/ 384 /* override to IPPROTO_ETHERIP for bridged traffic */ 385 386 M_SETFIB(m, sc->gif_fibnum); 387 /* inner AF-specific encapsulation */ 388 /* XXX should we check if our outer source is legal? */ 389 /* dispatch to output logic based on outer AF */ 390 switch (sc->gif_psrc->sa_family) { 391 #ifdef INET 392 case AF_INET: 393 error = in_gif_output(ifp, af, m); 394 break; 395 #endif 396 #ifdef INET6 397 case AF_INET6: 398 error = in6_gif_output(ifp, af, m); 399 break; 400 #endif 401 default: 402 m_freem(m); 403 error = ENETDOWN; 404 } 405 if (error) 406 ifp->if_oerrors++; 407 408 } 409 ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; 410 GIF_UNLOCK(sc); 411 return; 412 } 413 414 int 415 gif_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 416 struct route *ro) 417 { 418 struct gif_softc *sc = ifp->if_softc; 419 struct m_tag *mtag; 420 int error = 0; 421 int gif_called; 422 uint32_t af; 423 #ifdef MAC 424 error = mac_ifnet_check_transmit(ifp, m); 425 if (error) { 426 m_freem(m); 427 goto end; 428 } 429 #endif 430 if ((ifp->if_flags & IFF_MONITOR) != 0) { 431 error = ENETDOWN; 432 m_freem(m); 433 goto end; 434 } 435 436 /* 437 * gif may cause infinite recursion calls when misconfigured. 438 * We'll prevent this by detecting loops. 439 * 440 * High nesting level may cause stack exhaustion. 441 * We'll prevent this by introducing upper limit. 442 */ 443 gif_called = 1; 444 mtag = m_tag_locate(m, MTAG_GIF, MTAG_GIF_CALLED, NULL); 445 while (mtag != NULL) { 446 if (*(struct ifnet **)(mtag + 1) == ifp) { 447 log(LOG_NOTICE, 448 "gif_output: loop detected on %s\n", 449 (*(struct ifnet **)(mtag + 1))->if_xname); 450 m_freem(m); 451 error = EIO; /* is there better errno? */ 452 goto end; 453 } 454 mtag = m_tag_locate(m, MTAG_GIF, MTAG_GIF_CALLED, mtag); 455 gif_called++; 456 } 457 if (gif_called > V_max_gif_nesting) { 458 log(LOG_NOTICE, 459 "gif_output: recursively called too many times(%d)\n", 460 gif_called); 461 m_freem(m); 462 error = EIO; /* is there better errno? */ 463 goto end; 464 } 465 mtag = m_tag_alloc(MTAG_GIF, MTAG_GIF_CALLED, sizeof(struct ifnet *), 466 M_NOWAIT); 467 if (mtag == NULL) { 468 m_freem(m); 469 error = ENOMEM; 470 goto end; 471 } 472 *(struct ifnet **)(mtag + 1) = ifp; 473 m_tag_prepend(m, mtag); 474 475 m->m_flags &= ~(M_BCAST|M_MCAST); 476 /* BPF writes need to be handled specially. */ 477 if (dst->sa_family == AF_UNSPEC) 478 bcopy(dst->sa_data, &af, sizeof(af)); 479 else 480 af = dst->sa_family; 481 /* 482 * Now save the af in the inbound pkt csum 483 * data, this is a cheat since we are using 484 * the inbound csum_data field to carry the 485 * af over to the gif_start() routine, avoiding 486 * using yet another mtag. 487 */ 488 m->m_pkthdr.csum_data = af; 489 if (!(ifp->if_flags & IFF_UP) || 490 sc->gif_psrc == NULL || sc->gif_pdst == NULL) { 491 m_freem(m); 492 error = ENETDOWN; 493 goto end; 494 } 495 #ifdef ALTQ 496 /* 497 * Make altq aware of the bytes we will add 498 * when we actually send it. 499 */ 500 #ifdef INET 501 if (sc->gif_psrc->sa_family == AF_INET) 502 m->m_pkthdr.len += GIF_HDR_LEN; 503 #endif 504 #ifdef INET6 505 if (sc->gif_psrc->sa_family == AF_INET6) 506 m->m_pkthdr.len += GIF_HDR_LEN6; 507 #endif 508 #endif 509 /* 510 * Queue message on interface, update output statistics if 511 * successful, and start output if interface not yet active. 512 */ 513 IFQ_HANDOFF(ifp, m, error); 514 end: 515 if (error) 516 ifp->if_oerrors++; 517 return (error); 518 } 519 520 void 521 gif_input(struct mbuf *m, int af, struct ifnet *ifp) 522 { 523 int isr, n; 524 struct gif_softc *sc; 525 struct etherip_header *eip; 526 struct ether_header *eh; 527 struct ifnet *oldifp; 528 529 if (ifp == NULL) { 530 /* just in case */ 531 m_freem(m); 532 return; 533 } 534 sc = ifp->if_softc; 535 m->m_pkthdr.rcvif = ifp; 536 537 #ifdef MAC 538 mac_ifnet_create_mbuf(ifp, m); 539 #endif 540 541 if (bpf_peers_present(ifp->if_bpf)) { 542 u_int32_t af1 = af; 543 bpf_mtap2(ifp->if_bpf, &af1, sizeof(af1), m); 544 } 545 546 if ((ifp->if_flags & IFF_MONITOR) != 0) { 547 ifp->if_ipackets++; 548 ifp->if_ibytes += m->m_pkthdr.len; 549 m_freem(m); 550 return; 551 } 552 553 if (ng_gif_input_p != NULL) { 554 (*ng_gif_input_p)(ifp, &m, af); 555 if (m == NULL) 556 return; 557 } 558 559 /* 560 * Put the packet to the network layer input queue according to the 561 * specified address family. 562 * Note: older versions of gif_input directly called network layer 563 * input functions, e.g. ip6_input, here. We changed the policy to 564 * prevent too many recursive calls of such input functions, which 565 * might cause kernel panic. But the change may introduce another 566 * problem; if the input queue is full, packets are discarded. 567 * The kernel stack overflow really happened, and we believed 568 * queue-full rarely occurs, so we changed the policy. 569 */ 570 switch (af) { 571 #ifdef INET 572 case AF_INET: 573 isr = NETISR_IP; 574 break; 575 #endif 576 #ifdef INET6 577 case AF_INET6: 578 isr = NETISR_IPV6; 579 break; 580 #endif 581 case AF_LINK: 582 n = sizeof(struct etherip_header) + sizeof(struct ether_header); 583 if (n > m->m_len) { 584 m = m_pullup(m, n); 585 if (m == NULL) { 586 ifp->if_ierrors++; 587 return; 588 } 589 } 590 591 eip = mtod(m, struct etherip_header *); 592 /* 593 * GIF_ACCEPT_REVETHIP (enabled by default) intentionally 594 * accepts an EtherIP packet with revered version field in 595 * the header. This is a knob for backward compatibility 596 * with FreeBSD 7.2R or prior. 597 */ 598 if (sc->gif_options & GIF_ACCEPT_REVETHIP) { 599 if (eip->eip_resvl != ETHERIP_VERSION 600 && eip->eip_ver != ETHERIP_VERSION) { 601 /* discard unknown versions */ 602 m_freem(m); 603 return; 604 } 605 } else { 606 if (eip->eip_ver != ETHERIP_VERSION) { 607 /* discard unknown versions */ 608 m_freem(m); 609 return; 610 } 611 } 612 m_adj(m, sizeof(struct etherip_header)); 613 614 m->m_flags &= ~(M_BCAST|M_MCAST); 615 m->m_pkthdr.rcvif = ifp; 616 617 if (ifp->if_bridge) { 618 oldifp = ifp; 619 eh = mtod(m, struct ether_header *); 620 if (ETHER_IS_MULTICAST(eh->ether_dhost)) { 621 if (ETHER_IS_BROADCAST(eh->ether_dhost)) 622 m->m_flags |= M_BCAST; 623 else 624 m->m_flags |= M_MCAST; 625 ifp->if_imcasts++; 626 } 627 BRIDGE_INPUT(ifp, m); 628 629 if (m != NULL && ifp != oldifp) { 630 /* 631 * The bridge gave us back itself or one of the 632 * members for which the frame is addressed. 633 */ 634 ether_demux(ifp, m); 635 return; 636 } 637 } 638 if (m != NULL) 639 m_freem(m); 640 return; 641 642 default: 643 if (ng_gif_input_orphan_p != NULL) 644 (*ng_gif_input_orphan_p)(ifp, m, af); 645 else 646 m_freem(m); 647 return; 648 } 649 650 ifp->if_ipackets++; 651 ifp->if_ibytes += m->m_pkthdr.len; 652 M_SETFIB(m, ifp->if_fib); 653 netisr_dispatch(isr, m); 654 } 655 656 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */ 657 int 658 gif_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 659 { 660 struct gif_softc *sc = ifp->if_softc; 661 struct ifreq *ifr = (struct ifreq*)data; 662 int error = 0, size; 663 u_int options; 664 struct sockaddr *dst, *src; 665 #ifdef SIOCSIFMTU /* xxx */ 666 u_long mtu; 667 #endif 668 669 switch (cmd) { 670 case SIOCSIFADDR: 671 ifp->if_flags |= IFF_UP; 672 break; 673 674 case SIOCADDMULTI: 675 case SIOCDELMULTI: 676 break; 677 678 #ifdef SIOCSIFMTU /* xxx */ 679 case SIOCGIFMTU: 680 break; 681 682 case SIOCSIFMTU: 683 mtu = ifr->ifr_mtu; 684 if (mtu < GIF_MTU_MIN || mtu > GIF_MTU_MAX) 685 return (EINVAL); 686 ifp->if_mtu = mtu; 687 break; 688 #endif /* SIOCSIFMTU */ 689 690 #ifdef INET 691 case SIOCSIFPHYADDR: 692 #endif 693 #ifdef INET6 694 case SIOCSIFPHYADDR_IN6: 695 #endif /* INET6 */ 696 switch (cmd) { 697 #ifdef INET 698 case SIOCSIFPHYADDR: 699 src = (struct sockaddr *) 700 &(((struct in_aliasreq *)data)->ifra_addr); 701 dst = (struct sockaddr *) 702 &(((struct in_aliasreq *)data)->ifra_dstaddr); 703 break; 704 #endif 705 #ifdef INET6 706 case SIOCSIFPHYADDR_IN6: 707 src = (struct sockaddr *) 708 &(((struct in6_aliasreq *)data)->ifra_addr); 709 dst = (struct sockaddr *) 710 &(((struct in6_aliasreq *)data)->ifra_dstaddr); 711 break; 712 #endif 713 default: 714 return EINVAL; 715 } 716 717 /* sa_family must be equal */ 718 if (src->sa_family != dst->sa_family) 719 return EINVAL; 720 721 /* validate sa_len */ 722 switch (src->sa_family) { 723 #ifdef INET 724 case AF_INET: 725 if (src->sa_len != sizeof(struct sockaddr_in)) 726 return EINVAL; 727 break; 728 #endif 729 #ifdef INET6 730 case AF_INET6: 731 if (src->sa_len != sizeof(struct sockaddr_in6)) 732 return EINVAL; 733 break; 734 #endif 735 default: 736 return EAFNOSUPPORT; 737 } 738 switch (dst->sa_family) { 739 #ifdef INET 740 case AF_INET: 741 if (dst->sa_len != sizeof(struct sockaddr_in)) 742 return EINVAL; 743 break; 744 #endif 745 #ifdef INET6 746 case AF_INET6: 747 if (dst->sa_len != sizeof(struct sockaddr_in6)) 748 return EINVAL; 749 break; 750 #endif 751 default: 752 return EAFNOSUPPORT; 753 } 754 755 /* check sa_family looks sane for the cmd */ 756 switch (cmd) { 757 case SIOCSIFPHYADDR: 758 if (src->sa_family == AF_INET) 759 break; 760 return EAFNOSUPPORT; 761 #ifdef INET6 762 case SIOCSIFPHYADDR_IN6: 763 if (src->sa_family == AF_INET6) 764 break; 765 return EAFNOSUPPORT; 766 #endif /* INET6 */ 767 } 768 769 error = gif_set_tunnel(GIF2IFP(sc), src, dst); 770 break; 771 772 #ifdef SIOCDIFPHYADDR 773 case SIOCDIFPHYADDR: 774 gif_delete_tunnel(GIF2IFP(sc)); 775 break; 776 #endif 777 778 case SIOCGIFPSRCADDR: 779 #ifdef INET6 780 case SIOCGIFPSRCADDR_IN6: 781 #endif /* INET6 */ 782 if (sc->gif_psrc == NULL) { 783 error = EADDRNOTAVAIL; 784 goto bad; 785 } 786 src = sc->gif_psrc; 787 switch (cmd) { 788 #ifdef INET 789 case SIOCGIFPSRCADDR: 790 dst = &ifr->ifr_addr; 791 size = sizeof(ifr->ifr_addr); 792 break; 793 #endif /* INET */ 794 #ifdef INET6 795 case SIOCGIFPSRCADDR_IN6: 796 dst = (struct sockaddr *) 797 &(((struct in6_ifreq *)data)->ifr_addr); 798 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 799 break; 800 #endif /* INET6 */ 801 default: 802 error = EADDRNOTAVAIL; 803 goto bad; 804 } 805 if (src->sa_len > size) 806 return EINVAL; 807 bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); 808 #ifdef INET6 809 if (dst->sa_family == AF_INET6) { 810 error = sa6_recoverscope((struct sockaddr_in6 *)dst); 811 if (error != 0) 812 return (error); 813 } 814 #endif 815 break; 816 817 case SIOCGIFPDSTADDR: 818 #ifdef INET6 819 case SIOCGIFPDSTADDR_IN6: 820 #endif /* INET6 */ 821 if (sc->gif_pdst == NULL) { 822 error = EADDRNOTAVAIL; 823 goto bad; 824 } 825 src = sc->gif_pdst; 826 switch (cmd) { 827 #ifdef INET 828 case SIOCGIFPDSTADDR: 829 dst = &ifr->ifr_addr; 830 size = sizeof(ifr->ifr_addr); 831 break; 832 #endif /* INET */ 833 #ifdef INET6 834 case SIOCGIFPDSTADDR_IN6: 835 dst = (struct sockaddr *) 836 &(((struct in6_ifreq *)data)->ifr_addr); 837 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 838 break; 839 #endif /* INET6 */ 840 default: 841 error = EADDRNOTAVAIL; 842 goto bad; 843 } 844 if (src->sa_len > size) 845 return EINVAL; 846 error = prison_if(curthread->td_ucred, src); 847 if (error != 0) 848 return (error); 849 error = prison_if(curthread->td_ucred, dst); 850 if (error != 0) 851 return (error); 852 bcopy((caddr_t)src, (caddr_t)dst, src->sa_len); 853 #ifdef INET6 854 if (dst->sa_family == AF_INET6) { 855 error = sa6_recoverscope((struct sockaddr_in6 *)dst); 856 if (error != 0) 857 return (error); 858 } 859 #endif 860 break; 861 862 case SIOCSIFFLAGS: 863 /* if_ioctl() takes care of it */ 864 break; 865 866 case GIFGOPTS: 867 options = sc->gif_options; 868 error = copyout(&options, ifr->ifr_data, 869 sizeof(options)); 870 break; 871 872 case GIFSOPTS: 873 if ((error = priv_check(curthread, PRIV_NET_GIF)) != 0) 874 break; 875 error = copyin(ifr->ifr_data, &options, sizeof(options)); 876 if (error) 877 break; 878 if (options & ~GIF_OPTMASK) 879 error = EINVAL; 880 else 881 sc->gif_options = options; 882 break; 883 884 default: 885 error = EINVAL; 886 break; 887 } 888 bad: 889 return error; 890 } 891 892 /* 893 * XXXRW: There's a general event-ordering issue here: the code to check 894 * if a given tunnel is already present happens before we perform a 895 * potentially blocking setup of the tunnel. This code needs to be 896 * re-ordered so that the check and replacement can be atomic using 897 * a mutex. 898 */ 899 int 900 gif_set_tunnel(struct ifnet *ifp, struct sockaddr *src, struct sockaddr *dst) 901 { 902 struct gif_softc *sc = ifp->if_softc; 903 struct gif_softc *sc2; 904 struct sockaddr *osrc, *odst, *sa; 905 int error = 0; 906 907 mtx_lock(&gif_mtx); 908 LIST_FOREACH(sc2, &V_gif_softc_list, gif_list) { 909 if (sc2 == sc) 910 continue; 911 if (!sc2->gif_pdst || !sc2->gif_psrc) 912 continue; 913 if (sc2->gif_pdst->sa_family != dst->sa_family || 914 sc2->gif_pdst->sa_len != dst->sa_len || 915 sc2->gif_psrc->sa_family != src->sa_family || 916 sc2->gif_psrc->sa_len != src->sa_len) 917 continue; 918 919 /* 920 * Disallow parallel tunnels unless instructed 921 * otherwise. 922 */ 923 if (!V_parallel_tunnels && 924 bcmp(sc2->gif_pdst, dst, dst->sa_len) == 0 && 925 bcmp(sc2->gif_psrc, src, src->sa_len) == 0) { 926 error = EADDRNOTAVAIL; 927 mtx_unlock(&gif_mtx); 928 goto bad; 929 } 930 931 /* XXX both end must be valid? (I mean, not 0.0.0.0) */ 932 } 933 mtx_unlock(&gif_mtx); 934 935 /* XXX we can detach from both, but be polite just in case */ 936 if (sc->gif_psrc) 937 switch (sc->gif_psrc->sa_family) { 938 #ifdef INET 939 case AF_INET: 940 (void)in_gif_detach(sc); 941 break; 942 #endif 943 #ifdef INET6 944 case AF_INET6: 945 (void)in6_gif_detach(sc); 946 break; 947 #endif 948 } 949 950 osrc = sc->gif_psrc; 951 sa = (struct sockaddr *)malloc(src->sa_len, M_IFADDR, M_WAITOK); 952 bcopy((caddr_t)src, (caddr_t)sa, src->sa_len); 953 sc->gif_psrc = sa; 954 955 odst = sc->gif_pdst; 956 sa = (struct sockaddr *)malloc(dst->sa_len, M_IFADDR, M_WAITOK); 957 bcopy((caddr_t)dst, (caddr_t)sa, dst->sa_len); 958 sc->gif_pdst = sa; 959 960 switch (sc->gif_psrc->sa_family) { 961 #ifdef INET 962 case AF_INET: 963 error = in_gif_attach(sc); 964 break; 965 #endif 966 #ifdef INET6 967 case AF_INET6: 968 /* 969 * Check validity of the scope zone ID of the addresses, and 970 * convert it into the kernel internal form if necessary. 971 */ 972 error = sa6_embedscope((struct sockaddr_in6 *)sc->gif_psrc, 0); 973 if (error != 0) 974 break; 975 error = sa6_embedscope((struct sockaddr_in6 *)sc->gif_pdst, 0); 976 if (error != 0) 977 break; 978 error = in6_gif_attach(sc); 979 break; 980 #endif 981 } 982 if (error) { 983 /* rollback */ 984 free((caddr_t)sc->gif_psrc, M_IFADDR); 985 free((caddr_t)sc->gif_pdst, M_IFADDR); 986 sc->gif_psrc = osrc; 987 sc->gif_pdst = odst; 988 goto bad; 989 } 990 991 if (osrc) 992 free((caddr_t)osrc, M_IFADDR); 993 if (odst) 994 free((caddr_t)odst, M_IFADDR); 995 996 bad: 997 if (sc->gif_psrc && sc->gif_pdst) 998 ifp->if_drv_flags |= IFF_DRV_RUNNING; 999 else 1000 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1001 1002 return error; 1003 } 1004 1005 void 1006 gif_delete_tunnel(struct ifnet *ifp) 1007 { 1008 struct gif_softc *sc = ifp->if_softc; 1009 1010 if (sc->gif_psrc) { 1011 free((caddr_t)sc->gif_psrc, M_IFADDR); 1012 sc->gif_psrc = NULL; 1013 } 1014 if (sc->gif_pdst) { 1015 free((caddr_t)sc->gif_pdst, M_IFADDR); 1016 sc->gif_pdst = NULL; 1017 } 1018 /* it is safe to detach from both */ 1019 #ifdef INET 1020 (void)in_gif_detach(sc); 1021 #endif 1022 #ifdef INET6 1023 (void)in6_gif_detach(sc); 1024 #endif 1025 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1026 } 1027