1 /*- 2 * Copyright (c) 2016 Yandex LLC 3 * Copyright (c) 2016 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 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/fnv_hash.h> 38 #include <sys/jail.h> 39 #include <sys/lock.h> 40 #include <sys/malloc.h> 41 #include <sys/mbuf.h> 42 #include <sys/module.h> 43 #include <sys/rmlock.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_clone.h> 56 #include <net/if_types.h> 57 #include <net/bpf.h> 58 #include <net/route.h> 59 #include <net/vnet.h> 60 61 #include <netinet/in.h> 62 #include <netinet/in_var.h> 63 #include <netinet/ip.h> 64 65 #include <netinet/ip6.h> 66 #include <netinet6/in6_var.h> 67 #include <netinet6/scope6_var.h> 68 69 #include <netipsec/ipsec.h> 70 #ifdef INET6 71 #include <netipsec/ipsec6.h> 72 #endif 73 74 #include <net/if_ipsec.h> 75 #include <netipsec/key.h> 76 77 #include <security/mac/mac_framework.h> 78 79 static MALLOC_DEFINE(M_IPSEC, "ipsec", "IPsec Virtual Tunnel Interface"); 80 static const char ipsecname[] = "ipsec"; 81 82 #if defined(INET) && defined(INET6) 83 #define IPSEC_SPCOUNT 4 84 #else 85 #define IPSEC_SPCOUNT 2 86 #endif 87 88 struct ipsec_softc { 89 struct ifnet *ifp; 90 91 struct rmlock lock; 92 struct secpolicy *sp[IPSEC_SPCOUNT]; 93 94 uint32_t reqid; 95 u_int family; 96 u_int fibnum; 97 LIST_ENTRY(ipsec_softc) chain; 98 LIST_ENTRY(ipsec_softc) hash; 99 }; 100 101 #define IPSEC_LOCK_INIT(sc) rm_init(&(sc)->lock, "if_ipsec softc") 102 #define IPSEC_LOCK_DESTROY(sc) rm_destroy(&(sc)->lock) 103 #define IPSEC_RLOCK_TRACKER struct rm_priotracker ipsec_tracker 104 #define IPSEC_RLOCK(sc) rm_rlock(&(sc)->lock, &ipsec_tracker) 105 #define IPSEC_RUNLOCK(sc) rm_runlock(&(sc)->lock, &ipsec_tracker) 106 #define IPSEC_RLOCK_ASSERT(sc) rm_assert(&(sc)->lock, RA_RLOCKED) 107 #define IPSEC_WLOCK(sc) rm_wlock(&(sc)->lock) 108 #define IPSEC_WUNLOCK(sc) rm_wunlock(&(sc)->lock) 109 #define IPSEC_WLOCK_ASSERT(sc) rm_assert(&(sc)->lock, RA_WLOCKED) 110 111 static struct rmlock ipsec_sc_lock; 112 RM_SYSINIT(ipsec_sc_lock, &ipsec_sc_lock, "if_ipsec softc list"); 113 114 #define IPSEC_SC_RLOCK_TRACKER struct rm_priotracker ipsec_sc_tracker 115 #define IPSEC_SC_RLOCK() rm_rlock(&ipsec_sc_lock, &ipsec_sc_tracker) 116 #define IPSEC_SC_RUNLOCK() rm_runlock(&ipsec_sc_lock, &ipsec_sc_tracker) 117 #define IPSEC_SC_RLOCK_ASSERT() rm_assert(&ipsec_sc_lock, RA_RLOCKED) 118 #define IPSEC_SC_WLOCK() rm_wlock(&ipsec_sc_lock) 119 #define IPSEC_SC_WUNLOCK() rm_wunlock(&ipsec_sc_lock) 120 #define IPSEC_SC_WLOCK_ASSERT() rm_assert(&ipsec_sc_lock, RA_WLOCKED) 121 122 LIST_HEAD(ipsec_iflist, ipsec_softc); 123 static VNET_DEFINE(struct ipsec_iflist, ipsec_sc_list); 124 static VNET_DEFINE(struct ipsec_iflist *, ipsec_sc_htbl); 125 static VNET_DEFINE(u_long, ipsec_sc_hmask); 126 #define V_ipsec_sc_list VNET(ipsec_sc_list) 127 #define V_ipsec_sc_htbl VNET(ipsec_sc_htbl) 128 #define V_ipsec_sc_hmask VNET(ipsec_sc_hmask) 129 130 static uint32_t 131 ipsec_hash(uint32_t id) 132 { 133 134 return (fnv_32_buf(&id, sizeof(id), FNV1_32_INIT)); 135 } 136 137 #define SCHASH_NHASH_LOG2 5 138 #define SCHASH_NHASH (1 << SCHASH_NHASH_LOG2) 139 #define SCHASH_HASHVAL(id) (ipsec_hash((id)) & V_ipsec_sc_hmask) 140 #define SCHASH_HASH(id) &V_ipsec_sc_htbl[SCHASH_HASHVAL(id)] 141 142 /* 143 * ipsec_ioctl_sx protects from concurrent ioctls. 144 */ 145 static struct sx ipsec_ioctl_sx; 146 SX_SYSINIT(ipsec_ioctl_sx, &ipsec_ioctl_sx, "ipsec_ioctl"); 147 148 static int ipsec_init_reqid(struct ipsec_softc *); 149 static int ipsec_set_tunnel(struct ipsec_softc *, struct sockaddr *, 150 struct sockaddr *, uint32_t); 151 static void ipsec_delete_tunnel(struct ifnet *, int); 152 153 static int ipsec_set_addresses(struct ifnet *, struct sockaddr *, 154 struct sockaddr *); 155 static int ipsec_set_reqid(struct ifnet *, uint32_t); 156 157 static int ipsec_ioctl(struct ifnet *, u_long, caddr_t); 158 static int ipsec_transmit(struct ifnet *, struct mbuf *); 159 static int ipsec_output(struct ifnet *, struct mbuf *, 160 const struct sockaddr *, struct route *); 161 static void ipsec_qflush(struct ifnet *); 162 static int ipsec_clone_create(struct if_clone *, int, caddr_t); 163 static void ipsec_clone_destroy(struct ifnet *); 164 165 static VNET_DEFINE(struct if_clone *, ipsec_cloner); 166 #define V_ipsec_cloner VNET(ipsec_cloner) 167 168 static int 169 ipsec_clone_create(struct if_clone *ifc, int unit, caddr_t params) 170 { 171 struct ipsec_softc *sc; 172 struct ifnet *ifp; 173 174 sc = malloc(sizeof(*sc), M_IPSEC, M_WAITOK | M_ZERO); 175 sc->fibnum = curthread->td_proc->p_fibnum; 176 sc->ifp = ifp = if_alloc(IFT_TUNNEL); 177 IPSEC_LOCK_INIT(sc); 178 ifp->if_softc = sc; 179 if_initname(ifp, ipsecname, unit); 180 181 ifp->if_addrlen = 0; 182 ifp->if_mtu = IPSEC_MTU; 183 ifp->if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 184 ifp->if_ioctl = ipsec_ioctl; 185 ifp->if_transmit = ipsec_transmit; 186 ifp->if_qflush = ipsec_qflush; 187 ifp->if_output = ipsec_output; 188 if_attach(ifp); 189 bpfattach(ifp, DLT_NULL, sizeof(uint32_t)); 190 191 IPSEC_SC_WLOCK(); 192 LIST_INSERT_HEAD(&V_ipsec_sc_list, sc, chain); 193 IPSEC_SC_WUNLOCK(); 194 return (0); 195 } 196 197 static void 198 ipsec_clone_destroy(struct ifnet *ifp) 199 { 200 struct ipsec_softc *sc; 201 202 sx_xlock(&ipsec_ioctl_sx); 203 sc = ifp->if_softc; 204 205 IPSEC_SC_WLOCK(); 206 ipsec_delete_tunnel(ifp, 1); 207 LIST_REMOVE(sc, chain); 208 IPSEC_SC_WUNLOCK(); 209 210 bpfdetach(ifp); 211 if_detach(ifp); 212 ifp->if_softc = NULL; 213 sx_xunlock(&ipsec_ioctl_sx); 214 215 if_free(ifp); 216 IPSEC_LOCK_DESTROY(sc); 217 free(sc, M_IPSEC); 218 } 219 220 static void 221 vnet_ipsec_init(const void *unused __unused) 222 { 223 224 LIST_INIT(&V_ipsec_sc_list); 225 V_ipsec_sc_htbl = hashinit(SCHASH_NHASH, M_IPSEC, &V_ipsec_sc_hmask); 226 V_ipsec_cloner = if_clone_simple(ipsecname, ipsec_clone_create, 227 ipsec_clone_destroy, 0); 228 } 229 VNET_SYSINIT(vnet_ipsec_init, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 230 vnet_ipsec_init, NULL); 231 232 static void 233 vnet_ipsec_uninit(const void *unused __unused) 234 { 235 236 if_clone_detach(V_ipsec_cloner); 237 hashdestroy(V_ipsec_sc_htbl, M_IPSEC, V_ipsec_sc_hmask); 238 } 239 VNET_SYSUNINIT(vnet_ipsec_uninit, SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY, 240 vnet_ipsec_uninit, NULL); 241 242 static struct secpolicy * 243 ipsec_getpolicy(struct ipsec_softc *sc, int dir, sa_family_t af) 244 { 245 246 switch (af) { 247 #ifdef INET 248 case AF_INET: 249 return (sc->sp[(dir == IPSEC_DIR_INBOUND ? 0: 1)]); 250 #endif 251 #ifdef INET6 252 case AF_INET6: 253 return (sc->sp[(dir == IPSEC_DIR_INBOUND ? 0: 1) 254 #ifdef INET 255 + 2 256 #endif 257 ]); 258 #endif 259 } 260 return (NULL); 261 } 262 263 static struct secasindex * 264 ipsec_getsaidx(struct ipsec_softc *sc, int dir, sa_family_t af) 265 { 266 struct secpolicy *sp; 267 268 sp = ipsec_getpolicy(sc, dir, af); 269 if (sp == NULL) 270 return (NULL); 271 return (&sp->req[0]->saidx); 272 } 273 274 static int 275 ipsec_transmit(struct ifnet *ifp, struct mbuf *m) 276 { 277 IPSEC_RLOCK_TRACKER; 278 struct ipsec_softc *sc; 279 struct secpolicy *sp; 280 struct ip *ip; 281 uint32_t af; 282 int error; 283 284 #ifdef MAC 285 error = mac_ifnet_check_transmit(ifp, m); 286 if (error) { 287 m_freem(m); 288 goto err; 289 } 290 #endif 291 error = ENETDOWN; 292 sc = ifp->if_softc; 293 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 294 (ifp->if_flags & IFF_MONITOR) != 0 || 295 (ifp->if_flags & IFF_UP) == 0) { 296 m_freem(m); 297 goto err; 298 } 299 300 /* Determine address family to correctly handle packet in BPF */ 301 ip = mtod(m, struct ip *); 302 switch (ip->ip_v) { 303 #ifdef INET 304 case IPVERSION: 305 af = AF_INET; 306 break; 307 #endif 308 #ifdef INET6 309 case (IPV6_VERSION >> 4): 310 af = AF_INET6; 311 break; 312 #endif 313 default: 314 error = EAFNOSUPPORT; 315 m_freem(m); 316 goto err; 317 } 318 319 /* 320 * Loop prevention. 321 * XXX: for now just check presence of IPSEC_OUT_DONE mbuf tag. 322 * We can read full chain and compare destination address, 323 * proto and mode from xform_history with values from softc. 324 */ 325 if (m_tag_find(m, PACKET_TAG_IPSEC_OUT_DONE, NULL) != NULL) { 326 m_freem(m); 327 goto err; 328 } 329 330 IPSEC_RLOCK(sc); 331 if (sc->family == 0) { 332 IPSEC_RUNLOCK(sc); 333 m_freem(m); 334 goto err; 335 } 336 sp = ipsec_getpolicy(sc, IPSEC_DIR_OUTBOUND, af); 337 key_addref(sp); 338 M_SETFIB(m, sc->fibnum); 339 IPSEC_RUNLOCK(sc); 340 341 BPF_MTAP2(ifp, &af, sizeof(af), m); 342 if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1); 343 if_inc_counter(ifp, IFCOUNTER_OBYTES, m->m_pkthdr.len); 344 345 switch (af) { 346 #ifdef INET 347 case AF_INET: 348 error = ipsec4_process_packet(m, sp, NULL); 349 break; 350 #endif 351 #ifdef INET6 352 case AF_INET6: 353 error = ipsec6_process_packet(m, sp, NULL); 354 break; 355 #endif 356 default: 357 panic("%s: unknown address family\n", __func__); 358 } 359 err: 360 if (error != 0) 361 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); 362 return (error); 363 } 364 365 static void 366 ipsec_qflush(struct ifnet *ifp __unused) 367 { 368 369 } 370 371 static int 372 ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 373 struct route *ro) 374 { 375 376 return (ifp->if_transmit(ifp, m)); 377 } 378 379 int 380 ipsec_if_input(struct mbuf *m, struct secasvar *sav, uint32_t af) 381 { 382 IPSEC_SC_RLOCK_TRACKER; 383 struct secasindex *saidx; 384 struct ipsec_softc *sc; 385 struct ifnet *ifp; 386 387 if (sav->state != SADB_SASTATE_MATURE && 388 sav->state != SADB_SASTATE_DYING) { 389 m_freem(m); 390 return (ENETDOWN); 391 } 392 393 if (sav->sah->saidx.mode != IPSEC_MODE_TUNNEL || 394 sav->sah->saidx.proto != IPPROTO_ESP) 395 return (0); 396 397 IPSEC_SC_RLOCK(); 398 /* 399 * We only acquire SC_RLOCK() while we are doing search in 400 * ipsec_sc_htbl. It is safe, because removing softc or changing 401 * of reqid/addresses requires removing from hash table. 402 */ 403 LIST_FOREACH(sc, SCHASH_HASH(sav->sah->saidx.reqid), hash) { 404 saidx = ipsec_getsaidx(sc, IPSEC_DIR_INBOUND, 405 sav->sah->saidx.src.sa.sa_family); 406 /* SA's reqid should match reqid in SP */ 407 if (saidx == NULL || 408 sav->sah->saidx.reqid != saidx->reqid) 409 continue; 410 /* SAH's addresses should match tunnel endpoints. */ 411 if (key_sockaddrcmp(&sav->sah->saidx.dst.sa, 412 &saidx->dst.sa, 0) != 0) 413 continue; 414 if (key_sockaddrcmp(&sav->sah->saidx.src.sa, 415 &saidx->src.sa, 0) == 0) 416 break; 417 } 418 if (sc == NULL) { 419 IPSEC_SC_RUNLOCK(); 420 /* Tunnel was not found. Nothing to do. */ 421 return (0); 422 } 423 ifp = sc->ifp; 424 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || 425 (ifp->if_flags & IFF_UP) == 0) { 426 IPSEC_SC_RUNLOCK(); 427 m_freem(m); 428 return (ENETDOWN); 429 } 430 /* 431 * We found matching and working tunnel. 432 * Set its ifnet as receiving interface. 433 */ 434 m->m_pkthdr.rcvif = ifp; 435 IPSEC_SC_RUNLOCK(); 436 437 /* m_clrprotoflags(m); */ 438 M_SETFIB(m, ifp->if_fib); 439 BPF_MTAP2(ifp, &af, sizeof(af), m); 440 if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1); 441 if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); 442 if ((ifp->if_flags & IFF_MONITOR) != 0) { 443 m_freem(m); 444 return (ENETDOWN); 445 } 446 return (0); 447 } 448 449 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */ 450 int 451 ipsec_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 452 { 453 IPSEC_RLOCK_TRACKER; 454 struct ifreq *ifr = (struct ifreq*)data; 455 struct sockaddr *dst, *src; 456 struct ipsec_softc *sc; 457 struct secasindex *saidx; 458 #ifdef INET 459 struct sockaddr_in *sin = NULL; 460 #endif 461 #ifdef INET6 462 struct sockaddr_in6 *sin6 = NULL; 463 #endif 464 uint32_t reqid; 465 int error; 466 467 switch (cmd) { 468 case SIOCSIFADDR: 469 ifp->if_flags |= IFF_UP; 470 case SIOCADDMULTI: 471 case SIOCDELMULTI: 472 case SIOCGIFMTU: 473 case SIOCSIFFLAGS: 474 return (0); 475 case SIOCSIFMTU: 476 if (ifr->ifr_mtu < IPSEC_MTU_MIN || 477 ifr->ifr_mtu > IPSEC_MTU_MAX) 478 return (EINVAL); 479 else 480 ifp->if_mtu = ifr->ifr_mtu; 481 return (0); 482 } 483 sx_xlock(&ipsec_ioctl_sx); 484 sc = ifp->if_softc; 485 /* Check that softc is still here */ 486 if (sc == NULL) { 487 error = ENXIO; 488 goto bad; 489 } 490 error = 0; 491 switch (cmd) { 492 case SIOCSIFPHYADDR: 493 #ifdef INET6 494 case SIOCSIFPHYADDR_IN6: 495 #endif 496 error = EINVAL; 497 switch (cmd) { 498 #ifdef INET 499 case SIOCSIFPHYADDR: 500 src = (struct sockaddr *) 501 &(((struct in_aliasreq *)data)->ifra_addr); 502 dst = (struct sockaddr *) 503 &(((struct in_aliasreq *)data)->ifra_dstaddr); 504 break; 505 #endif 506 #ifdef INET6 507 case SIOCSIFPHYADDR_IN6: 508 src = (struct sockaddr *) 509 &(((struct in6_aliasreq *)data)->ifra_addr); 510 dst = (struct sockaddr *) 511 &(((struct in6_aliasreq *)data)->ifra_dstaddr); 512 break; 513 #endif 514 default: 515 goto bad; 516 } 517 /* sa_family must be equal */ 518 if (src->sa_family != dst->sa_family || 519 src->sa_len != dst->sa_len) 520 goto bad; 521 522 /* validate sa_len */ 523 switch (src->sa_family) { 524 #ifdef INET 525 case AF_INET: 526 if (src->sa_len != sizeof(struct sockaddr_in)) 527 goto bad; 528 break; 529 #endif 530 #ifdef INET6 531 case AF_INET6: 532 if (src->sa_len != sizeof(struct sockaddr_in6)) 533 goto bad; 534 break; 535 #endif 536 default: 537 error = EAFNOSUPPORT; 538 goto bad; 539 } 540 /* check sa_family looks sane for the cmd */ 541 error = EAFNOSUPPORT; 542 switch (cmd) { 543 #ifdef INET 544 case SIOCSIFPHYADDR: 545 if (src->sa_family == AF_INET) 546 break; 547 goto bad; 548 #endif 549 #ifdef INET6 550 case SIOCSIFPHYADDR_IN6: 551 if (src->sa_family == AF_INET6) 552 break; 553 goto bad; 554 #endif 555 } 556 error = EADDRNOTAVAIL; 557 switch (src->sa_family) { 558 #ifdef INET 559 case AF_INET: 560 if (satosin(src)->sin_addr.s_addr == INADDR_ANY || 561 satosin(dst)->sin_addr.s_addr == INADDR_ANY) 562 goto bad; 563 break; 564 #endif 565 #ifdef INET6 566 case AF_INET6: 567 if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr) 568 || 569 IN6_IS_ADDR_UNSPECIFIED(&satosin6(dst)->sin6_addr)) 570 goto bad; 571 /* 572 * Check validity of the scope zone ID of the 573 * addresses, and convert it into the kernel 574 * internal form if necessary. 575 */ 576 error = sa6_embedscope(satosin6(src), 0); 577 if (error != 0) 578 goto bad; 579 error = sa6_embedscope(satosin6(dst), 0); 580 if (error != 0) 581 goto bad; 582 #endif 583 }; 584 error = ipsec_set_addresses(ifp, src, dst); 585 break; 586 case SIOCDIFPHYADDR: 587 ipsec_delete_tunnel(ifp, 0); 588 break; 589 case SIOCGIFPSRCADDR: 590 case SIOCGIFPDSTADDR: 591 #ifdef INET6 592 case SIOCGIFPSRCADDR_IN6: 593 case SIOCGIFPDSTADDR_IN6: 594 #endif 595 IPSEC_RLOCK(sc); 596 if (sc->family == 0) { 597 IPSEC_RUNLOCK(sc); 598 error = EADDRNOTAVAIL; 599 break; 600 } 601 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family); 602 switch (cmd) { 603 #ifdef INET 604 case SIOCGIFPSRCADDR: 605 case SIOCGIFPDSTADDR: 606 if (saidx->src.sa.sa_family != AF_INET) { 607 error = EADDRNOTAVAIL; 608 break; 609 } 610 sin = (struct sockaddr_in *)&ifr->ifr_addr; 611 memset(sin, 0, sizeof(*sin)); 612 sin->sin_family = AF_INET; 613 sin->sin_len = sizeof(*sin); 614 break; 615 #endif 616 #ifdef INET6 617 case SIOCGIFPSRCADDR_IN6: 618 case SIOCGIFPDSTADDR_IN6: 619 if (saidx->src.sa.sa_family != AF_INET6) { 620 error = EADDRNOTAVAIL; 621 break; 622 } 623 sin6 = (struct sockaddr_in6 *) 624 &(((struct in6_ifreq *)data)->ifr_addr); 625 memset(sin6, 0, sizeof(*sin6)); 626 sin6->sin6_family = AF_INET6; 627 sin6->sin6_len = sizeof(*sin6); 628 break; 629 #endif 630 default: 631 error = EAFNOSUPPORT; 632 } 633 if (error == 0) { 634 switch (cmd) { 635 #ifdef INET 636 case SIOCGIFPSRCADDR: 637 sin->sin_addr = saidx->src.sin.sin_addr; 638 break; 639 case SIOCGIFPDSTADDR: 640 sin->sin_addr = saidx->dst.sin.sin_addr; 641 break; 642 #endif 643 #ifdef INET6 644 case SIOCGIFPSRCADDR_IN6: 645 sin6->sin6_addr = saidx->src.sin6.sin6_addr; 646 break; 647 case SIOCGIFPDSTADDR_IN6: 648 sin6->sin6_addr = saidx->dst.sin6.sin6_addr; 649 break; 650 #endif 651 } 652 } 653 IPSEC_RUNLOCK(sc); 654 if (error != 0) 655 break; 656 switch (cmd) { 657 #ifdef INET 658 case SIOCGIFPSRCADDR: 659 case SIOCGIFPDSTADDR: 660 error = prison_if(curthread->td_ucred, 661 (struct sockaddr *)sin); 662 if (error != 0) 663 memset(sin, 0, sizeof(*sin)); 664 break; 665 #endif 666 #ifdef INET6 667 case SIOCGIFPSRCADDR_IN6: 668 case SIOCGIFPDSTADDR_IN6: 669 error = prison_if(curthread->td_ucred, 670 (struct sockaddr *)sin6); 671 if (error == 0) 672 error = sa6_recoverscope(sin6); 673 if (error != 0) 674 memset(sin6, 0, sizeof(*sin6)); 675 #endif 676 } 677 break; 678 case SIOCGTUNFIB: 679 ifr->ifr_fib = sc->fibnum; 680 break; 681 case SIOCSTUNFIB: 682 if ((error = priv_check(curthread, PRIV_NET_SETIFFIB)) != 0) 683 break; 684 if (ifr->ifr_fib >= rt_numfibs) 685 error = EINVAL; 686 else 687 sc->fibnum = ifr->ifr_fib; 688 break; 689 case IPSECGREQID: 690 reqid = sc->reqid; 691 error = copyout(&reqid, ifr_data_get_ptr(ifr), sizeof(reqid)); 692 break; 693 case IPSECSREQID: 694 if ((error = priv_check(curthread, PRIV_NET_SETIFCAP)) != 0) 695 break; 696 error = copyin(ifr_data_get_ptr(ifr), &reqid, sizeof(reqid)); 697 if (error != 0) 698 break; 699 error = ipsec_set_reqid(ifp, reqid); 700 break; 701 default: 702 error = EINVAL; 703 break; 704 } 705 bad: 706 sx_xunlock(&ipsec_ioctl_sx); 707 return (error); 708 } 709 710 /* 711 * Allocate new private security policies for tunneling interface. 712 * Each tunneling interface has following security policies for 713 * both AF: 714 * 0.0.0.0/0[any] 0.0.0.0/0[any] -P in \ 715 * ipsec esp/tunnel/RemoteIP-LocalIP/unique:reqid 716 * 0.0.0.0/0[any] 0.0.0.0/0[any] -P out \ 717 * ipsec esp/tunnel/LocalIP-RemoteIP/unique:reqid 718 */ 719 static int 720 ipsec_newpolicies(struct ipsec_softc *sc, struct secpolicy *sp[IPSEC_SPCOUNT], 721 const struct sockaddr *src, const struct sockaddr *dst, uint32_t reqid) 722 { 723 struct ipsecrequest *isr; 724 int i; 725 726 memset(sp, 0, sizeof(struct secpolicy *) * IPSEC_SPCOUNT); 727 for (i = 0; i < IPSEC_SPCOUNT; i++) { 728 if ((sp[i] = key_newsp()) == NULL) 729 goto fail; 730 if ((isr = ipsec_newisr()) == NULL) 731 goto fail; 732 733 sp[i]->policy = IPSEC_POLICY_IPSEC; 734 sp[i]->state = IPSEC_SPSTATE_DEAD; 735 sp[i]->req[sp[i]->tcount++] = isr; 736 sp[i]->created = time_second; 737 /* Use priority field to store if_index */ 738 sp[i]->priority = sc->ifp->if_index; 739 isr->level = IPSEC_LEVEL_UNIQUE; 740 isr->saidx.proto = IPPROTO_ESP; 741 isr->saidx.mode = IPSEC_MODE_TUNNEL; 742 isr->saidx.reqid = reqid; 743 if (i % 2 == 0) { 744 sp[i]->spidx.dir = IPSEC_DIR_INBOUND; 745 bcopy(src, &isr->saidx.dst, src->sa_len); 746 bcopy(dst, &isr->saidx.src, dst->sa_len); 747 } else { 748 sp[i]->spidx.dir = IPSEC_DIR_OUTBOUND; 749 bcopy(src, &isr->saidx.src, src->sa_len); 750 bcopy(dst, &isr->saidx.dst, dst->sa_len); 751 } 752 sp[i]->spidx.ul_proto = IPSEC_ULPROTO_ANY; 753 #ifdef INET 754 if (i < 2) { 755 sp[i]->spidx.src.sa.sa_family = 756 sp[i]->spidx.dst.sa.sa_family = AF_INET; 757 sp[i]->spidx.src.sa.sa_len = 758 sp[i]->spidx.dst.sa.sa_len = 759 sizeof(struct sockaddr_in); 760 continue; 761 } 762 #endif 763 #ifdef INET6 764 sp[i]->spidx.src.sa.sa_family = 765 sp[i]->spidx.dst.sa.sa_family = AF_INET6; 766 sp[i]->spidx.src.sa.sa_len = 767 sp[i]->spidx.dst.sa.sa_len = sizeof(struct sockaddr_in6); 768 #endif 769 } 770 return (0); 771 fail: 772 for (i = 0; i < IPSEC_SPCOUNT; i++) 773 key_freesp(&sp[i]); 774 return (ENOMEM); 775 } 776 777 static int 778 ipsec_check_reqid(uint32_t reqid) 779 { 780 struct ipsec_softc *sc; 781 782 IPSEC_SC_RLOCK_ASSERT(); 783 LIST_FOREACH(sc, &V_ipsec_sc_list, chain) { 784 if (sc->reqid == reqid) 785 return (EEXIST); 786 } 787 return (0); 788 } 789 790 /* 791 * We use key_newreqid() to automatically obtain unique reqid. 792 * Then we check that given id is unique, i.e. it is not used by 793 * another if_ipsec(4) interface. This macro limits the number of 794 * tries to get unique id. 795 */ 796 #define IPSEC_REQID_TRYCNT 64 797 static int 798 ipsec_init_reqid(struct ipsec_softc *sc) 799 { 800 uint32_t reqid; 801 int trycount; 802 803 IPSEC_SC_RLOCK_ASSERT(); 804 805 if (sc->reqid != 0) /* already initialized */ 806 return (0); 807 808 trycount = IPSEC_REQID_TRYCNT; 809 while (--trycount > 0) { 810 reqid = key_newreqid(); 811 if (ipsec_check_reqid(reqid) == 0) 812 break; 813 } 814 if (trycount == 0) 815 return (EEXIST); 816 sc->reqid = reqid; 817 return (0); 818 } 819 820 /* 821 * Set or update reqid for given tunneling interface. 822 * When specified reqid is zero, generate new one. 823 * We are protected by ioctl_sx lock from concurrent id generation. 824 * Also softc would not disappear while we hold ioctl_sx lock. 825 */ 826 static int 827 ipsec_set_reqid(struct ifnet *ifp, uint32_t reqid) 828 { 829 IPSEC_SC_RLOCK_TRACKER; 830 struct ipsec_softc *sc; 831 struct secasindex *saidx; 832 833 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 834 835 sc = ifp->if_softc; 836 if (sc->reqid == reqid && reqid != 0) 837 return (0); 838 839 IPSEC_SC_RLOCK(); 840 if (reqid != 0) { 841 /* Check that specified reqid doesn't exist */ 842 if (ipsec_check_reqid(reqid) != 0) { 843 IPSEC_SC_RUNLOCK(); 844 return (EEXIST); 845 } 846 sc->reqid = reqid; 847 } else { 848 /* Generate new reqid */ 849 if (ipsec_init_reqid(sc) != 0) { 850 IPSEC_SC_RUNLOCK(); 851 return (EEXIST); 852 } 853 } 854 IPSEC_SC_RUNLOCK(); 855 856 /* Tunnel isn't fully configured, just return. */ 857 if (sc->family == 0) 858 return (0); 859 860 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, sc->family); 861 KASSERT(saidx != NULL, 862 ("saidx is NULL, but family is %d", sc->family)); 863 return (ipsec_set_tunnel(sc, &saidx->src.sa, &saidx->dst.sa, 864 sc->reqid)); 865 } 866 867 /* 868 * Set tunnel endpoints addresses. 869 */ 870 static int 871 ipsec_set_addresses(struct ifnet *ifp, struct sockaddr *src, 872 struct sockaddr *dst) 873 { 874 IPSEC_SC_RLOCK_TRACKER; 875 struct ipsec_softc *sc, *tsc; 876 struct secasindex *saidx; 877 878 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 879 880 sc = ifp->if_softc; 881 if (sc->family != 0) { 882 saidx = ipsec_getsaidx(sc, IPSEC_DIR_OUTBOUND, 883 src->sa_family); 884 if (saidx != NULL && saidx->reqid == sc->reqid && 885 key_sockaddrcmp(&saidx->src.sa, src, 0) == 0 && 886 key_sockaddrcmp(&saidx->dst.sa, dst, 0) == 0) 887 return (0); /* Nothing has been changed. */ 888 889 } 890 /* 891 * We cannot service IPsec tunnel when source address is 892 * not our own. 893 */ 894 #ifdef INET 895 if (src->sa_family == AF_INET && 896 in_localip(satosin(src)->sin_addr) == 0) 897 return (EADDRNOTAVAIL); 898 #endif 899 #ifdef INET6 900 /* 901 * NOTE: IPv6 addresses are in kernel internal form with 902 * embedded scope zone id. 903 */ 904 if (src->sa_family == AF_INET6 && 905 in6_localip(&satosin6(src)->sin6_addr) == 0) 906 return (EADDRNOTAVAIL); 907 #endif 908 /* Check that given addresses aren't already configured */ 909 IPSEC_SC_RLOCK(); 910 LIST_FOREACH(tsc, &V_ipsec_sc_list, chain) { 911 if (tsc == sc || tsc->family != src->sa_family) 912 continue; 913 saidx = ipsec_getsaidx(tsc, IPSEC_DIR_OUTBOUND, tsc->family); 914 if (key_sockaddrcmp(&saidx->src.sa, src, 0) == 0 && 915 key_sockaddrcmp(&saidx->dst.sa, dst, 0) == 0) { 916 /* We already have tunnel with such addresses */ 917 IPSEC_SC_RUNLOCK(); 918 return (EADDRNOTAVAIL); 919 } 920 } 921 /* If reqid is not set, generate new one. */ 922 if (ipsec_init_reqid(sc) != 0) { 923 IPSEC_SC_RUNLOCK(); 924 return (EEXIST); 925 } 926 IPSEC_SC_RUNLOCK(); 927 return (ipsec_set_tunnel(sc, src, dst, sc->reqid)); 928 } 929 930 static int 931 ipsec_set_tunnel(struct ipsec_softc *sc, struct sockaddr *src, 932 struct sockaddr *dst, uint32_t reqid) 933 { 934 struct secpolicy *sp[IPSEC_SPCOUNT]; 935 struct secpolicy *oldsp[IPSEC_SPCOUNT]; 936 int i, f; 937 938 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 939 940 /* Allocate SP with new addresses. */ 941 if (ipsec_newpolicies(sc, sp, src, dst, reqid) == 0) { 942 /* Add new policies to SPDB */ 943 if (key_register_ifnet(sp, IPSEC_SPCOUNT) != 0) { 944 for (i = 0; i < IPSEC_SPCOUNT; i++) 945 key_freesp(&sp[i]); 946 return (EAGAIN); 947 } 948 IPSEC_SC_WLOCK(); 949 if ((f = sc->family) != 0) 950 LIST_REMOVE(sc, hash); 951 IPSEC_WLOCK(sc); 952 for (i = 0; i < IPSEC_SPCOUNT; i++) { 953 oldsp[i] = sc->sp[i]; 954 sc->sp[i] = sp[i]; 955 } 956 sc->family = src->sa_family; 957 IPSEC_WUNLOCK(sc); 958 LIST_INSERT_HEAD(SCHASH_HASH(sc->reqid), sc, hash); 959 IPSEC_SC_WUNLOCK(); 960 } else { 961 sc->ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 962 return (ENOMEM); 963 } 964 965 sc->ifp->if_drv_flags |= IFF_DRV_RUNNING; 966 if (f != 0) { 967 key_unregister_ifnet(oldsp, IPSEC_SPCOUNT); 968 for (i = 0; i < IPSEC_SPCOUNT; i++) 969 key_freesp(&oldsp[i]); 970 } 971 return (0); 972 } 973 974 static void 975 ipsec_delete_tunnel(struct ifnet *ifp, int locked) 976 { 977 struct ipsec_softc *sc = ifp->if_softc; 978 struct secpolicy *oldsp[IPSEC_SPCOUNT]; 979 int i; 980 981 sx_assert(&ipsec_ioctl_sx, SA_XLOCKED); 982 983 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; 984 if (sc->family != 0) { 985 if (!locked) 986 IPSEC_SC_WLOCK(); 987 /* Remove from hash table */ 988 LIST_REMOVE(sc, hash); 989 IPSEC_WLOCK(sc); 990 for (i = 0; i < IPSEC_SPCOUNT; i++) { 991 oldsp[i] = sc->sp[i]; 992 sc->sp[i] = NULL; 993 } 994 sc->family = 0; 995 IPSEC_WUNLOCK(sc); 996 if (!locked) 997 IPSEC_SC_WUNLOCK(); 998 key_unregister_ifnet(oldsp, IPSEC_SPCOUNT); 999 for (i = 0; i < IPSEC_SPCOUNT; i++) 1000 key_freesp(&oldsp[i]); 1001 } 1002 } 1003