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