1 /* $NetBSD: if_ipsec.c,v 1.14 2018/05/24 07:00:28 knakahara Exp $ */ 2 3 /* 4 * Copyright (c) 2017 Internet Initiative Japan Inc. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS 17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/cdefs.h> 30 __KERNEL_RCSID(0, "$NetBSD: if_ipsec.c,v 1.14 2018/05/24 07:00:28 knakahara Exp $"); 31 32 #ifdef _KERNEL_OPT 33 #include "opt_inet.h" 34 #endif 35 36 #include <sys/param.h> 37 #include <sys/systm.h> 38 #include <sys/kernel.h> 39 #include <sys/mbuf.h> 40 #include <sys/socket.h> 41 #include <sys/sockio.h> 42 #include <sys/errno.h> 43 #include <sys/ioctl.h> 44 #include <sys/time.h> 45 #include <sys/syslog.h> 46 #include <sys/cpu.h> 47 #include <sys/kmem.h> 48 #include <sys/mutex.h> 49 #include <sys/pserialize.h> 50 #include <sys/psref.h> 51 52 #include <net/if.h> 53 #include <net/if_types.h> 54 #include <net/route.h> 55 #include <net/bpf.h> 56 #include <net/pfkeyv2.h> 57 58 #include <netinet/in.h> 59 #include <netinet/in_systm.h> 60 #include <netinet/ip.h> 61 #ifdef INET 62 #include <netinet/in_var.h> 63 #endif /* INET */ 64 65 #ifdef INET6 66 #include <netinet6/in6_var.h> 67 #include <netinet/ip6.h> 68 #include <netinet6/ip6_var.h> 69 #endif /* INET6 */ 70 71 #include <netinet/ip_encap.h> 72 73 #include <net/if_ipsec.h> 74 75 #include <net/raw_cb.h> 76 #include <net/pfkeyv2.h> 77 78 #include <netipsec/key.h> 79 #include <netipsec/keydb.h> /* for union sockaddr_union */ 80 #include <netipsec/ipsec.h> 81 #include <netipsec/ipsecif.h> 82 83 static void if_ipsec_ro_init_pc(void *, void *, struct cpu_info *); 84 static void if_ipsec_ro_fini_pc(void *, void *, struct cpu_info *); 85 86 static int if_ipsec_clone_create(struct if_clone *, int); 87 static int if_ipsec_clone_destroy(struct ifnet *); 88 89 static inline int if_ipsec_out_direct(struct ipsec_variant *, struct mbuf *, int); 90 static inline void if_ipsec_in_enqueue(struct mbuf *, int, struct ifnet *); 91 92 static int if_ipsec_encap_attach(struct ipsec_variant *); 93 static int if_ipsec_encap_detach(struct ipsec_variant *); 94 static int if_ipsec_set_tunnel(struct ifnet *, 95 struct sockaddr *, struct sockaddr *); 96 static void if_ipsec_delete_tunnel(struct ifnet *); 97 static int if_ipsec_ensure_flags(struct ifnet *, short); 98 static void if_ipsec_attach0(struct ipsec_softc *); 99 100 static int if_ipsec_update_variant(struct ipsec_softc *, 101 struct ipsec_variant *, struct ipsec_variant *); 102 103 /* sadb_msg */ 104 static inline void if_ipsec_add_mbuf(struct mbuf *, void *, size_t); 105 static inline void if_ipsec_add_pad(struct mbuf *, size_t); 106 static inline size_t if_ipsec_set_sadb_addr(struct sadb_address *, 107 struct sockaddr *, int, uint16_t); 108 static inline size_t if_ipsec_set_sadb_src(struct sadb_address *, 109 struct sockaddr *, int); 110 static inline size_t if_ipsec_set_sadb_dst(struct sadb_address *, 111 struct sockaddr *, int); 112 static inline size_t if_ipsec_set_sadb_x_policy(struct sadb_x_policy *, 113 struct sadb_x_ipsecrequest *, uint16_t, uint8_t, uint32_t, uint8_t, 114 struct sockaddr *, struct sockaddr *); 115 static inline void if_ipsec_set_sadb_msg(struct sadb_msg *, uint16_t, uint8_t); 116 static inline void if_ipsec_set_sadb_msg_add(struct sadb_msg *, uint16_t); 117 static inline void if_ipsec_set_sadb_msg_del(struct sadb_msg *, uint16_t); 118 /* SPD */ 119 static int if_ipsec_share_sp(struct ipsec_variant *); 120 static int if_ipsec_unshare_sp(struct ipsec_variant *); 121 static inline struct secpolicy *if_ipsec_add_sp0(struct sockaddr *, 122 in_port_t, struct sockaddr *, in_port_t, int, int, int, u_int); 123 static inline int if_ipsec_del_sp0(struct secpolicy *); 124 static int if_ipsec_add_sp(struct ipsec_variant *, 125 struct sockaddr *, in_port_t, struct sockaddr *, in_port_t); 126 static void if_ipsec_del_sp(struct ipsec_variant *); 127 static int if_ipsec_replace_sp(struct ipsec_softc *, struct ipsec_variant *, 128 struct ipsec_variant *); 129 130 static int if_ipsec_set_addr_port(struct sockaddr *, struct sockaddr *, 131 in_port_t); 132 #define IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, target) \ 133 if_ipsec_set_addr_port(target, (var)->iv_psrc, (var)->iv_sport) 134 #define IF_IPSEC_GATHER_PDST_ADDR_PORT(var, target) \ 135 if_ipsec_set_addr_port(target, (var)->iv_pdst, (var)->iv_dport) 136 137 /* 138 * ipsec global variable definitions 139 */ 140 141 /* This list is used in ioctl context only. */ 142 LIST_HEAD(ipsec_sclist, ipsec_softc); 143 static struct { 144 struct ipsec_sclist list; 145 kmutex_t lock; 146 } ipsec_softcs __cacheline_aligned; 147 148 pserialize_t ipsec_psz __read_mostly; 149 struct psref_class *iv_psref_class __read_mostly; 150 151 struct if_clone ipsec_cloner = 152 IF_CLONE_INITIALIZER("ipsec", if_ipsec_clone_create, if_ipsec_clone_destroy); 153 static int max_ipsec_nesting = MAX_IPSEC_NEST; 154 155 /* ARGSUSED */ 156 void 157 ipsecifattach(int count) 158 { 159 160 mutex_init(&ipsec_softcs.lock, MUTEX_DEFAULT, IPL_NONE); 161 LIST_INIT(&ipsec_softcs.list); 162 163 ipsec_psz = pserialize_create(); 164 iv_psref_class = psref_class_create("ipsecvar", IPL_SOFTNET); 165 166 if_clone_attach(&ipsec_cloner); 167 } 168 169 static int 170 if_ipsec_clone_create(struct if_clone *ifc, int unit) 171 { 172 struct ipsec_softc *sc; 173 struct ipsec_variant *var; 174 175 sc = kmem_zalloc(sizeof(*sc), KM_SLEEP); 176 177 if_initname(&sc->ipsec_if, ifc->ifc_name, unit); 178 179 if_ipsec_attach0(sc); 180 181 var = kmem_zalloc(sizeof(*var), KM_SLEEP); 182 var->iv_softc = sc; 183 psref_target_init(&var->iv_psref, iv_psref_class); 184 185 sc->ipsec_var = var; 186 mutex_init(&sc->ipsec_lock, MUTEX_DEFAULT, IPL_NONE); 187 sc->ipsec_ro_percpu = percpu_alloc(sizeof(struct ipsec_ro)); 188 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_init_pc, NULL); 189 190 mutex_enter(&ipsec_softcs.lock); 191 LIST_INSERT_HEAD(&ipsec_softcs.list, sc, ipsec_list); 192 mutex_exit(&ipsec_softcs.lock); 193 return 0; 194 } 195 196 static void 197 if_ipsec_attach0(struct ipsec_softc *sc) 198 { 199 200 sc->ipsec_if.if_addrlen = 0; 201 sc->ipsec_if.if_mtu = IPSEC_MTU; 202 sc->ipsec_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST; 203 /* set ipsec(4) specific default flags. */ 204 sc->ipsec_if.if_flags |= IFF_FWD_IPV6; 205 sc->ipsec_if.if_extflags = IFEF_NO_LINK_STATE_CHANGE | IFEF_MPSAFE; 206 sc->ipsec_if.if_ioctl = if_ipsec_ioctl; 207 sc->ipsec_if.if_output = if_ipsec_output; 208 sc->ipsec_if.if_type = IFT_IPSEC; 209 sc->ipsec_if.if_dlt = DLT_NULL; 210 sc->ipsec_if.if_softc = sc; 211 IFQ_SET_READY(&sc->ipsec_if.if_snd); 212 if_initialize(&sc->ipsec_if); 213 if_alloc_sadl(&sc->ipsec_if); 214 bpf_attach(&sc->ipsec_if, DLT_NULL, sizeof(u_int)); 215 if_register(&sc->ipsec_if); 216 } 217 218 static void 219 if_ipsec_ro_init_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) 220 { 221 struct ipsec_ro *iro = p; 222 223 iro->ir_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NONE); 224 } 225 226 static void 227 if_ipsec_ro_fini_pc(void *p, void *arg __unused, struct cpu_info *ci __unused) 228 { 229 struct ipsec_ro *iro = p; 230 231 rtcache_free(&iro->ir_ro); 232 233 mutex_obj_free(iro->ir_lock); 234 } 235 236 static int 237 if_ipsec_clone_destroy(struct ifnet *ifp) 238 { 239 struct ipsec_softc *sc = ifp->if_softc; 240 struct ipsec_variant *var; 241 int bound; 242 243 mutex_enter(&ipsec_softcs.lock); 244 LIST_REMOVE(sc, ipsec_list); 245 mutex_exit(&ipsec_softcs.lock); 246 247 bound = curlwp_bind(); 248 if_ipsec_delete_tunnel(&sc->ipsec_if); 249 curlwp_bindx(bound); 250 251 bpf_detach(ifp); 252 if_detach(ifp); 253 254 percpu_foreach(sc->ipsec_ro_percpu, if_ipsec_ro_fini_pc, NULL); 255 percpu_free(sc->ipsec_ro_percpu, sizeof(struct ipsec_ro)); 256 257 mutex_destroy(&sc->ipsec_lock); 258 259 var = sc->ipsec_var; 260 kmem_free(var, sizeof(*var)); 261 kmem_free(sc, sizeof(*sc)); 262 263 return 0; 264 } 265 266 static inline bool 267 if_ipsec_nat_t(struct ipsec_softc *sc) 268 { 269 270 return (sc->ipsec_if.if_flags & IFF_NAT_T) != 0; 271 } 272 273 static inline bool 274 if_ipsec_fwd_ipv6(struct ipsec_softc *sc) 275 { 276 277 return (sc->ipsec_if.if_flags & IFF_FWD_IPV6) != 0; 278 } 279 280 int 281 if_ipsec_encap_func(struct mbuf *m, int off, int proto, void *arg) 282 { 283 uint8_t v; 284 struct ipsec_softc *sc; 285 struct ipsec_variant *var = NULL; 286 struct psref psref; 287 int ret = 0; 288 289 sc = arg; 290 KASSERT(sc != NULL); 291 292 if ((sc->ipsec_if.if_flags & IFF_UP) == 0) 293 goto out; 294 295 var = if_ipsec_getref_variant(sc, &psref); 296 if (if_ipsec_variant_is_unconfigured(var)) 297 goto out; 298 299 switch (proto) { 300 case IPPROTO_IPV4: 301 case IPPROTO_IPV6: 302 break; 303 default: 304 goto out; 305 } 306 307 m_copydata(m, 0, sizeof(v), &v); 308 v = (v >> 4) & 0xff; /* Get the IP version number. */ 309 310 switch (v) { 311 #ifdef INET 312 case IPVERSION: { 313 struct ip ip; 314 315 if (m->m_pkthdr.len < sizeof(ip)) 316 goto out; 317 318 m_copydata(m, 0, sizeof(ip), &ip); 319 if (var->iv_psrc->sa_family != AF_INET || 320 var->iv_pdst->sa_family != AF_INET) 321 goto out; 322 ret = ipsecif4_encap_func(m, &ip, var); 323 break; 324 } 325 #endif 326 #ifdef INET6 327 case (IPV6_VERSION >> 4): { 328 struct ip6_hdr ip6; 329 330 if (m->m_pkthdr.len < sizeof(ip6)) 331 goto out; 332 333 m_copydata(m, 0, sizeof(ip6), &ip6); 334 if (var->iv_psrc->sa_family != AF_INET6 || 335 var->iv_pdst->sa_family != AF_INET6) 336 goto out; 337 ret = ipsecif6_encap_func(m, &ip6, var); 338 break; 339 } 340 #endif 341 default: 342 goto out; 343 } 344 345 out: 346 if (var != NULL) 347 if_ipsec_putref_variant(var, &psref); 348 return ret; 349 } 350 351 /* 352 * ipsec(4) I/F may cause infinite recursion calls when misconfigured. 353 * We'll prevent this by introducing upper limit. 354 */ 355 static int 356 if_ipsec_check_nesting(struct ifnet *ifp, struct mbuf *m) 357 { 358 359 return if_tunnel_check_nesting(ifp, m, max_ipsec_nesting); 360 } 361 362 int 363 if_ipsec_output(struct ifnet *ifp, struct mbuf *m, const struct sockaddr *dst, 364 const struct rtentry *rt) 365 { 366 struct ipsec_softc *sc = ifp->if_softc; 367 struct ipsec_variant *var; 368 struct psref psref; 369 int error; 370 int bound; 371 372 IFQ_CLASSIFY(&ifp->if_snd, m, dst->sa_family); 373 374 error = if_ipsec_check_nesting(ifp, m); 375 if (error) { 376 m_freem(m); 377 goto noref_end; 378 } 379 380 if ((ifp->if_flags & IFF_UP) == 0) { 381 m_freem(m); 382 error = ENETDOWN; 383 goto noref_end; 384 } 385 386 387 bound = curlwp_bind(); 388 var = if_ipsec_getref_variant(sc, &psref); 389 if (if_ipsec_variant_is_unconfigured(var)) { 390 m_freem(m); 391 error = ENETDOWN; 392 goto end; 393 } 394 395 m->m_flags &= ~(M_BCAST|M_MCAST); 396 397 /* use DLT_NULL encapsulation here to pass inner af type */ 398 M_PREPEND(m, sizeof(int), M_DONTWAIT); 399 if (!m) { 400 error = ENOBUFS; 401 goto end; 402 } 403 *mtod(m, int *) = dst->sa_family; 404 405 #if INET6 406 /* drop IPv6 packet if IFF_FWD_IPV6 is not set */ 407 if (dst->sa_family == AF_INET6 && 408 !if_ipsec_fwd_ipv6(sc)) { 409 /* 410 * IPv6 packet is not allowed to forward,that is not error. 411 */ 412 error = 0; 413 IF_DROP(&ifp->if_snd); 414 m_freem(m); 415 goto end; 416 } 417 #endif 418 419 error = if_ipsec_out_direct(var, m, dst->sa_family); 420 421 end: 422 if_ipsec_putref_variant(var, &psref); 423 curlwp_bindx(bound); 424 noref_end: 425 if (error) 426 ifp->if_oerrors++; 427 428 return error; 429 } 430 431 static inline int 432 if_ipsec_out_direct(struct ipsec_variant *var, struct mbuf *m, int family) 433 { 434 struct ifnet *ifp = &var->iv_softc->ipsec_if; 435 int error; 436 int len; 437 438 KASSERT(if_ipsec_heldref_variant(var)); 439 KASSERT(var->iv_output != NULL); 440 441 len = m->m_pkthdr.len; 442 443 /* input DLT_NULL frame to BPF */ 444 bpf_mtap(ifp, m); 445 446 /* grab and chop off inner af type */ 447 /* XXX need pullup? */ 448 m_adj(m, sizeof(int)); 449 450 error = var->iv_output(var, family, m); 451 if (error) 452 return error; 453 454 ifp->if_opackets++; 455 ifp->if_obytes += len; 456 457 return 0; 458 } 459 460 void 461 if_ipsec_input(struct mbuf *m, int af, struct ifnet *ifp) 462 { 463 464 KASSERT(ifp != NULL); 465 466 m_set_rcvif(m, ifp); 467 468 bpf_mtap_af(ifp, af, m); 469 470 if_ipsec_in_enqueue(m, af, ifp); 471 472 return; 473 } 474 475 static inline void 476 if_ipsec_in_enqueue(struct mbuf *m, int af, struct ifnet *ifp) 477 { 478 pktqueue_t *pktq; 479 int pktlen; 480 481 /* 482 * Put the packet to the network layer input queue according to the 483 * specified address family. 484 */ 485 switch (af) { 486 #ifdef INET 487 case AF_INET: 488 pktq = ip_pktq; 489 break; 490 #endif 491 #ifdef INET6 492 case AF_INET6: 493 pktq = ip6_pktq; 494 break; 495 #endif 496 default: 497 ifp->if_ierrors++; 498 m_freem(m); 499 return; 500 } 501 502 #if 1 503 const u_int h = curcpu()->ci_index; 504 #else 505 const uint32_t h = pktq_rps_hash(m); 506 #endif 507 pktlen = m->m_pkthdr.len; 508 if (__predict_true(pktq_enqueue(pktq, m, h))) { 509 ifp->if_ibytes += pktlen; 510 ifp->if_ipackets++; 511 } else { 512 m_freem(m); 513 } 514 515 return; 516 } 517 518 static inline int 519 if_ipsec_check_salen(struct sockaddr *addr) 520 { 521 522 switch (addr->sa_family) { 523 #ifdef INET 524 case AF_INET: 525 if (addr->sa_len != sizeof(struct sockaddr_in)) 526 return EINVAL; 527 break; 528 #endif /* INET */ 529 #ifdef INET6 530 case AF_INET6: 531 if (addr->sa_len != sizeof(struct sockaddr_in6)) 532 return EINVAL; 533 break; 534 #endif /* INET6 */ 535 default: 536 return EAFNOSUPPORT; 537 } 538 539 return 0; 540 } 541 542 /* XXX how should we handle IPv6 scope on SIOC[GS]IFPHYADDR? */ 543 int 544 if_ipsec_ioctl(struct ifnet *ifp, u_long cmd, void *data) 545 { 546 struct ipsec_softc *sc = ifp->if_softc; 547 struct ipsec_variant *var = NULL; 548 struct ifreq *ifr = (struct ifreq*)data; 549 struct ifaddr *ifa = (struct ifaddr*)data; 550 int error = 0, size; 551 struct sockaddr *dst, *src; 552 u_long mtu; 553 short oflags = ifp->if_flags; 554 int bound; 555 struct psref psref; 556 557 switch (cmd) { 558 case SIOCINITIFADDR: 559 ifp->if_flags |= IFF_UP; 560 ifa->ifa_rtrequest = p2p_rtrequest; 561 break; 562 563 case SIOCSIFDSTADDR: 564 break; 565 566 case SIOCADDMULTI: 567 case SIOCDELMULTI: 568 switch (ifr->ifr_addr.sa_family) { 569 #ifdef INET 570 case AF_INET: /* IP supports Multicast */ 571 break; 572 #endif /* INET */ 573 #ifdef INET6 574 case AF_INET6: /* IP6 supports Multicast */ 575 break; 576 #endif /* INET6 */ 577 default: /* Other protocols doesn't support Multicast */ 578 error = EAFNOSUPPORT; 579 break; 580 } 581 break; 582 583 case SIOCSIFMTU: 584 mtu = ifr->ifr_mtu; 585 if (mtu < IPSEC_MTU_MIN || mtu > IPSEC_MTU_MAX) 586 return EINVAL; 587 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 588 error = 0; 589 break; 590 591 #ifdef INET 592 case SIOCSIFPHYADDR: 593 #endif 594 #ifdef INET6 595 case SIOCSIFPHYADDR_IN6: 596 #endif /* INET6 */ 597 case SIOCSLIFPHYADDR: 598 switch (cmd) { 599 #ifdef INET 600 case SIOCSIFPHYADDR: 601 src = (struct sockaddr *) 602 &(((struct in_aliasreq *)data)->ifra_addr); 603 dst = (struct sockaddr *) 604 &(((struct in_aliasreq *)data)->ifra_dstaddr); 605 break; 606 #endif /* INET */ 607 #ifdef INET6 608 case SIOCSIFPHYADDR_IN6: 609 src = (struct sockaddr *) 610 &(((struct in6_aliasreq *)data)->ifra_addr); 611 dst = (struct sockaddr *) 612 &(((struct in6_aliasreq *)data)->ifra_dstaddr); 613 break; 614 #endif /* INET6 */ 615 case SIOCSLIFPHYADDR: 616 src = (struct sockaddr *) 617 &(((struct if_laddrreq *)data)->addr); 618 dst = (struct sockaddr *) 619 &(((struct if_laddrreq *)data)->dstaddr); 620 break; 621 default: 622 return EINVAL; 623 } 624 625 /* sa_family must be equal */ 626 if (src->sa_family != dst->sa_family) 627 return EINVAL; 628 629 error = if_ipsec_check_salen(src); 630 if (error) 631 return error; 632 error = if_ipsec_check_salen(dst); 633 if (error) 634 return error; 635 636 /* check sa_family looks sane for the cmd */ 637 switch (cmd) { 638 #ifdef INET 639 case SIOCSIFPHYADDR: 640 if (src->sa_family == AF_INET) 641 break; 642 return EAFNOSUPPORT; 643 #endif /* INET */ 644 #ifdef INET6 645 case SIOCSIFPHYADDR_IN6: 646 if (src->sa_family == AF_INET6) 647 break; 648 return EAFNOSUPPORT; 649 #endif /* INET6 */ 650 case SIOCSLIFPHYADDR: 651 /* checks done in the above */ 652 break; 653 } 654 /* 655 * calls if_ipsec_getref_variant() for other softcs to check 656 * address pair duplicattion 657 */ 658 bound = curlwp_bind(); 659 error = if_ipsec_set_tunnel(&sc->ipsec_if, src, dst); 660 if (error) 661 goto bad; 662 curlwp_bindx(bound); 663 break; 664 665 case SIOCDIFPHYADDR: 666 bound = curlwp_bind(); 667 if_ipsec_delete_tunnel(&sc->ipsec_if); 668 curlwp_bindx(bound); 669 break; 670 671 case SIOCGIFPSRCADDR: 672 #ifdef INET6 673 case SIOCGIFPSRCADDR_IN6: 674 #endif /* INET6 */ 675 bound = curlwp_bind(); 676 var = if_ipsec_getref_variant(sc, &psref); 677 if (var->iv_psrc == NULL) { 678 error = EADDRNOTAVAIL; 679 goto bad; 680 } 681 src = var->iv_psrc; 682 switch (cmd) { 683 #ifdef INET 684 case SIOCGIFPSRCADDR: 685 dst = &ifr->ifr_addr; 686 size = sizeof(ifr->ifr_addr); 687 break; 688 #endif /* INET */ 689 #ifdef INET6 690 case SIOCGIFPSRCADDR_IN6: 691 dst = (struct sockaddr *) 692 &(((struct in6_ifreq *)data)->ifr_addr); 693 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 694 break; 695 #endif /* INET6 */ 696 default: 697 error = EADDRNOTAVAIL; 698 goto bad; 699 } 700 if (src->sa_len > size) { 701 error = EINVAL; 702 goto bad; 703 } 704 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst); 705 if (error) 706 goto bad; 707 if_ipsec_putref_variant(var, &psref); 708 curlwp_bindx(bound); 709 break; 710 711 case SIOCGIFPDSTADDR: 712 #ifdef INET6 713 case SIOCGIFPDSTADDR_IN6: 714 #endif /* INET6 */ 715 bound = curlwp_bind(); 716 var = if_ipsec_getref_variant(sc, &psref); 717 if (var->iv_pdst == NULL) { 718 error = EADDRNOTAVAIL; 719 goto bad; 720 } 721 src = var->iv_pdst; 722 switch (cmd) { 723 #ifdef INET 724 case SIOCGIFPDSTADDR: 725 dst = &ifr->ifr_addr; 726 size = sizeof(ifr->ifr_addr); 727 break; 728 #endif /* INET */ 729 #ifdef INET6 730 case SIOCGIFPDSTADDR_IN6: 731 dst = (struct sockaddr *) 732 &(((struct in6_ifreq *)data)->ifr_addr); 733 size = sizeof(((struct in6_ifreq *)data)->ifr_addr); 734 break; 735 #endif /* INET6 */ 736 default: 737 error = EADDRNOTAVAIL; 738 goto bad; 739 } 740 if (src->sa_len > size) { 741 error = EINVAL; 742 goto bad; 743 } 744 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst); 745 if (error) 746 goto bad; 747 if_ipsec_putref_variant(var, &psref); 748 curlwp_bindx(bound); 749 break; 750 751 case SIOCGLIFPHYADDR: 752 bound = curlwp_bind(); 753 var = if_ipsec_getref_variant(sc, &psref); 754 if (if_ipsec_variant_is_unconfigured(var)) { 755 error = EADDRNOTAVAIL; 756 goto bad; 757 } 758 759 /* copy src */ 760 src = var->iv_psrc; 761 dst = (struct sockaddr *) 762 &(((struct if_laddrreq *)data)->addr); 763 size = sizeof(((struct if_laddrreq *)data)->addr); 764 if (src->sa_len > size) { 765 error = EINVAL; 766 goto bad; 767 } 768 error = IF_IPSEC_GATHER_PSRC_ADDR_PORT(var, dst); 769 if (error) 770 goto bad; 771 772 /* copy dst */ 773 src = var->iv_pdst; 774 dst = (struct sockaddr *) 775 &(((struct if_laddrreq *)data)->dstaddr); 776 size = sizeof(((struct if_laddrreq *)data)->dstaddr); 777 if (src->sa_len > size) { 778 error = EINVAL; 779 goto bad; 780 } 781 error = IF_IPSEC_GATHER_PDST_ADDR_PORT(var, dst); 782 if (error) 783 goto bad; 784 if_ipsec_putref_variant(var, &psref); 785 curlwp_bindx(bound); 786 break; 787 788 default: 789 error = ifioctl_common(ifp, cmd, data); 790 if (!error) { 791 bound = curlwp_bind(); 792 error = if_ipsec_ensure_flags(&sc->ipsec_if, oflags); 793 if (error) 794 goto bad; 795 curlwp_bindx(bound); 796 } 797 break; 798 } 799 return error; 800 801 bad: 802 if (var != NULL) 803 if_ipsec_putref_variant(var, &psref); 804 curlwp_bindx(bound); 805 806 return error; 807 } 808 809 struct encap_funcs { 810 #ifdef INET 811 int (*ef_inet)(struct ipsec_variant *); 812 #endif 813 #ifdef INET6 814 int (*ef_inet6)(struct ipsec_variant *); 815 #endif 816 }; 817 818 static struct encap_funcs ipsec_encap_attach = { 819 #ifdef INET 820 .ef_inet = ipsecif4_attach, 821 #endif 822 #ifdef INET6 823 .ef_inet6 = &ipsecif6_attach, 824 #endif 825 }; 826 827 static struct encap_funcs ipsec_encap_detach = { 828 #ifdef INET 829 .ef_inet = ipsecif4_detach, 830 #endif 831 #ifdef INET6 832 .ef_inet6 = &ipsecif6_detach, 833 #endif 834 }; 835 836 static int 837 if_ipsec_encap_common(struct ipsec_variant *var, struct encap_funcs *funcs) 838 { 839 int error; 840 841 KASSERT(var != NULL); 842 KASSERT(if_ipsec_variant_is_configured(var)); 843 844 switch (var->iv_psrc->sa_family) { 845 #ifdef INET 846 case AF_INET: 847 error = (funcs->ef_inet)(var); 848 break; 849 #endif /* INET */ 850 #ifdef INET6 851 case AF_INET6: 852 error = (funcs->ef_inet6)(var); 853 break; 854 #endif /* INET6 */ 855 default: 856 error = EINVAL; 857 break; 858 } 859 860 return error; 861 } 862 863 static int 864 if_ipsec_encap_attach(struct ipsec_variant *var) 865 { 866 867 return if_ipsec_encap_common(var, &ipsec_encap_attach); 868 } 869 870 static int 871 if_ipsec_encap_detach(struct ipsec_variant *var) 872 { 873 874 return if_ipsec_encap_common(var, &ipsec_encap_detach); 875 } 876 877 /* 878 * Validate and set ipsec(4) I/F configurations. 879 * (1) validate 880 * (1-1) Check the argument src and dst address pair will change 881 * configuration from current src and dst address pair. 882 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair 883 * with argument src and dst address pair, except for NAT-T shared 884 * tunnels. 885 * (2) set 886 * (2-1) Create variant for new configuration. 887 * (2-2) Create temporary "null" variant used to avoid to access 888 * dangling variant while SPs are deleted and added. 889 * (2-3) Swap variant include its SPs. 890 * (2-4) Cleanup last configurations. 891 */ 892 static int 893 if_ipsec_set_tunnel(struct ifnet *ifp, 894 struct sockaddr *src, struct sockaddr *dst) 895 { 896 struct ipsec_softc *sc = ifp->if_softc; 897 struct ipsec_softc *sc2; 898 struct ipsec_variant *ovar, *nvar, *nullvar; 899 struct sockaddr *osrc, *odst; 900 struct sockaddr *nsrc, *ndst; 901 in_port_t nsport = 0, ndport = 0; 902 int error; 903 904 error = encap_lock_enter(); 905 if (error) 906 return error; 907 908 nsrc = sockaddr_dup(src, M_WAITOK); 909 ndst = sockaddr_dup(dst, M_WAITOK); 910 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP); 911 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP); 912 913 mutex_enter(&sc->ipsec_lock); 914 915 ovar = sc->ipsec_var; 916 917 switch(nsrc->sa_family) { 918 #ifdef INET 919 case AF_INET: 920 nsport = satosin(src)->sin_port; 921 /* 922 * avoid confuse SP when NAT-T disabled, 923 * e.g. 924 * expected: 10.0.1.2[any] 10.0.1.1[any] 4(ipv4) 925 * confuse : 10.0.1.2[600] 10.0.1.1[600] 4(ipv4) 926 */ 927 satosin(nsrc)->sin_port = 0; 928 ndport = satosin(dst)->sin_port; 929 satosin(ndst)->sin_port = 0; 930 break; 931 #endif /* INET */ 932 #ifdef INET6 933 case AF_INET6: 934 nsport = satosin6(src)->sin6_port; 935 satosin6(nsrc)->sin6_port = 0; 936 ndport = satosin6(dst)->sin6_port; 937 satosin6(ndst)->sin6_port = 0; 938 break; 939 #endif /* INET6 */ 940 default: 941 log(LOG_DEBUG, 942 "%s: Invalid address family: %d.\n", 943 __func__, src->sa_family); 944 error = EINVAL; 945 goto out; 946 } 947 948 /* 949 * (1-1) Check the argument src and dst address pair will change 950 * configuration from current src and dst address pair. 951 */ 952 if ((ovar->iv_pdst && sockaddr_cmp(ovar->iv_pdst, dst) == 0) && 953 (ovar->iv_psrc && sockaddr_cmp(ovar->iv_psrc, src) == 0) && 954 (ovar->iv_sport == nsport && ovar->iv_dport == ndport)) { 955 /* address and port pair not changed. */ 956 error = 0; 957 goto out; 958 } 959 960 /* 961 * (1-2) Check any ipsec(4) I/F uses duplicated src and dst address pair 962 * with argument src and dst address pair, except for NAT-T shared 963 * tunnels. 964 */ 965 mutex_enter(&ipsec_softcs.lock); 966 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) { 967 struct ipsec_variant *var2; 968 struct psref psref; 969 970 if (sc2 == sc) 971 continue; 972 var2 = if_ipsec_getref_variant(sc2, &psref); 973 if (if_ipsec_variant_is_unconfigured(var2)) { 974 if_ipsec_putref_variant(var2, &psref); 975 continue; 976 } 977 if (if_ipsec_nat_t(sc) || if_ipsec_nat_t(sc2)) { 978 if_ipsec_putref_variant(var2, &psref); 979 continue; /* NAT-T shared tunnel */ 980 } 981 if (sockaddr_cmp(var2->iv_pdst, dst) == 0 && 982 sockaddr_cmp(var2->iv_psrc, src) == 0) { 983 if_ipsec_putref_variant(var2, &psref); 984 mutex_exit(&ipsec_softcs.lock); 985 error = EADDRNOTAVAIL; 986 goto out; 987 } 988 989 if_ipsec_putref_variant(var2, &psref); 990 /* XXX both end must be valid? (I mean, not 0.0.0.0) */ 991 } 992 mutex_exit(&ipsec_softcs.lock); 993 994 995 osrc = ovar->iv_psrc; 996 odst = ovar->iv_pdst; 997 998 /* 999 * (2-1) Create ipsec_variant for new configuration. 1000 */ 1001 if_ipsec_copy_variant(nvar, ovar); 1002 nvar->iv_psrc = nsrc; 1003 nvar->iv_pdst = ndst; 1004 nvar->iv_sport = nsport; 1005 nvar->iv_dport = ndport; 1006 nvar->iv_encap_cookie4 = NULL; 1007 nvar->iv_encap_cookie6 = NULL; 1008 psref_target_init(&nvar->iv_psref, iv_psref_class); 1009 error = if_ipsec_encap_attach(nvar); 1010 if (error) 1011 goto out; 1012 1013 /* 1014 * (2-2) Create temporary "null" variant. 1015 */ 1016 if_ipsec_copy_variant(nullvar, ovar); 1017 if_ipsec_clear_config(nullvar); 1018 psref_target_init(&nullvar->iv_psref, iv_psref_class); 1019 membar_producer(); 1020 /* 1021 * (2-3) Swap variant include its SPs. 1022 */ 1023 error = if_ipsec_update_variant(sc, nvar, nullvar); 1024 if (error) { 1025 if_ipsec_encap_detach(nvar); 1026 goto out; 1027 } 1028 1029 mutex_exit(&sc->ipsec_lock); 1030 1031 /* 1032 * (2-4) Cleanup last configurations. 1033 */ 1034 if (if_ipsec_variant_is_configured(ovar)) 1035 if_ipsec_encap_detach(ovar); 1036 encap_lock_exit(); 1037 1038 if (osrc != NULL) 1039 sockaddr_free(osrc); 1040 if (odst != NULL) 1041 sockaddr_free(odst); 1042 kmem_free(ovar, sizeof(*ovar)); 1043 kmem_free(nullvar, sizeof(*nullvar)); 1044 1045 return 0; 1046 1047 out: 1048 mutex_exit(&sc->ipsec_lock); 1049 encap_lock_exit(); 1050 1051 sockaddr_free(nsrc); 1052 sockaddr_free(ndst); 1053 kmem_free(nvar, sizeof(*nvar)); 1054 kmem_free(nullvar, sizeof(*nullvar)); 1055 1056 return error; 1057 } 1058 1059 /* 1060 * Validate and delete ipsec(4) I/F configurations. 1061 * (1) validate 1062 * (1-1) Check current src and dst address pair are null, 1063 * which means the ipsec(4) I/F is already done deletetunnel. 1064 * (2) delete 1065 * (2-1) Create variant for deleted status. 1066 * (2-2) Create temporary "null" variant used to avoid to access 1067 * dangling variant while SPs are deleted and added. 1068 * NOTE: 1069 * The contents of temporary "null" variant equal to the variant 1070 * of (2-1), however two psref_target_destroy() synchronization 1071 * points are necessary to avoid to access dangling variant 1072 * while SPs are deleted and added. To implement that simply, 1073 * we use the same manner as if_ipsec_set_tunnel(), that is, 1074 * create extra "null" variant and use it temporarily. 1075 * (2-3) Swap variant include its SPs. 1076 * (2-4) Cleanup last configurations. 1077 */ 1078 static void 1079 if_ipsec_delete_tunnel(struct ifnet *ifp) 1080 { 1081 struct ipsec_softc *sc = ifp->if_softc; 1082 struct ipsec_variant *ovar, *nvar, *nullvar; 1083 struct sockaddr *osrc, *odst; 1084 int error; 1085 1086 error = encap_lock_enter(); 1087 if (error) 1088 return; 1089 1090 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP); 1091 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP); 1092 1093 mutex_enter(&sc->ipsec_lock); 1094 1095 ovar = sc->ipsec_var; 1096 osrc = ovar->iv_psrc; 1097 odst = ovar->iv_pdst; 1098 /* 1099 * (1-1) Check current src and dst address pair are null, 1100 * which means the ipsec(4) I/F is already done deletetunnel. 1101 */ 1102 if (osrc == NULL || odst == NULL) { 1103 /* address pair not changed. */ 1104 mutex_exit(&sc->ipsec_lock); 1105 encap_lock_exit(); 1106 kmem_free(nvar, sizeof(*nvar)); 1107 return; 1108 } 1109 1110 /* 1111 * (2-1) Create variant for deleted status. 1112 */ 1113 if_ipsec_copy_variant(nvar, ovar); 1114 if_ipsec_clear_config(nvar); 1115 psref_target_init(&nvar->iv_psref, iv_psref_class); 1116 1117 /* 1118 * (2-2) Create temporary "null" variant used to avoid to access 1119 * dangling variant while SPs are deleted and added. 1120 */ 1121 if_ipsec_copy_variant(nullvar, ovar); 1122 if_ipsec_clear_config(nullvar); 1123 psref_target_init(&nullvar->iv_psref, iv_psref_class); 1124 membar_producer(); 1125 /* 1126 * (2-3) Swap variant include its SPs. 1127 */ 1128 /* if_ipsec_update_variant() does not fail when delete SP only. */ 1129 (void)if_ipsec_update_variant(sc, nvar, nullvar); 1130 1131 mutex_exit(&sc->ipsec_lock); 1132 1133 /* 1134 * (2-4) Cleanup last configurations. 1135 */ 1136 if (if_ipsec_variant_is_configured(ovar)) 1137 if_ipsec_encap_detach(ovar); 1138 encap_lock_exit(); 1139 1140 sockaddr_free(osrc); 1141 sockaddr_free(odst); 1142 kmem_free(ovar, sizeof(*ovar)); 1143 kmem_free(nullvar, sizeof(*nullvar)); 1144 } 1145 1146 /* 1147 * Check IFF_NAT_T and IFF_FWD_IPV6 flags, therefore update SPs if needed. 1148 * (1) check 1149 * (1-1) Check flags are changed. 1150 * (1-2) Check current src and dst address pair. If they are null, 1151 * that means the ipsec(4) I/F is deletetunnel'ed, so it is 1152 * not needed to update. 1153 * (2) update 1154 * (2-1) Create variant for new SPs. 1155 * (2-2) Create temporary "null" variant used to avoid to access 1156 * dangling variant while SPs are deleted and added. 1157 * NOTE: 1158 * There is the same problem as if_ipsec_delete_tunnel(). 1159 * (2-3) Swap variant include its SPs. 1160 * (2-4) Cleanup unused configurations. 1161 * NOTE: use the same encap_cookies. 1162 */ 1163 static int 1164 if_ipsec_ensure_flags(struct ifnet *ifp, short oflags) 1165 { 1166 struct ipsec_softc *sc = ifp->if_softc; 1167 struct ipsec_variant *ovar, *nvar, *nullvar; 1168 int error; 1169 1170 /* 1171 * (1) Check flags are changed. 1172 */ 1173 if ((oflags & (IFF_NAT_T|IFF_FWD_IPV6)) == 1174 (ifp->if_flags & (IFF_NAT_T|IFF_FWD_IPV6))) 1175 return 0; /* flags not changed. */ 1176 1177 error = encap_lock_enter(); 1178 if (error) 1179 return error; 1180 1181 nvar = kmem_zalloc(sizeof(*nvar), KM_SLEEP); 1182 nullvar = kmem_zalloc(sizeof(*nullvar), KM_SLEEP); 1183 1184 mutex_enter(&sc->ipsec_lock); 1185 1186 ovar = sc->ipsec_var; 1187 /* 1188 * (1-2) Check current src and dst address pair. 1189 */ 1190 if (if_ipsec_variant_is_unconfigured(ovar)) { 1191 /* nothing to do */ 1192 mutex_exit(&sc->ipsec_lock); 1193 encap_lock_exit(); 1194 return 0; 1195 } 1196 1197 /* 1198 * (2-1) Create variant for new SPs. 1199 */ 1200 if_ipsec_copy_variant(nvar, ovar); 1201 psref_target_init(&nvar->iv_psref, iv_psref_class); 1202 /* 1203 * (2-2) Create temporary "null" variant used to avoid to access 1204 * dangling variant while SPs are deleted and added. 1205 */ 1206 if_ipsec_copy_variant(nullvar, ovar); 1207 if_ipsec_clear_config(nullvar); 1208 psref_target_init(&nullvar->iv_psref, iv_psref_class); 1209 membar_producer(); 1210 /* 1211 * (2-3) Swap variant include its SPs. 1212 */ 1213 error = if_ipsec_update_variant(sc, nvar, nullvar); 1214 1215 mutex_exit(&sc->ipsec_lock); 1216 encap_lock_exit(); 1217 1218 /* 1219 * (2-4) Cleanup unused configurations. 1220 */ 1221 if (!error) 1222 kmem_free(ovar, sizeof(*ovar)); 1223 else 1224 kmem_free(nvar, sizeof(*ovar)); 1225 kmem_free(nullvar, sizeof(*nullvar)); 1226 1227 return error; 1228 } 1229 1230 /* 1231 * SPD management 1232 */ 1233 1234 /* 1235 * Share SP set with other NAT-T ipsec(4) I/F(s). 1236 * Return 1, when "var" shares SP set. 1237 * Return 0, when "var" cannot share SP set. 1238 * 1239 * NOTE: 1240 * if_ipsec_share_sp() and if_ipsec_unshare_sp() would require global lock 1241 * to exclude other ipsec(4) I/Fs set_tunnel/delete_tunnel. E.g. when ipsec0 1242 * and ipsec1 can share SP set, running ipsec0's set_tunnel and ipsec1's 1243 * set_tunnel causes race. 1244 * Currently, (fortunately) encap_lock works as this global lock. 1245 */ 1246 static int 1247 if_ipsec_share_sp(struct ipsec_variant *var) 1248 { 1249 struct ipsec_softc *sc = var->iv_softc; 1250 struct ipsec_softc *sc2; 1251 struct ipsec_variant *var2; 1252 struct psref psref; 1253 1254 KASSERT(encap_lock_held()); 1255 KASSERT(var->iv_psrc != NULL && var->iv_pdst != NULL); 1256 1257 mutex_enter(&ipsec_softcs.lock); 1258 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) { 1259 if (sc2 == sc) 1260 continue; 1261 var2 = if_ipsec_getref_variant(sc2, &psref); 1262 if (if_ipsec_variant_is_unconfigured(var2)) { 1263 if_ipsec_putref_variant(var2, &psref); 1264 continue; 1265 } 1266 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 || 1267 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) { 1268 if_ipsec_putref_variant(var2, &psref); 1269 continue; 1270 } 1271 1272 break; 1273 } 1274 mutex_exit(&ipsec_softcs.lock); 1275 if (sc2 == NULL) 1276 return 0; /* not shared */ 1277 1278 IV_SP_IN(var) = IV_SP_IN(var2); 1279 IV_SP_IN6(var) = IV_SP_IN6(var2); 1280 IV_SP_OUT(var) = IV_SP_OUT(var2); 1281 IV_SP_OUT6(var) = IV_SP_OUT6(var2); 1282 1283 if_ipsec_putref_variant(var2, &psref); 1284 return 1; /* shared */ 1285 } 1286 1287 /* 1288 * Unshare SP set with other NAT-T ipsec(4) I/F(s). 1289 * Return 1, when "var" shared SP set, and then unshare them. 1290 * Return 0, when "var" did not share SP set. 1291 * 1292 * NOTE: 1293 * See if_ipsec_share_sp()'s note. 1294 */ 1295 static int 1296 if_ipsec_unshare_sp(struct ipsec_variant *var) 1297 { 1298 struct ipsec_softc *sc = var->iv_softc; 1299 struct ipsec_softc *sc2; 1300 struct ipsec_variant *var2; 1301 struct psref psref; 1302 1303 KASSERT(encap_lock_held()); 1304 1305 if (!var->iv_pdst || !var->iv_psrc) 1306 return 0; 1307 1308 mutex_enter(&ipsec_softcs.lock); 1309 LIST_FOREACH(sc2, &ipsec_softcs.list, ipsec_list) { 1310 if (sc2 == sc) 1311 continue; 1312 var2 = if_ipsec_getref_variant(sc2, &psref); 1313 if (!var2->iv_pdst || !var2->iv_psrc) { 1314 if_ipsec_putref_variant(var2, &psref); 1315 continue; 1316 } 1317 if (sockaddr_cmp(var2->iv_pdst, var->iv_pdst) != 0 || 1318 sockaddr_cmp(var2->iv_psrc, var->iv_psrc) != 0) { 1319 if_ipsec_putref_variant(var2, &psref); 1320 continue; 1321 } 1322 1323 break; 1324 } 1325 mutex_exit(&ipsec_softcs.lock); 1326 if (sc2 == NULL) 1327 return 0; /* not shared */ 1328 1329 IV_SP_IN(var) = NULL; 1330 IV_SP_IN6(var) = NULL; 1331 IV_SP_OUT(var) = NULL; 1332 IV_SP_OUT6(var) = NULL; 1333 if_ipsec_putref_variant(var2, &psref); 1334 return 1; /* shared */ 1335 } 1336 1337 static inline void 1338 if_ipsec_add_mbuf_optalign(struct mbuf *m0, void *data, size_t len, bool align) 1339 { 1340 struct mbuf *m; 1341 1342 MGET(m, M_WAIT, MT_DATA); 1343 if (align) { 1344 m->m_len = PFKEY_ALIGN8(len); 1345 memset(mtod(m, void *), 0, m->m_len); 1346 } else 1347 m->m_len = len; 1348 m_copyback(m, 0, len, data); 1349 m_cat(m0, m); 1350 } 1351 1352 static inline void 1353 if_ipsec_add_mbuf(struct mbuf *m0, void *data, size_t len) 1354 { 1355 1356 if_ipsec_add_mbuf_optalign(m0, data, len, true); 1357 } 1358 1359 static inline void 1360 if_ipsec_add_mbuf_addr_port(struct mbuf *m0, struct sockaddr *addr, in_port_t port, bool align) 1361 { 1362 1363 if (port == 0) { 1364 if_ipsec_add_mbuf_optalign(m0, addr, addr->sa_len, align); 1365 } else { 1366 union sockaddr_union addrport_u; 1367 struct sockaddr *addrport = &addrport_u.sa; 1368 1369 if_ipsec_set_addr_port(addrport, addr, port); 1370 if_ipsec_add_mbuf_optalign(m0, addrport, addrport->sa_len, align); 1371 } 1372 } 1373 1374 static inline void 1375 if_ipsec_add_pad(struct mbuf *m0, size_t len) 1376 { 1377 struct mbuf *m; 1378 1379 if (len == 0) 1380 return; 1381 1382 MGET(m, M_WAIT, MT_DATA); 1383 m->m_len = len; 1384 memset(mtod(m, void *), 0, m->m_len); 1385 m_cat(m0, m); 1386 } 1387 1388 static inline size_t 1389 if_ipsec_set_sadb_addr(struct sadb_address *saaddr, struct sockaddr *addr, 1390 int proto, uint16_t exttype) 1391 { 1392 size_t size; 1393 1394 KASSERT(saaddr != NULL); 1395 KASSERT(addr != NULL); 1396 1397 size = sizeof(*saaddr) + PFKEY_ALIGN8(addr->sa_len); 1398 saaddr->sadb_address_len = PFKEY_UNIT64(size); 1399 saaddr->sadb_address_exttype = exttype; 1400 saaddr->sadb_address_proto = proto; 1401 switch (addr->sa_family) { 1402 #ifdef INET 1403 case AF_INET: 1404 saaddr->sadb_address_prefixlen = sizeof(struct in_addr) << 3; 1405 break; 1406 #endif /* INET */ 1407 #ifdef INET6 1408 case AF_INET6: 1409 saaddr->sadb_address_prefixlen = sizeof(struct in6_addr) << 3; 1410 break; 1411 #endif /* INET6 */ 1412 default: 1413 log(LOG_DEBUG, 1414 "%s: Invalid address family: %d.\n", 1415 __func__, addr->sa_family); 1416 break; 1417 } 1418 saaddr->sadb_address_reserved = 0; 1419 1420 return size; 1421 } 1422 1423 static inline size_t 1424 if_ipsec_set_sadb_src(struct sadb_address *sasrc, struct sockaddr *src, 1425 int proto) 1426 { 1427 1428 return if_ipsec_set_sadb_addr(sasrc, src, proto, 1429 SADB_EXT_ADDRESS_SRC); 1430 } 1431 1432 static inline size_t 1433 if_ipsec_set_sadb_dst(struct sadb_address *sadst, struct sockaddr *dst, 1434 int proto) 1435 { 1436 1437 return if_ipsec_set_sadb_addr(sadst, dst, proto, 1438 SADB_EXT_ADDRESS_DST); 1439 } 1440 1441 static inline size_t 1442 if_ipsec_set_sadb_x_policy(struct sadb_x_policy *xpl, 1443 struct sadb_x_ipsecrequest *xisr, uint16_t policy, uint8_t dir, uint32_t id, 1444 uint8_t level, struct sockaddr *src, struct sockaddr *dst) 1445 { 1446 size_t size; 1447 1448 KASSERT(policy != IPSEC_POLICY_IPSEC || xisr != NULL); 1449 1450 size = sizeof(*xpl); 1451 if (policy == IPSEC_POLICY_IPSEC) { 1452 size += PFKEY_ALIGN8(sizeof(*xisr)); 1453 if (src != NULL && dst != NULL) 1454 size += PFKEY_ALIGN8(src->sa_len + dst->sa_len); 1455 } 1456 xpl->sadb_x_policy_len = PFKEY_UNIT64(size); 1457 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; 1458 xpl->sadb_x_policy_type = policy; 1459 xpl->sadb_x_policy_dir = dir; 1460 xpl->sadb_x_policy_reserved = 0; 1461 xpl->sadb_x_policy_id = id; 1462 xpl->sadb_x_policy_reserved2 = 0; 1463 1464 if (policy == IPSEC_POLICY_IPSEC) { 1465 xisr->sadb_x_ipsecrequest_len = PFKEY_ALIGN8(sizeof(*xisr)); 1466 if (src != NULL && dst != NULL) 1467 xisr->sadb_x_ipsecrequest_len += 1468 PFKEY_ALIGN8(src->sa_len + dst->sa_len); 1469 xisr->sadb_x_ipsecrequest_proto = IPPROTO_ESP; 1470 xisr->sadb_x_ipsecrequest_mode = IPSEC_MODE_TRANSPORT; 1471 xisr->sadb_x_ipsecrequest_level = level; 1472 xisr->sadb_x_ipsecrequest_reqid = key_newreqid(); 1473 } 1474 1475 return size; 1476 } 1477 1478 static inline void 1479 if_ipsec_set_sadb_msg(struct sadb_msg *msg, uint16_t extlen, uint8_t msgtype) 1480 { 1481 1482 KASSERT(msg != NULL); 1483 1484 msg->sadb_msg_version = PF_KEY_V2; 1485 msg->sadb_msg_type = msgtype; 1486 msg->sadb_msg_errno = 0; 1487 msg->sadb_msg_satype = SADB_SATYPE_UNSPEC; 1488 msg->sadb_msg_len = PFKEY_UNIT64(sizeof(*msg)) + extlen; 1489 msg->sadb_msg_reserved = 0; 1490 msg->sadb_msg_seq = 0; /* XXXX */ 1491 msg->sadb_msg_pid = 0; /* XXXX */ 1492 } 1493 1494 static inline void 1495 if_ipsec_set_sadb_msg_add(struct sadb_msg *msg, uint16_t extlen) 1496 { 1497 1498 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDADD); 1499 } 1500 1501 static inline void 1502 if_ipsec_set_sadb_msg_del(struct sadb_msg *msg, uint16_t extlen) 1503 { 1504 1505 if_ipsec_set_sadb_msg(msg, extlen, SADB_X_SPDDELETE2); 1506 } 1507 1508 static int 1509 if_ipsec_set_addr_port(struct sockaddr *addrport, struct sockaddr *addr, 1510 in_port_t port) 1511 { 1512 int error = 0; 1513 1514 sockaddr_copy(addrport, addr->sa_len, addr); 1515 1516 switch (addr->sa_family) { 1517 #ifdef INET 1518 case AF_INET: { 1519 struct sockaddr_in *sin = satosin(addrport); 1520 sin->sin_port = port; 1521 break; 1522 } 1523 #endif /* INET */ 1524 #ifdef INET6 1525 case AF_INET6: { 1526 struct sockaddr_in6 *sin6 = satosin6(addrport); 1527 sin6->sin6_port = port; 1528 break; 1529 } 1530 #endif /* INET6 */ 1531 default: 1532 log(LOG_DEBUG, 1533 "%s: Invalid address family: %d.\n", 1534 __func__, addr->sa_family); 1535 error = EINVAL; 1536 } 1537 1538 return error; 1539 } 1540 1541 static struct secpolicy * 1542 if_ipsec_add_sp0(struct sockaddr *src, in_port_t sport, 1543 struct sockaddr *dst, in_port_t dport, 1544 int dir, int proto, int level, u_int policy) 1545 { 1546 struct sadb_msg msg; 1547 struct sadb_address xsrc, xdst; 1548 struct sadb_x_policy xpl; 1549 struct sadb_x_ipsecrequest xisr; 1550 size_t size; 1551 size_t padlen; 1552 uint16_t ext_msg_len = 0; 1553 struct mbuf *m; 1554 1555 memset(&msg, 0, sizeof(msg)); 1556 memset(&xsrc, 0, sizeof(xsrc)); 1557 memset(&xdst, 0, sizeof(xdst)); 1558 memset(&xpl, 0, sizeof(xpl)); 1559 memset(&xisr, 0, sizeof(xisr)); 1560 1561 MGETHDR(m, M_WAIT, MT_DATA); 1562 1563 size = if_ipsec_set_sadb_src(&xsrc, src, proto); 1564 ext_msg_len += PFKEY_UNIT64(size); 1565 size = if_ipsec_set_sadb_dst(&xdst, dst, proto); 1566 ext_msg_len += PFKEY_UNIT64(size); 1567 size = if_ipsec_set_sadb_x_policy(&xpl, &xisr, policy, dir, 0, level, src, dst); 1568 ext_msg_len += PFKEY_UNIT64(size); 1569 if_ipsec_set_sadb_msg_add(&msg, ext_msg_len); 1570 1571 /* build PF_KEY message */ 1572 1573 m->m_len = sizeof(msg); 1574 m_copyback(m, 0, sizeof(msg), &msg); 1575 1576 if_ipsec_add_mbuf(m, &xsrc, sizeof(xsrc)); 1577 /* 1578 * secpolicy.spidx.{src, dst} must not be set port number, 1579 * even if it is used for NAT-T. 1580 */ 1581 if_ipsec_add_mbuf_addr_port(m, src, 0, true); 1582 padlen = PFKEY_UNUNIT64(xsrc.sadb_address_len) 1583 - (sizeof(xsrc) + PFKEY_ALIGN8(src->sa_len)); 1584 if_ipsec_add_pad(m, padlen); 1585 1586 if_ipsec_add_mbuf(m, &xdst, sizeof(xdst)); 1587 /* ditto */ 1588 if_ipsec_add_mbuf_addr_port(m, dst, 0, true); 1589 padlen = PFKEY_UNUNIT64(xdst.sadb_address_len) 1590 - (sizeof(xdst) + PFKEY_ALIGN8(dst->sa_len)); 1591 if_ipsec_add_pad(m, padlen); 1592 1593 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl)); 1594 if (policy == IPSEC_POLICY_IPSEC) { 1595 if_ipsec_add_mbuf(m, &xisr, sizeof(xisr)); 1596 /* 1597 * secpolicy.req->saidx.{src, dst} must be set port number, 1598 * when it is used for NAT-T. 1599 */ 1600 if_ipsec_add_mbuf_addr_port(m, src, sport, false); 1601 if_ipsec_add_mbuf_addr_port(m, dst, dport, false); 1602 } 1603 padlen = PFKEY_UNUNIT64(xpl.sadb_x_policy_len) - sizeof(xpl); 1604 if (src != NULL && dst != NULL) 1605 padlen -= PFKEY_ALIGN8(src->sa_len + dst->sa_len); 1606 if_ipsec_add_pad(m, padlen); 1607 1608 /* key_kpi_spdadd() has already done KEY_SP_REF(). */ 1609 return key_kpi_spdadd(m); 1610 } 1611 1612 static int 1613 if_ipsec_add_sp(struct ipsec_variant *var, 1614 struct sockaddr *src, in_port_t sport, 1615 struct sockaddr *dst, in_port_t dport) 1616 { 1617 struct ipsec_softc *sc = var->iv_softc; 1618 int level; 1619 u_int v6policy; 1620 1621 /* 1622 * must delete sp before add it. 1623 */ 1624 KASSERT(IV_SP_IN(var) == NULL); 1625 KASSERT(IV_SP_OUT(var) == NULL); 1626 KASSERT(IV_SP_IN6(var) == NULL); 1627 KASSERT(IV_SP_OUT6(var) == NULL); 1628 1629 /* 1630 * can be shared? 1631 */ 1632 if (if_ipsec_share_sp(var)) 1633 return 0; 1634 1635 if (if_ipsec_nat_t(sc)) 1636 level = IPSEC_LEVEL_REQUIRE; 1637 else 1638 level = IPSEC_LEVEL_UNIQUE; 1639 1640 if (if_ipsec_fwd_ipv6(sc)) 1641 v6policy = IPSEC_POLICY_IPSEC; 1642 else 1643 v6policy = IPSEC_POLICY_DISCARD; 1644 1645 IV_SP_IN(var) = if_ipsec_add_sp0(dst, dport, src, sport, 1646 IPSEC_DIR_INBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC); 1647 if (IV_SP_IN(var) == NULL) 1648 goto fail; 1649 IV_SP_OUT(var) = if_ipsec_add_sp0(src, sport, dst, dport, 1650 IPSEC_DIR_OUTBOUND, IPPROTO_IPIP, level, IPSEC_POLICY_IPSEC); 1651 if (IV_SP_OUT(var) == NULL) 1652 goto fail; 1653 IV_SP_IN6(var) = if_ipsec_add_sp0(dst, dport, src, sport, 1654 IPSEC_DIR_INBOUND, IPPROTO_IPV6, level, v6policy); 1655 if (IV_SP_IN6(var) == NULL) 1656 goto fail; 1657 IV_SP_OUT6(var) = if_ipsec_add_sp0(src, sport, dst, dport, 1658 IPSEC_DIR_OUTBOUND, IPPROTO_IPV6, level, v6policy); 1659 if (IV_SP_OUT6(var) == NULL) 1660 goto fail; 1661 1662 return 0; 1663 1664 fail: 1665 if (IV_SP_IN6(var) != NULL) { 1666 if_ipsec_del_sp0(IV_SP_IN6(var)); 1667 IV_SP_IN6(var) = NULL; 1668 } 1669 if (IV_SP_OUT(var) != NULL) { 1670 if_ipsec_del_sp0(IV_SP_OUT(var)); 1671 IV_SP_OUT(var) = NULL; 1672 } 1673 if (IV_SP_IN(var) != NULL) { 1674 if_ipsec_del_sp0(IV_SP_IN(var)); 1675 IV_SP_IN(var) = NULL; 1676 } 1677 1678 return EEXIST; 1679 } 1680 1681 static int 1682 if_ipsec_del_sp0(struct secpolicy *sp) 1683 { 1684 struct sadb_msg msg; 1685 struct sadb_x_policy xpl; 1686 size_t size; 1687 uint16_t ext_msg_len = 0; 1688 int error; 1689 struct mbuf *m; 1690 1691 if (sp == NULL) 1692 return 0; 1693 1694 memset(&msg, 0, sizeof(msg)); 1695 memset(&xpl, 0, sizeof(xpl)); 1696 1697 MGETHDR(m, M_WAIT, MT_DATA); 1698 1699 size = if_ipsec_set_sadb_x_policy(&xpl, NULL, 0, 0, sp->id, 0, NULL, NULL); 1700 ext_msg_len += PFKEY_UNIT64(size); 1701 1702 if_ipsec_set_sadb_msg_del(&msg, ext_msg_len); 1703 1704 m->m_len = sizeof(msg); 1705 m_copyback(m, 0, sizeof(msg), &msg); 1706 1707 if_ipsec_add_mbuf(m, &xpl, sizeof(xpl)); 1708 1709 /* unreference correspond to key_kpi_spdadd(). */ 1710 KEY_SP_UNREF(&sp); 1711 error = key_kpi_spddelete2(m); 1712 if (error != 0) { 1713 log(LOG_ERR, "%s: cannot delete SP(ID=%u) (error=%d).\n", 1714 __func__, sp->id, error); 1715 } 1716 return error; 1717 } 1718 1719 static void 1720 if_ipsec_del_sp(struct ipsec_variant *var) 1721 { 1722 1723 /* are the SPs shared? */ 1724 if (if_ipsec_unshare_sp(var)) 1725 return; 1726 1727 (void)if_ipsec_del_sp0(IV_SP_OUT(var)); 1728 (void)if_ipsec_del_sp0(IV_SP_IN(var)); 1729 (void)if_ipsec_del_sp0(IV_SP_OUT6(var)); 1730 (void)if_ipsec_del_sp0(IV_SP_IN6(var)); 1731 IV_SP_IN(var) = NULL; 1732 IV_SP_IN6(var) = NULL; 1733 IV_SP_OUT(var) = NULL; 1734 IV_SP_OUT6(var) = NULL; 1735 } 1736 1737 static int 1738 if_ipsec_replace_sp(struct ipsec_softc *sc, struct ipsec_variant *ovar, 1739 struct ipsec_variant *nvar) 1740 { 1741 in_port_t src_port = 0; 1742 in_port_t dst_port = 0; 1743 struct sockaddr *src; 1744 struct sockaddr *dst; 1745 int error = 0; 1746 1747 KASSERT(mutex_owned(&sc->ipsec_lock)); 1748 1749 if_ipsec_del_sp(ovar); 1750 1751 src = nvar->iv_psrc; 1752 dst = nvar->iv_pdst; 1753 if (if_ipsec_nat_t(sc)) { 1754 /* NAT-T enabled */ 1755 src_port = nvar->iv_sport; 1756 dst_port = nvar->iv_dport; 1757 } 1758 if (src && dst) 1759 error = if_ipsec_add_sp(nvar, src, src_port, dst, dst_port); 1760 1761 return error; 1762 } 1763 1764 /* 1765 * ipsec_variant and its SPs update API. 1766 * 1767 * Assumption: 1768 * reader side dereferences sc->ipsec_var in reader critical section only, 1769 * that is, all of reader sides do not reader the sc->ipsec_var after 1770 * pserialize_perform(). 1771 */ 1772 static int 1773 if_ipsec_update_variant(struct ipsec_softc *sc, struct ipsec_variant *nvar, 1774 struct ipsec_variant *nullvar) 1775 { 1776 struct ifnet *ifp = &sc->ipsec_if; 1777 struct ipsec_variant *ovar = sc->ipsec_var; 1778 int error; 1779 1780 KASSERT(mutex_owned(&sc->ipsec_lock)); 1781 1782 /* 1783 * To keep consistency between ipsec(4) I/F settings and SPs, 1784 * we stop packet processing while replacing SPs, that is, we set 1785 * "null" config variant to sc->ipsec_var. 1786 */ 1787 sc->ipsec_var = nullvar; 1788 pserialize_perform(ipsec_psz); 1789 psref_target_destroy(&ovar->iv_psref, iv_psref_class); 1790 1791 error = if_ipsec_replace_sp(sc, ovar, nvar); 1792 if (!error) 1793 sc->ipsec_var = nvar; 1794 else { 1795 sc->ipsec_var = ovar; /* rollback */ 1796 psref_target_init(&ovar->iv_psref, iv_psref_class); 1797 } 1798 1799 pserialize_perform(ipsec_psz); 1800 psref_target_destroy(&nullvar->iv_psref, iv_psref_class); 1801 1802 if (if_ipsec_variant_is_configured(sc->ipsec_var)) 1803 ifp->if_flags |= IFF_RUNNING; 1804 else 1805 ifp->if_flags &= ~IFF_RUNNING; 1806 1807 return error; 1808 } 1809