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