1 /*- 2 * Copyright (c) 2016-2018 Yandex LLC 3 * Copyright (c) 2016-2018 Andrey V. Elsukov <ae@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28 #include <sys/cdefs.h> 29 __FBSDID("$FreeBSD$"); 30 31 #include "opt_inet.h" 32 #include "opt_inet6.h" 33 #include "opt_ipsec.h" 34 35 #include <sys/param.h> 36 #include <sys/systm.h> 37 #include <sys/kernel.h> 38 #include <sys/fnv_hash.h> 39 #include <sys/jail.h> 40 #include <sys/lock.h> 41 #include <sys/malloc.h> 42 #include <sys/mbuf.h> 43 #include <sys/module.h> 44 #include <sys/socket.h> 45 #include <sys/sockio.h> 46 #include <sys/sx.h> 47 #include <sys/errno.h> 48 #include <sys/sysctl.h> 49 #include <sys/priv.h> 50 #include <sys/proc.h> 51 #include <sys/conf.h> 52 53 #include <net/if.h> 54 #include <net/if_var.h> 55 #include <net/if_private.h> 56 #include <net/if_clone.h> 57 #include <net/if_types.h> 58 #include <net/bpf.h> 59 #include <net/route.h> 60 #include <net/vnet.h> 61 62 #include <netinet/in.h> 63 #include <netinet/in_var.h> 64 #include <netinet/ip.h> 65 #include <netinet/ip_encap.h> 66 67 #include <netinet/ip6.h> 68 #include <netinet6/in6_var.h> 69 #include <netinet6/scope6_var.h> 70 71 #include <netipsec/ipsec.h> 72 #ifdef INET6 73 #include <netipsec/ipsec6.h> 74 #endif 75 76 #include <net/if_ipsec.h> 77 #include <netipsec/key.h> 78 79 #include <security/mac/mac_framework.h> 80 81 static MALLOC_DEFINE(M_IPSEC, "ipsec", "IPsec Virtual Tunnel Interface"); 82 static const char ipsecname[] = "ipsec"; 83 84 #if defined(INET) && defined(INET6) 85 #define IPSEC_SPCOUNT 4 86 #else 87 #define IPSEC_SPCOUNT 2 88 #endif 89 90 struct ipsec_softc { 91 struct ifnet *ifp; 92 struct secpolicy *sp[IPSEC_SPCOUNT]; 93 uint32_t reqid; 94 u_int family; 95 u_int fibnum; 96 97 CK_LIST_ENTRY(ipsec_softc) idhash; 98 CK_LIST_ENTRY(ipsec_softc) srchash; 99 }; 100 101 #define IPSEC_RLOCK_TRACKER struct epoch_tracker ipsec_et 102 #define IPSEC_RLOCK() epoch_enter_preempt(net_epoch_preempt, &ipsec_et) 103 #define IPSEC_RUNLOCK() epoch_exit_preempt(net_epoch_preempt, &ipsec_et) 104 #define IPSEC_WAIT() epoch_wait_preempt(net_epoch_preempt) 105 106 #ifndef IPSEC_HASH_SIZE 107 #define IPSEC_HASH_SIZE (1 << 5) 108 #endif 109 110 CK_LIST_HEAD(ipsec_iflist, ipsec_softc); 111 VNET_DEFINE_STATIC(struct ipsec_iflist *, ipsec_idhtbl) = NULL; 112 #define V_ipsec_idhtbl VNET(ipsec_idhtbl) 113 114 #ifdef INET 115 VNET_DEFINE_STATIC(struct ipsec_iflist *, ipsec4_srchtbl) = NULL; 116 #define V_ipsec4_srchtbl VNET(ipsec4_srchtbl) 117 static const struct srcaddrtab *ipsec4_srctab = NULL; 118 #endif 119 120 #ifdef INET6 121 VNET_DEFINE_STATIC(struct ipsec_iflist *, ipsec6_srchtbl) = NULL; 122 #define V_ipsec6_srchtbl VNET(ipsec6_srchtbl) 123 static const struct srcaddrtab *ipsec6_srctab = NULL; 124 #endif 125 126 static struct ipsec_iflist * 127 ipsec_idhash(uint32_t id) 128 { 129 130 return (&V_ipsec_idhtbl[fnv_32_buf(&id, sizeof(id), 131 FNV1_32_INIT) & (IPSEC_HASH_SIZE - 1)]); 132 } 133 134 static struct ipsec_iflist * 135 ipsec_srchash(const struct sockaddr *sa) 136 { 137 uint32_t hval; 138 139 switch (sa->sa_family) { 140 #ifdef INET 141 case AF_INET: 142 hval = fnv_32_buf( 143 &((const struct sockaddr_in *)sa)->sin_addr.s_addr, 144 sizeof(in_addr_t), FNV1_32_INIT); 145 return (&V_ipsec4_srchtbl[hval & (IPSEC_HASH_SIZE - 1)]); 146 #endif 147 #ifdef INET6 148 case AF_INET6: 149 hval = fnv_32_buf( 150 &((const struct sockaddr_in6 *)sa)->sin6_addr, 151 sizeof(struct in6_addr), FNV1_32_INIT); 152 return (&V_ipsec6_srchtbl[hval & (IPSEC_HASH_SIZE - 1)]); 153 #endif 154 } 155 return (NULL); 156 } 157 158 /* 159 * ipsec_ioctl_sx protects from concurrent ioctls. 160 */ 161 static struct sx ipsec_ioctl_sx; 162 SX_SYSINIT(ipsec_ioctl_sx, &ipsec_ioctl_sx, "ipsec_ioctl"); 163 164 static int ipsec_init_reqid(struct ipsec_softc *); 165 static int ipsec_set_tunnel(struct ipsec_softc *, struct sockaddr *, 166 struct sockaddr *, uint32_t); 167 static void ipsec_delete_tunnel(struct ipsec_softc *); 168 169 static int ipsec_set_addresses(struct ifnet *, struct sockaddr *, 170 struct sockaddr *); 171 static int ipsec_set_reqid(struct ipsec_softc *, uint32_t); 172 static void ipsec_set_running(struct ipsec_softc *); 173 174 #ifdef VIMAGE 175 static void ipsec_reassign(struct ifnet *, struct vnet *, char *); 176 #endif 177 static void ipsec_srcaddr(void *, const struct sockaddr *, int); 178 static int ipsec_ioctl(struct ifnet *, u_long, caddr_t); 179 static int ipsec_transmit(struct ifnet *, struct mbuf *); 180 static int ipsec_output(struct ifnet *, struct mbuf *, 181 const struct sockaddr *, struct route *); 182 static void ipsec_qflush(struct ifnet *); 183 static int ipsec_clone_create(struct if_clone *, int, caddr_t); 184 static void ipsec_clone_destroy(struct ifnet *); 185 186 VNET_DEFINE_STATIC(struct if_clone *, ipsec_cloner); 187 #define V_ipsec_cloner VNET(ipsec_cloner) 188 189 static int 190 ipsec_clone_create(struct if_clone *ifc, int unit, caddr_t params) 191 { 192 struct ipsec_softc *sc; 193 struct ifnet *ifp; 194 195 sc = malloc(sizeof(*sc), M_IPSEC, M_WAITOK | M_ZERO); 196 sc->fibnum = curthread->td_proc->p_fibnum; 197 sc->ifp = ifp = if_alloc(IFT_TUNNEL); 198 ifp->if_softc = sc; 199 if_initname(ifp, ipsecname, unit); 200 201 ifp->if_addrlen = 0; 202 ifp->if_mtu = IPSEC_MTU; 203 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 204 ifp->if_ioctl = ipsec_ioctl; 205 ifp->if_transmit = ipsec_transmit; 206 ifp->if_qflush = ipsec_qflush; 207 ifp->if_output = ipsec_output; 208 #ifdef VIMAGE 209 ifp->if_reassign = ipsec_reassign; 210 #endif 211 if_attach(ifp); 212 bpfattach(ifp, DLT_NULL, sizeof(uint32_t)); 213 214 return (0); 215 } 216 217 #ifdef VIMAGE 218 static void 219 ipsec_reassign(struct ifnet *ifp, struct vnet *new_vnet __unused, 220 char *unused __unused) 221 { 222 struct ipsec_softc *sc; 223 224 sx_xlock(&ipsec_ioctl_sx); 225 sc = ifp->if_softc; 226 if (sc != NULL) 227 ipsec_delete_tunnel(sc); 228 sx_xunlock(&ipsec_ioctl_sx); 229 } 230 #endif /* VIMAGE */ 231 232 static void 233 ipsec_clone_destroy(struct ifnet *ifp) 234 { 235 struct ipsec_softc *sc; 236 237 sx_xlock(&ipsec_ioctl_sx); 238 sc = ifp->if_softc; 239 ipsec_delete_tunnel(sc); 240 /* 241 * Delete softc from idhash on interface destroy, since 242 * ipsec_delete_tunnel() keeps reqid unchanged. 243 */ 244 if (sc->reqid != 0) 245 CK_LIST_REMOVE(sc, idhash); 246 bpfdetach(ifp); 247 if_detach(ifp); 248 ifp->if_softc = NULL; 249 sx_xunlock(&ipsec_ioctl_sx); 250 251 IPSEC_WAIT(); 252 if_free(ifp); 253 free(sc, M_IPSEC); 254 } 255 256 static struct ipsec_iflist * 257 ipsec_hashinit(void) 258 { 259 struct ipsec_iflist *hash; 260 int i; 261 262 hash = malloc(sizeof(struct ipsec_iflist) * IPSEC_HASH_SIZE, 263 M_IPSEC, M_WAITOK); 264 for (i = 0; i < IPSEC_HASH_SIZE; i++) 265 CK_LIST_INIT(&hash[i]); 266 267 return (hash); 268 } 269 270 static void 271 vnet_ipsec_init(const void *unused __unused) 272 { 273 274 V_ipsec_idhtbl = ipsec_hashinit(); 275 #ifdef INET 276 V_ipsec4_srchtbl = ipsec_hashinit(); 277 if (IS_DEFAULT_VNET(curvnet)) 278 ipsec4_srctab = ip_encap_register_srcaddr(ipsec_srcaddr, 279 NULL, M_WAITOK); 280 #endif 281 #ifdef INET6 282 V_ipsec6_srchtbl = ipsec_hashinit(); 283 if (IS_DEFAULT_VNET(curvnet)) 284 ipsec6_srctab = ip6_encap_register_srcaddr(ipsec_srcaddr, 285 NULL, M_WAITOK); 286 #endif 287 V_ipsec_cloner = if_clone_simple(ipsecname, ipsec_clone_create, 288 ipsec_clone_destroy, 0); 289 } 290 VNET_SYSINIT(vnet_ipsec_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 291 vnet_ipsec_init, NULL); 292 293 static void 294 vnet_ipsec_uninit(const void *unused __unused) 295 { 296 297 if_clone_detach(V_ipsec_cloner); 298 free(V_ipsec_idhtbl, M_IPSEC); 299 /* 300 * Use V_ipsec_idhtbl pointer as indicator that VNET is going to be 301 * destroyed, it is used by ipsec_srcaddr() callback. 302 */ 303 V_ipsec_idhtbl = NULL; 304 IPSEC_WAIT(); 305 306 #ifdef INET 307 if (IS_DEFAULT_VNET(curvnet)) 308 ip_encap_unregister_srcaddr(ipsec4_srctab); 309 free(V_ipsec4_srchtbl, M_IPSEC); 310 #endif 311 #ifdef INET6 312 if (IS_DEFAULT_VNET(curvnet)) 313 ip6_encap_unregister_srcaddr(ipsec6_srctab); 314 free(V_ipsec6_srchtbl, M_IPSEC); 315 #endif 316 } 317 VNET_SYSUNINIT(vnet_ipsec_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 318 vnet_ipsec_uninit, NULL); 319 320 static struct secpolicy * 321 ipsec_getpolicy(struct ipsec_softc *sc, int dir, sa_family_t af) 322 { 323 324 switch (af) { 325 #ifdef INET 326 case AF_INET: 327 return (sc->sp[(dir == IPSEC_DIR_INBOUND ? 0: 1)]); 328 #endif 329 #ifdef INET6 330 case AF_INET6: 331 return (sc->sp[(dir == IPSEC_DIR_INBOUND ? 0: 1) 332 #ifdef INET 333 + 2 334 #endif 335 ]); 336 #endif 337 } 338 return (NULL); 339 } 340 341 static struct secasindex * 342 ipsec_getsaidx(struct ipsec_softc *sc, int dir, sa_family_t af) 343 { 344 struct secpolicy *sp; 345 346 sp = ipsec_getpolicy(sc, dir, af); 347 if (sp == NULL) 348 return (NULL); 349 return (&sp->req[0]->saidx); 350 } 351 352 static int 353 ipsec_transmit(struct ifnet *ifp, struct mbuf *m) 354 { 355 IPSEC_RLOCK_TRACKER; 356 struct ipsec_softc *sc; 357 struct secpolicy *sp; 358 struct ip *ip; 359 uint32_t af; 360 int error; 361 362 IPSEC_RLOCK(); 363 #ifdef MAC 364 error = mac_ifnet_check_transmit(ifp, m); 365 if (error) { 366 m_freem(m); 367 goto err; 368 } 369 #endif 370 error = ENETDOWN; 371 sc = ifp->if_softc; 372 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 373 (ifp->if_flags & IFF_MONITOR) != 0 || 374 (ifp->if_flags & IFF_UP) == 0 || sc->family == 0) { 375 m_freem(m); 376 goto err; 377 } 378 379 /* Determine address family to correctly handle packet in BPF */ 380 ip = mtod(m, struct ip *); 381 switch (ip->ip_v) { 382 #ifdef INET 383 case IPVERSION: 384 af = AF_INET; 385 break; 386 #endif 387 #ifdef INET6 388 case (IPV6_VERSION >> 4): 389 af = AF_INET6; 390 break; 391 #endif 392 default: 393 error = EAFNOSUPPORT; 394 m_freem(m); 395 goto err; 396 } 397 398 /* 399 * Loop prevention. 400 * XXX: for now just check presence of IPSEC_OUT_DONE mbuf tag. 401 * We can read full chain and compare destination address, 402 * proto and mode from xform_history with values from softc. 403 */ 404 if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) { 405 m_freem(m); 406 goto err; 407 } 408 409 sp = ipsec_getpolicy(sc, IPSEC_DIR_OUTBOUND, af); 410 key_addref(sp); 411 M_SETFIB(m, sc->fibnum); 412 413 BPF_MTAP2(ifp, &af, sizeof(af), m); 414 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 415 if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); 416 417 switch (af) { 418 #ifdef INET 419 case AF_INET: 420 error = ipsec4_process_packet(m, sp, NULL); 421 break; 422 #endif 423 #ifdef INET6 424 case AF_INET6: 425 error = ipsec6_process_packet(m, sp, NULL); 426 break; 427 #endif 428 default: 429 panic("%s: unknown address family\n", __func__); 430 } 431 err: 432 if (error != 0) 433 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 434 IPSEC_RUNLOCK(); 435 return (error); 436 } 437 438 static void 439 ipsec_qflush(struct ifnet *ifp __unused) 440 { 441 442 } 443 444 static int 445 ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 446 struct route *ro) 447 { 448 449 return (ifp->if_transmit(ifp, m)); 450 } 451 452 int 453 ipsec_if_input(struct mbuf *m, struct secasvar *sav, uint32_t af) 454 { 455 IPSEC_RLOCK_TRACKER; 456 struct secasindex *saidx; 457 struct ipsec_softc *sc; 458 struct ifnet *ifp; 459 460 if (sav->state != SADB_SASTATE_MATURE && 461 sav->state != SADB_SASTATE_DYING) { 462 m_freem(m); 463 return (ENETDOWN); 464 } 465 466 if (sav->sah->saidx.mode != IPSEC_MODE_TUNNEL || 467 sav->sah->saidx.proto != IPPROTO_ESP) 468 return (0); 469 470 IPSEC_RLOCK(); 471 CK_LIST_FOREACH(sc, ipsec_idhash(sav->sah->saidx.reqid), idhash) { 472 if (sc->family == 0) 473 continue; 474 saidx = ipsec_getsaidx(sc, IPSEC_DIR_INBOUND, 475 sav->sah->saidx.src.sa.sa_family); 476 /* SA's reqid should match reqid in SP */ 477 if (saidx == NULL || 478 sav->sah->saidx.reqid != saidx->reqid) 479 continue; 480 /* SAH's addresses should match tunnel endpoints. */ 481 if (key_sockaddrcmp(&sav->sah->saidx.dst.sa, 482 &saidx->dst.sa, 0) != 0) 483 continue; 484 if (key_sockaddrcmp(&sav->sah->saidx.src.sa, 485 &saidx->src.sa, 0) == 0) 486 break; 487 } 488 if (sc == NULL) { 489 IPSEC_RUNLOCK(); 490 /* Tunnel was not found. Nothing to do. */ 491 return (0); 492 } 493 ifp = sc->ifp; 494 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 495 (ifp->if_flags & IFF_UP) == 0) { 496 IPSEC_RUNLOCK(); 497 m_freem(m); 498 return (ENETDOWN); 499 } 500 /* 501 * We found matching and working tunnel. 502 * Set its ifnet as receiving interface. 503 */ 504 m->m_pkthdr.rcvif = ifp; 505 506 m_clrprotoflags(m); 507 M_SETFIB(m, ifp->if_fib); 508 BPF_MTAP2(ifp, &af, sizeof(af), m); 509 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 510 if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); 511 if ((ifp->if_flags & IFF_MONITOR) != 0) { 512 IPSEC_RUNLOCK(); 513 m_freem(m); 514 return (ENETDOWN); 515 } 516 IPSEC_RUNLOCK(); 517 return (0); 518 } 519 520 static int 521 ipsec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 522 { 523 struct ifreq *ifr = (struct ifreq*)data; 524 struct sockaddr *dst, *src; 525 struct ipsec_softc *sc; 526 struct secasindex *saidx; 527 #ifdef INET 528 struct sockaddr_in *sin = NULL; 529 #endif 530 #ifdef INET6 531 struct sockaddr_in6 *sin6 = NULL; 532 #endif 533 uint32_t reqid; 534 int error; 535 536 switch (cmd) { 537 case SIOCSIFADDR: 538 ifp->if_flags |= IFF_UP; 539 case SIOCADDMULTI: 540 case SIOCDELMULTI: 541 case SIOCGIFMTU: 542 case SIOCSIFFLAGS: 543 return (0); 544 case SIOCSIFMTU: 545 if (ifr->ifr_mtu < IPSEC_MTU_MIN || 546 ifr->ifr_mtu > IPSEC_MTU_MAX) 547 return (EINVAL); 548 else 549 ifp->if_mtu = ifr->ifr_mtu; 550 return (0); 551 } 552 sx_xlock(&ipsec_ioctl_sx); 553 sc = ifp->if_softc; 554 /* Check that softc is still here */ 555 if (sc == NULL) { 556 error = ENXIO; 557 goto bad; 558 } 559 error = 0; 560 switch (cmd) { 561 case SIOCSIFPHYADDR: 562 #ifdef INET6 563 case SIOCSIFPHYADDR_IN6: 564 #endif 565 error = EINVAL; 566 switch (cmd) { 567 #ifdef INET 568 case SIOCSIFPHYADDR: 569 src = (struct sockaddr *) 570 &(((struct in_aliasreq *)data)->ifra_addr); 571 dst = (struct sockaddr *) 572 &(((struct in_aliasreq *)data)->ifra_dstaddr); 573 break; 574 #endif 575 #ifdef INET6 576 case SIOCSIFPHYADDR_IN6: 577 src = (struct sockaddr *) 578 &(((struct in6_aliasreq *)data)->ifra_addr); 579 dst = (struct sockaddr *) 580 &(((struct in6_aliasreq *)data)->ifra_dstaddr); 581 break; 582 #endif 583 default: 584 goto bad; 585 } 586 /* sa_family must be equal */ 587 if (src->sa_family != dst->sa_family || 588 src->sa_len != dst->sa_len) 589 goto bad; 590 591 /* validate sa_len */ 592 switch (src->sa_family) { 593 #ifdef INET 594 case AF_INET: 595 if (src->sa_len != sizeof(struct sockaddr_in)) 596 goto bad; 597 break; 598 #endif 599 #ifdef INET6 600 case AF_INET6: 601 if (src->sa_len != sizeof(struct sockaddr_in6)) 602 goto bad; 603 break; 604 #endif 605 default: 606 error = EAFNOSUPPORT; 607 goto bad; 608 } 609 /* check sa_family looks sane for the cmd */ 610 error = EAFNOSUPPORT; 611 switch (cmd) { 612 #ifdef INET 613 case SIOCSIFPHYADDR: 614 if (src->sa_family == AF_INET) 615 break; 616 goto bad; 617 #endif 618 #ifdef INET6 619 case SIOCSIFPHYADDR_IN6: 620 if (src->sa_family == AF_INET6) 621 break; 622 goto bad; 623 #endif 624 } 625 error = EADDRNOTAVAIL; 626 switch (src->sa_family) { 627 #ifdef INET 628 case AF_INET: 629 if (satosin(src)->sin_addr.s_addr == INADDR_ANY || 630 satosin(dst)->sin_addr.s_addr == INADDR_ANY) 631 goto bad; 632 break; 633 #endif 634 #ifdef INET6 635 case AF_INET6: 636 if (IN6_IS_ADDR_UNSPECIFIED( 637 &satosin6(src)->sin6_addr) || 638 IN6_IS_ADDR_UNSPECIFIED( 639 &satosin6(dst)->sin6_addr)) 640 goto bad; 641 /* 642 * Check validity of the scope zone ID of the 643 * addresses, and convert it into the kernel 644 * internal form if necessary. 645 */ 646 error = sa6_embedscope(satosin6(src), 0); 647 if (error != 0) 648 goto bad; 649 error = sa6_embedscope(satosin6(dst), 0); 650 if (error != 0) 651 goto bad; 652 #endif 653 }; 654 error = ipsec_set_addresses(ifp, src, dst); 655 break; 656 case SIOCDIFPHYADDR: 657 ipsec_delete_tunnel(sc); 658 break; 659 case SIOCGIFPSRCADDR: 660 case SIOCGIFPDSTADDR: 661 #ifdef INET6 662 case SIOCGIFPSRCADDR_IN6: 663 case SIOCGIFPDSTADDR_IN6: 664 #endif 665 if (sc->family == 0) { 666 error = EADDRNOTAVAIL; 667 break; 668 } 669 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family); 670 if (saidx == NULL) { 671 error = ENXIO; 672 break; 673 } 674 switch (cmd) { 675 #ifdef INET 676 case SIOCGIFPSRCADDR: 677 case SIOCGIFPDSTADDR: 678 if (saidx->src.sa.sa_family != AF_INET) { 679 error = EADDRNOTAVAIL; 680 break; 681 } 682 sin = (struct sockaddr_in *)&ifr->ifr_addr; 683 memset(sin, 0, sizeof(*sin)); 684 sin->sin_family = AF_INET; 685 sin->sin_len = sizeof(*sin); 686 break; 687 #endif 688 #ifdef INET6 689 case SIOCGIFPSRCADDR_IN6: 690 case SIOCGIFPDSTADDR_IN6: 691 if (saidx->src.sa.sa_family != AF_INET6) { 692 error = EADDRNOTAVAIL; 693 break; 694 } 695 sin6 = (struct sockaddr_in6 *) 696 &(((struct in6_ifreq *)data)->ifr_addr); 697 memset(sin6, 0, sizeof(*sin6)); 698 sin6->sin6_family = AF_INET6; 699 sin6->sin6_len = sizeof(*sin6); 700 break; 701 #endif 702 default: 703 error = EAFNOSUPPORT; 704 } 705 if (error == 0) { 706 switch (cmd) { 707 #ifdef INET 708 case SIOCGIFPSRCADDR: 709 sin->sin_addr = saidx->src.sin.sin_addr; 710 break; 711 case SIOCGIFPDSTADDR: 712 sin->sin_addr = saidx->dst.sin.sin_addr; 713 break; 714 #endif 715 #ifdef INET6 716 case SIOCGIFPSRCADDR_IN6: 717 sin6->sin6_addr = saidx->src.sin6.sin6_addr; 718 break; 719 case SIOCGIFPDSTADDR_IN6: 720 sin6->sin6_addr = saidx->dst.sin6.sin6_addr; 721 break; 722 #endif 723 } 724 } 725 if (error != 0) 726 break; 727 switch (cmd) { 728 #ifdef INET 729 case SIOCGIFPSRCADDR: 730 case SIOCGIFPDSTADDR: 731 error = prison_if(curthread->td_ucred, 732 (struct sockaddr *)sin); 733 if (error != 0) 734 memset(sin, 0, sizeof(*sin)); 735 break; 736 #endif 737 #ifdef INET6 738 case SIOCGIFPSRCADDR_IN6: 739 case SIOCGIFPDSTADDR_IN6: 740 error = prison_if(curthread->td_ucred, 741 (struct sockaddr *)sin6); 742 if (error == 0) 743 error = sa6_recoverscope(sin6); 744 if (error != 0) 745 memset(sin6, 0, sizeof(*sin6)); 746 #endif 747 } 748 break; 749 case SIOCGTUNFIB: 750 ifr->ifr_fib = sc->fibnum; 751 break; 752 case SIOCSTUNFIB: 753 if ((error = priv_check(curthread, PRIV_NET_SETIFFIB)) != 0) 754 break; 755 if (ifr->ifr_fib >= rt_numfibs) 756 error = EINVAL; 757 else 758 sc->fibnum = ifr->ifr_fib; 759 break; 760 case IPSECGREQID: 761 reqid = sc->reqid; 762 error = copyout(&reqid, ifr_data_get_ptr(ifr), sizeof(reqid)); 763 break; 764 case IPSECSREQID: 765 if ((error = priv_check(curthread, PRIV_NET_SETIFCAP)) != 0) 766 break; 767 error = copyin(ifr_data_get_ptr(ifr), &reqid, sizeof(reqid)); 768 if (error != 0) 769 break; 770 error = ipsec_set_reqid(sc, reqid); 771 break; 772 default: 773 error = EINVAL; 774 break; 775 } 776 bad: 777 sx_xunlock(&ipsec_ioctl_sx); 778 return (error); 779 } 780 781 /* 782 * Check that ingress address belongs to local host. 783 */ 784 static void 785 ipsec_set_running(struct ipsec_softc *sc) 786 { 787 struct secasindex *saidx; 788 int localip; 789 790 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family); 791 if (saidx == NULL) 792 return; 793 localip = 0; 794 switch (sc->family) { 795 #ifdef INET 796 case AF_INET: 797 localip = in_localip(saidx->src.sin.sin_addr); 798 break; 799 #endif 800 #ifdef INET6 801 case AF_INET6: 802 localip = in6_localip(&saidx->src.sin6.sin6_addr); 803 break; 804 #endif 805 } 806 if (localip != 0) 807 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 808 else 809 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 810 } 811 812 /* 813 * ifaddr_event handler. 814 * Clear IFF_DRV_RUNNING flag when ingress address disappears to prevent 815 * source address spoofing. 816 */ 817 static void 818 ipsec_srcaddr(void *arg __unused, const struct sockaddr *sa, 819 int event __unused) 820 { 821 struct ipsec_softc *sc; 822 struct secasindex *saidx; 823 struct ipsec_iflist *iflist; 824 825 /* Check that VNET is ready */ 826 if (V_ipsec_idhtbl == NULL) 827 return; 828 829 NET_EPOCH_ASSERT(); 830 iflist = ipsec_srchash(sa); 831 if (iflist == NULL) 832 return; 833 CK_LIST_FOREACH(sc, iflist, srchash) { 834 if (sc->family == 0) 835 continue; 836 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sa->sa_family); 837 if (saidx == NULL || 838 key_sockaddrcmp(&saidx->src.sa, sa, 0) != 0) 839 continue; 840 ipsec_set_running(sc); 841 } 842 } 843 844 /* 845 * Allocate new private security policies for tunneling interface. 846 * Each tunneling interface has following security policies for 847 * both AF: 848 * 0.0.0.0/0[any] 0.0.0.0/0[any] -P in \ 849 * ipsec esp/tunnel/RemoteIP-LocalIP/unique:reqid 850 * 0.0.0.0/0[any] 0.0.0.0/0[any] -P out \ 851 * ipsec esp/tunnel/LocalIP-RemoteIP/unique:reqid 852 */ 853 static int 854 ipsec_newpolicies(struct ipsec_softc *sc, struct secpolicy *sp[IPSEC_SPCOUNT], 855 const struct sockaddr *src, const struct sockaddr *dst, uint32_t reqid) 856 { 857 struct ipsecrequest *isr; 858 int i; 859 860 memset(sp, 0, sizeof(struct secpolicy *) * IPSEC_SPCOUNT); 861 for (i = 0; i < IPSEC_SPCOUNT; i++) { 862 if ((sp[i] = key_newsp()) == NULL) 863 goto fail; 864 if ((isr = ipsec_newisr()) == NULL) 865 goto fail; 866 867 sp[i]->policy = IPSEC_POLICY_IPSEC; 868 sp[i]->state = IPSEC_SPSTATE_DEAD; 869 sp[i]->req[sp[i]->tcount++] = isr; 870 sp[i]->created = time_second; 871 /* Use priority field to store if_index */ 872 sp[i]->priority = sc->ifp->if_index; 873 isr->level = IPSEC_LEVEL_UNIQUE; 874 isr->saidx.proto = IPPROTO_ESP; 875 isr->saidx.mode = IPSEC_MODE_TUNNEL; 876 isr->saidx.reqid = reqid; 877 if (i % 2 == 0) { 878 sp[i]->spidx.dir = IPSEC_DIR_INBOUND; 879 bcopy(src, &isr->saidx.dst, src->sa_len); 880 bcopy(dst, &isr->saidx.src, dst->sa_len); 881 } else { 882 sp[i]->spidx.dir = IPSEC_DIR_OUTBOUND; 883 bcopy(src, &isr->saidx.src, src->sa_len); 884 bcopy(dst, &isr->saidx.dst, dst->sa_len); 885 } 886 sp[i]->spidx.ul_proto = IPSEC_ULPROTO_ANY; 887 #ifdef INET 888 if (i < 2) { 889 sp[i]->spidx.src.sa.sa_family = 890 sp[i]->spidx.dst.sa.sa_family = AF_INET; 891 sp[i]->spidx.src.sa.sa_len = 892 sp[i]->spidx.dst.sa.sa_len = 893 sizeof(struct sockaddr_in); 894 continue; 895 } 896 #endif 897 #ifdef INET6 898 sp[i]->spidx.src.sa.sa_family = 899 sp[i]->spidx.dst.sa.sa_family = AF_INET6; 900 sp[i]->spidx.src.sa.sa_len = 901 sp[i]->spidx.dst.sa.sa_len = sizeof(struct sockaddr_in6); 902 #endif 903 } 904 return (0); 905 fail: 906 for (i = 0; i < IPSEC_SPCOUNT; i++) 907 key_freesp(&sp[i]); 908 return (ENOMEM); 909 } 910 911 static int 912 ipsec_check_reqid(uint32_t reqid) 913 { 914 struct ipsec_softc *sc; 915 916 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 917 CK_LIST_FOREACH(sc, ipsec_idhash(reqid), idhash) { 918 if (sc->reqid == reqid) 919 return (EEXIST); 920 } 921 return (0); 922 } 923 924 /* 925 * We use key_newreqid() to automatically obtain unique reqid. 926 * Then we check that given id is unique, i.e. it is not used by 927 * another if_ipsec(4) interface. This macro limits the number of 928 * tries to get unique id. 929 */ 930 #define IPSEC_REQID_TRYCNT 64 931 static int 932 ipsec_init_reqid(struct ipsec_softc *sc) 933 { 934 uint32_t reqid; 935 int trycount; 936 937 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 938 if (sc->reqid != 0) /* already initialized */ 939 return (0); 940 941 trycount = IPSEC_REQID_TRYCNT; 942 while (--trycount > 0) { 943 reqid = key_newreqid(); 944 if (ipsec_check_reqid(reqid) == 0) 945 break; 946 } 947 if (trycount == 0) 948 return (EEXIST); 949 sc->reqid = reqid; 950 CK_LIST_INSERT_HEAD(ipsec_idhash(reqid), sc, idhash); 951 return (0); 952 } 953 954 /* 955 * Set or update reqid for given tunneling interface. 956 * When specified reqid is zero, generate new one. 957 * We are protected by ioctl_sx lock from concurrent id generation. 958 * Also softc would not disappear while we hold ioctl_sx lock. 959 */ 960 static int 961 ipsec_set_reqid(struct ipsec_softc *sc, uint32_t reqid) 962 { 963 struct secasindex *saidx; 964 965 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 966 967 if (sc->reqid == reqid && reqid != 0) 968 return (0); 969 970 if (reqid != 0) { 971 /* Check that specified reqid doesn't exist */ 972 if (ipsec_check_reqid(reqid) != 0) 973 return (EEXIST); 974 if (sc->reqid != 0) { 975 CK_LIST_REMOVE(sc, idhash); 976 IPSEC_WAIT(); 977 } 978 sc->reqid = reqid; 979 CK_LIST_INSERT_HEAD(ipsec_idhash(reqid), sc, idhash); 980 } else { 981 /* Generate new reqid */ 982 if (ipsec_init_reqid(sc) != 0) 983 return (EEXIST); 984 } 985 986 /* Tunnel isn't fully configured, just return. */ 987 if (sc->family == 0) 988 return (0); 989 990 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family); 991 KASSERT(saidx != NULL, 992 ("saidx is NULL, but family is %d", sc->family)); 993 return (ipsec_set_tunnel(sc, &saidx->src.sa, &saidx->dst.sa, 994 sc->reqid)); 995 } 996 997 /* 998 * Set tunnel endpoints addresses. 999 */ 1000 static int 1001 ipsec_set_addresses(struct ifnet *ifp, struct sockaddr *src, 1002 struct sockaddr *dst) 1003 { 1004 struct ipsec_softc *sc; 1005 struct secasindex *saidx; 1006 1007 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 1008 1009 sc = ifp->if_softc; 1010 if (sc->family != 0) { 1011 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, 1012 src->sa_family); 1013 if (saidx != NULL && saidx->reqid == sc->reqid && 1014 key_sockaddrcmp(&saidx->src.sa, src, 0) == 0 && 1015 key_sockaddrcmp(&saidx->dst.sa, dst, 0) == 0) 1016 return (0); /* Nothing has been changed. */ 1017 } 1018 /* If reqid is not set, generate new one. */ 1019 if (ipsec_init_reqid(sc) != 0) 1020 return (EEXIST); 1021 return (ipsec_set_tunnel(sc, src, dst, sc->reqid)); 1022 } 1023 1024 static int 1025 ipsec_set_tunnel(struct ipsec_softc *sc, struct sockaddr *src, 1026 struct sockaddr *dst, uint32_t reqid) 1027 { 1028 struct epoch_tracker et; 1029 struct ipsec_iflist *iflist; 1030 struct secpolicy *sp[IPSEC_SPCOUNT]; 1031 int i; 1032 1033 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 1034 1035 /* Allocate SP with new addresses. */ 1036 iflist = ipsec_srchash(src); 1037 if (iflist == NULL) { 1038 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1039 return (EAFNOSUPPORT); 1040 } 1041 if (ipsec_newpolicies(sc, sp, src, dst, reqid) == 0) { 1042 /* Add new policies to SPDB */ 1043 if (key_register_ifnet(sp, IPSEC_SPCOUNT) != 0) { 1044 for (i = 0; i < IPSEC_SPCOUNT; i++) 1045 key_freesp(&sp[i]); 1046 return (EAGAIN); 1047 } 1048 if (sc->family != 0) 1049 ipsec_delete_tunnel(sc); 1050 for (i = 0; i < IPSEC_SPCOUNT; i++) 1051 sc->sp[i] = sp[i]; 1052 sc->family = src->sa_family; 1053 CK_LIST_INSERT_HEAD(iflist, sc, srchash); 1054 } else { 1055 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1056 return (ENOMEM); 1057 } 1058 NET_EPOCH_ENTER(et); 1059 ipsec_set_running(sc); 1060 NET_EPOCH_EXIT(et); 1061 return (0); 1062 } 1063 1064 static void 1065 ipsec_delete_tunnel(struct ipsec_softc *sc) 1066 { 1067 int i; 1068 1069 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 1070 1071 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 1072 if (sc->family != 0) { 1073 CK_LIST_REMOVE(sc, srchash); 1074 sc->family = 0; 1075 /* 1076 * Make sure that ipsec_if_input() will not do access 1077 * to softc's policies. 1078 */ 1079 IPSEC_WAIT(); 1080 1081 key_unregister_ifnet(sc->sp, IPSEC_SPCOUNT); 1082 for (i = 0; i < IPSEC_SPCOUNT; i++) 1083 key_freesp(&sc->sp[i]); 1084 } 1085 } 1086