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