1 /* $OpenBSD: ip_spd.c,v 1.39 2001/08/21 06:48:55 angelos Exp $ */ 2 /* 3 * The author of this code is Angelos D. Keromytis (angelos@cis.upenn.edu) 4 * 5 * Copyright (c) 2000-2001 Angelos D. Keromytis. 6 * 7 * Permission to use, copy, and modify this software with or without fee 8 * is hereby granted, provided that this entire notice is included in 9 * all copies of any software which is or includes a copy or 10 * modification of this software. 11 * You may use this code under the GNU public license if you so wish. Please 12 * contribute changes back to the authors under this freer than GPL license 13 * so that we may further the use of strong encryption without limitations to 14 * all. 15 * 16 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTY. IN PARTICULAR, NONE OF THE AUTHORS MAKES ANY 18 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 19 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 20 * PURPOSE. 21 */ 22 23 #include <sys/param.h> 24 #include <sys/systm.h> 25 #include <sys/mbuf.h> 26 #include <sys/socket.h> 27 #include <sys/kernel.h> 28 29 #include <net/if.h> 30 #include <net/route.h> 31 #include <net/netisr.h> 32 33 #ifdef INET 34 #include <netinet/in.h> 35 #include <netinet/in_systm.h> 36 #include <netinet/ip.h> 37 #include <netinet/in_pcb.h> 38 #include <netinet/in_var.h> 39 #endif /* INET */ 40 41 #ifdef INET6 42 #ifndef INET 43 #include <netinet/in.h> 44 #endif 45 #include <netinet6/in6_var.h> 46 #endif /* INET6 */ 47 48 #include <netinet/ip_ipsp.h> 49 #include <net/pfkeyv2.h> 50 51 #ifdef ENCDEBUG 52 #define DPRINTF(x) if (encdebug) printf x 53 #else 54 #define DPRINTF(x) 55 #endif 56 57 struct pool ipsec_policy_pool; 58 struct pool ipsec_acquire_pool; 59 int ipsec_policy_pool_initialized = 0; 60 int ipsec_acquire_pool_initialized = 0; 61 62 /* 63 * Lookup at the SPD based on the headers contained on the mbuf. The second 64 * argument indicates what protocol family the header at the beginning of 65 * the mbuf is. hlen is the the offset of the transport protocol header 66 * in the mbuf. 67 * 68 * Return combinations (of return value and in *error): 69 * - NULL/0 -> no IPsec required on packet 70 * - NULL/-EINVAL -> silently drop the packet 71 * - NULL/errno -> drop packet and return error 72 * or a pointer to a TDB (and 0 in *error). 73 * 74 * In the case of incoming flows, only the first three combinations are 75 * returned. 76 */ 77 struct tdb * 78 ipsp_spd_lookup(struct mbuf *m, int af, int hlen, int *error, int direction, 79 struct tdb *tdbp, struct inpcb *inp) 80 { 81 struct route_enc re0, *re = &re0; 82 union sockaddr_union sdst, ssrc; 83 struct sockaddr_encap *ddst; 84 struct ipsec_policy *ipo; 85 int signore = 0, dignore = 0; 86 87 /* 88 * If there are no flows in place, there's no point 89 * continuing with the SPD lookup. 90 */ 91 if (!ipsec_in_use && inp == NULL) { 92 *error = 0; 93 return NULL; 94 } 95 96 /* 97 * If an input packet is destined to a BYPASS socket, just accept it. 98 */ 99 if ((inp != NULL) && (direction == IPSP_DIRECTION_IN) && 100 (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) && 101 (inp->inp_seclevel[SL_ESP_NETWORK] == IPSEC_LEVEL_BYPASS) && 102 (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) { 103 *error = 0; 104 return NULL; 105 } 106 107 bzero((caddr_t) re, sizeof(struct route_enc)); 108 bzero((caddr_t) &sdst, sizeof(union sockaddr_union)); 109 bzero((caddr_t) &ssrc, sizeof(union sockaddr_union)); 110 ddst = (struct sockaddr_encap *) &re->re_dst; 111 ddst->sen_family = PF_KEY; 112 ddst->sen_len = SENT_LEN; 113 114 switch (af) { 115 #ifdef INET 116 case AF_INET: 117 ddst->sen_direction = direction; 118 ddst->sen_type = SENT_IP4; 119 120 m_copydata(m, offsetof(struct ip, ip_src), 121 sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_src)); 122 m_copydata(m, offsetof(struct ip, ip_dst), 123 sizeof(struct in_addr), (caddr_t) &(ddst->sen_ip_dst)); 124 m_copydata(m, offsetof(struct ip, ip_p), sizeof(u_int8_t), 125 (caddr_t) &(ddst->sen_proto)); 126 127 sdst.sin.sin_family = ssrc.sin.sin_family = AF_INET; 128 sdst.sin.sin_len = ssrc.sin.sin_len = 129 sizeof(struct sockaddr_in); 130 ssrc.sin.sin_addr = ddst->sen_ip_src; 131 sdst.sin.sin_addr = ddst->sen_ip_dst; 132 133 /* 134 * If TCP/UDP, extract the port numbers to use in the lookup. 135 */ 136 switch (ddst->sen_proto) { 137 case IPPROTO_UDP: 138 case IPPROTO_TCP: 139 /* Make sure there's enough data in the packet. */ 140 if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) { 141 *error = EINVAL; 142 return NULL; 143 } 144 145 /* 146 * Luckily, the offset of the src/dst ports in 147 * both the UDP and TCP headers is the same (first 148 * two 16-bit values in the respective headers), 149 * so we can just copy them. 150 */ 151 m_copydata(m, hlen, sizeof(u_int16_t), 152 (caddr_t) &(ddst->sen_sport)); 153 m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t), 154 (caddr_t) &(ddst->sen_dport)); 155 break; 156 157 default: 158 ddst->sen_sport = 0; 159 ddst->sen_dport = 0; 160 } 161 162 break; 163 #endif /* INET */ 164 165 #ifdef INET6 166 case AF_INET6: 167 ddst->sen_type = SENT_IP6; 168 ddst->sen_ip6_direction = direction; 169 170 m_copydata(m, offsetof(struct ip6_hdr, ip6_src), 171 sizeof(struct in6_addr), 172 (caddr_t) &(ddst->sen_ip6_src)); 173 m_copydata(m, offsetof(struct ip6_hdr, ip6_dst), 174 sizeof(struct in6_addr), 175 (caddr_t) &(ddst->sen_ip6_dst)); 176 m_copydata(m, offsetof(struct ip6_hdr, ip6_nxt), 177 sizeof(u_int8_t), 178 (caddr_t) &(ddst->sen_ip6_proto)); 179 180 sdst.sin6.sin6_family = ssrc.sin6.sin6_family = AF_INET6; 181 sdst.sin6.sin6_len = ssrc.sin6.sin6_family = 182 sizeof(struct sockaddr_in6); 183 ssrc.sin6.sin6_addr = ddst->sen_ip6_src; 184 sdst.sin6.sin6_addr = ddst->sen_ip6_dst; 185 186 /* 187 * If TCP/UDP, extract the port numbers to use in the lookup. 188 */ 189 switch (ddst->sen_ip6_proto) { 190 case IPPROTO_UDP: 191 case IPPROTO_TCP: 192 /* Make sure there's enough data in the packet. */ 193 if (m->m_pkthdr.len < hlen + 2 * sizeof(u_int16_t)) { 194 *error = EINVAL; 195 return NULL; 196 } 197 198 /* 199 * Luckily, the offset of the src/dst ports in 200 * both the UDP and TCP headers is the same 201 * (first two 16-bit values in the respective 202 * headers), so we can just copy them. 203 */ 204 m_copydata(m, hlen, sizeof(u_int16_t), 205 (caddr_t) &(ddst->sen_ip6_sport)); 206 m_copydata(m, hlen + sizeof(u_int16_t), sizeof(u_int16_t), 207 (caddr_t) &(ddst->sen_ip6_dport)); 208 break; 209 210 default: 211 ddst->sen_ip6_sport = 0; 212 ddst->sen_ip6_dport = 0; 213 } 214 215 break; 216 #endif /* INET6 */ 217 218 default: 219 *error = EAFNOSUPPORT; 220 return NULL; 221 } 222 223 /* Actual SPD lookup. */ 224 rtalloc((struct route *) re); 225 if (re->re_rt == NULL) { 226 /* 227 * Return whatever the socket requirements are, there are no 228 * system-wide policies. 229 */ 230 *error = 0; 231 return ipsp_spd_inp(m, af, hlen, error, direction, 232 tdbp, inp, NULL); 233 } 234 235 /* Sanity check. */ 236 if ((re->re_rt->rt_gateway == NULL) || 237 (((struct sockaddr_encap *) re->re_rt->rt_gateway)->sen_type != 238 SENT_IPSP)) { 239 RTFREE(re->re_rt); 240 *error = EHOSTUNREACH; 241 return NULL; 242 } 243 244 ipo = ((struct sockaddr_encap *) (re->re_rt->rt_gateway))->sen_ipsp; 245 RTFREE(re->re_rt); 246 if (ipo == NULL) { 247 *error = EHOSTUNREACH; 248 return NULL; 249 } 250 251 switch (ipo->ipo_type) { 252 case IPSP_PERMIT: 253 *error = 0; 254 return ipsp_spd_inp(m, af, hlen, error, direction, tdbp, 255 inp, ipo); 256 257 case IPSP_DENY: 258 *error = EHOSTUNREACH; 259 return NULL; 260 261 case IPSP_IPSEC_USE: 262 case IPSP_IPSEC_ACQUIRE: 263 case IPSP_IPSEC_REQUIRE: 264 case IPSP_IPSEC_DONTACQ: 265 /* Nothing more needed here. */ 266 break; 267 268 default: 269 *error = EINVAL; 270 return NULL; 271 } 272 273 /* Check for non-specific destination in the policy. */ 274 switch (ipo->ipo_dst.sa.sa_family) { 275 #ifdef INET 276 case AF_INET: 277 if ((ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_ANY) || 278 (ipo->ipo_dst.sin.sin_addr.s_addr == INADDR_BROADCAST)) 279 dignore = 1; 280 break; 281 #endif /* INET */ 282 283 #ifdef INET6 284 case AF_INET6: 285 if ((IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_dst.sin6.sin6_addr)) || 286 (bcmp(&ipo->ipo_dst.sin6.sin6_addr, &in6mask128, 287 sizeof(in6mask128)) == 0)) 288 dignore = 1; 289 break; 290 #endif /* INET6 */ 291 } 292 293 /* Likewise for source. */ 294 switch (ipo->ipo_src.sa.sa_family) { 295 #ifdef INET 296 case AF_INET: 297 if (ipo->ipo_src.sin.sin_addr.s_addr == INADDR_ANY) 298 signore = 1; 299 break; 300 #endif /* INET */ 301 302 #ifdef INET6 303 case AF_INET6: 304 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_src.sin6.sin6_addr)) 305 signore = 1; 306 break; 307 #endif /* INET6 */ 308 } 309 310 /* Do we have a cached entry ? If so, check if it's still valid. */ 311 if ((ipo->ipo_tdb) && (ipo->ipo_tdb->tdb_flags & TDBF_INVALID)) { 312 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 313 ipo_tdb_next); 314 ipo->ipo_tdb = NULL; 315 } 316 317 /* Outgoing packet policy check. */ 318 if (direction == IPSP_DIRECTION_OUT) { 319 /* 320 * If the packet is destined for the policy-specified 321 * gateway/endhost, and the socket has the BYPASS 322 * option set, skip IPsec processing. 323 */ 324 if ((inp != NULL) && 325 (inp->inp_seclevel[SL_ESP_TRANS] == IPSEC_LEVEL_BYPASS) && 326 (inp->inp_seclevel[SL_ESP_NETWORK] == 327 IPSEC_LEVEL_BYPASS) && 328 (inp->inp_seclevel[SL_AUTH] == IPSEC_LEVEL_BYPASS)) { 329 /* Direct match. */ 330 if (dignore || 331 !bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len)) { 332 *error = 0; 333 return NULL; 334 } 335 } 336 337 /* Check that the cached TDB (if present), is appropriate. */ 338 if (ipo->ipo_tdb) { 339 if ((ipo->ipo_last_searched <= ipsec_last_added) || 340 (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) || 341 bcmp(dignore ? &sdst : &ipo->ipo_dst, 342 &ipo->ipo_tdb->tdb_dst, 343 ipo->ipo_tdb->tdb_dst.sa.sa_len)) 344 goto nomatchout; 345 346 /* Match source ID. */ 347 if (ipo->ipo_srcid) { 348 if (ipo->ipo_tdb->tdb_srcid == NULL || 349 !ipsp_ref_match(ipo->ipo_srcid, 350 ipo->ipo_tdb->tdb_srcid)) 351 goto nomatchout; 352 } 353 354 /* Match destination ID. */ 355 if (ipo->ipo_dstid) { 356 if (ipo->ipo_tdb->tdb_dstid == NULL || 357 !ipsp_ref_match(ipo->ipo_dstid, 358 ipo->ipo_tdb->tdb_dstid)) 359 goto nomatchout; 360 } 361 362 /* Match local credentials used. */ 363 if (ipo->ipo_local_cred) { 364 if (ipo->ipo_tdb->tdb_local_cred == NULL || 365 !ipsp_ref_match(ipo->ipo_local_cred, 366 ipo->ipo_tdb->tdb_local_cred)) 367 goto nomatchout; 368 } 369 370 /* Cached entry is good. */ 371 return ipsp_spd_inp(m, af, hlen, error, direction, 372 tdbp, inp, ipo); 373 374 nomatchout: 375 /* Cached TDB was not good. */ 376 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 377 ipo_tdb_next); 378 ipo->ipo_tdb = NULL; 379 ipo->ipo_last_searched = 0; 380 } 381 382 /* 383 * If no SA has been added since the last time we did a 384 * lookup, there's no point searching for one. However, if the 385 * destination gateway is left unspecified (or is all-1's), 386 * always lookup since this is a generic-match rule 387 * (otherwise, we can have situations where SAs to some 388 * destinations exist but are not used, possibly leading to an 389 * explosion in the number of acquired SAs). 390 */ 391 if (ipo->ipo_last_searched <= ipsec_last_added) { 392 /* "Touch" the entry. */ 393 if (dignore == 0) 394 ipo->ipo_last_searched = time.tv_sec; 395 396 /* Find an appropriate SA from the existing ones. */ 397 ipo->ipo_tdb = 398 gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst, 399 ipo, m, af); 400 if (ipo->ipo_tdb) { 401 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, 402 ipo, ipo_tdb_next); 403 *error = 0; 404 return ipsp_spd_inp(m, af, hlen, error, 405 direction, tdbp, inp, ipo); 406 } 407 } 408 409 /* So, we don't have an SA -- just a policy. */ 410 switch (ipo->ipo_type) { 411 case IPSP_IPSEC_REQUIRE: 412 /* Acquire SA through key management. */ 413 if (ipsp_acquire_sa(ipo, 414 dignore ? &sdst : &ipo->ipo_dst, 415 signore ? NULL : &ipo->ipo_src, ddst, m) != 0) { 416 *error = EACCES; 417 return NULL; 418 } 419 420 /* Fall through */ 421 case IPSP_IPSEC_DONTACQ: 422 *error = -EINVAL; /* Silently drop packet. */ 423 return NULL; 424 425 case IPSP_IPSEC_ACQUIRE: 426 /* Acquire SA through key management. */ 427 ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst, 428 signore ? NULL : &ipo->ipo_src, ddst, NULL); 429 430 /* Fall through */ 431 case IPSP_IPSEC_USE: 432 *error = 0; 433 return ipsp_spd_inp(m, af, hlen, error, direction, 434 tdbp, inp, ipo); 435 } 436 } else { /* IPSP_DIRECTION_IN */ 437 if (tdbp != NULL) { 438 /* Direct match in the cache. */ 439 if (ipo->ipo_tdb == tdbp) { 440 *error = 0; 441 return ipsp_spd_inp(m, af, hlen, error, 442 direction, tdbp, inp, ipo); 443 } 444 445 if (bcmp(dignore ? &ssrc : &ipo->ipo_dst, 446 &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) || 447 (ipo->ipo_sproto != tdbp->tdb_sproto)) 448 goto nomatchin; 449 450 /* Match source ID. */ 451 if (ipo->ipo_srcid) { 452 if (tdbp->tdb_dstid == NULL || 453 !ipsp_ref_match(ipo->ipo_srcid, 454 tdbp->tdb_dstid)) 455 goto nomatchin; 456 } 457 458 /* Match destination ID. */ 459 if (ipo->ipo_dstid) { 460 if (tdbp->tdb_srcid == NULL || 461 !ipsp_ref_match(ipo->ipo_dstid, 462 tdbp->tdb_srcid)) 463 goto nomatchin; 464 } 465 466 /* Add it to the cache. */ 467 if (ipo->ipo_tdb) 468 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, 469 ipo, ipo_tdb_next); 470 ipo->ipo_tdb = tdbp; 471 TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo, 472 ipo_tdb_next); 473 *error = 0; 474 return ipsp_spd_inp(m, af, hlen, error, direction, 475 tdbp, inp, ipo); 476 477 nomatchin: /* Nothing needed here, falling through */ 478 } 479 480 /* Check whether cached entry applies. */ 481 if (ipo->ipo_tdb) { 482 /* 483 * We only need to check that the correct 484 * security protocol and security gateway are 485 * set; credentials/IDs will be the same, 486 * since the cached entry is linked on this 487 * policy. 488 */ 489 if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto && 490 !bcmp(&ipo->ipo_tdb->tdb_src, 491 dignore ? &ssrc : &ipo->ipo_dst, 492 ipo->ipo_tdb->tdb_src.sa.sa_len)) 493 goto skipinputsearch; 494 495 /* Not applicable, unlink. */ 496 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 497 ipo_tdb_next); 498 ipo->ipo_last_searched = 0; 499 ipo->ipo_tdb = NULL; 500 } 501 502 /* Find whether there exists an appropriate SA. */ 503 if (ipo->ipo_last_searched <= ipsec_last_added) { 504 if (dignore == 0) 505 ipo->ipo_last_searched = time.tv_sec; 506 507 ipo->ipo_tdb = 508 gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst, 509 ipo, m, af); 510 if (ipo->ipo_tdb) 511 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, 512 ipo, ipo_tdb_next); 513 } 514 skipinputsearch: 515 516 switch (ipo->ipo_type) { 517 case IPSP_IPSEC_REQUIRE: 518 /* If appropriate SA exists, don't acquire another. */ 519 if (ipo->ipo_tdb) { 520 *error = -EINVAL; 521 return NULL; 522 } 523 524 /* Acquire SA through key management. */ 525 if ((*error = ipsp_acquire_sa(ipo, 526 dignore ? &ssrc : &ipo->ipo_dst, 527 signore ? NULL : &ipo->ipo_src, ddst, m)) != 0) 528 return NULL; 529 530 /* Fall through */ 531 case IPSP_IPSEC_DONTACQ: 532 /* Drop packet. */ 533 *error = -EINVAL; 534 return NULL; 535 536 case IPSP_IPSEC_ACQUIRE: 537 /* If appropriate SA exists, don't acquire another. */ 538 if (ipo->ipo_tdb) { 539 *error = 0; 540 return ipsp_spd_inp(m, af, hlen, error, 541 direction, tdbp, inp, ipo); 542 } 543 544 /* Acquire SA through key management. */ 545 ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst, 546 signore ? NULL : &ipo->ipo_src, ddst, NULL); 547 548 /* Fall through */ 549 case IPSP_IPSEC_USE: 550 *error = 0; 551 return ipsp_spd_inp(m, af, hlen, error, direction, 552 tdbp, inp, ipo); 553 } 554 } 555 556 /* Shouldn't ever get this far. */ 557 *error = EINVAL; 558 return NULL; 559 } 560 561 /* 562 * Delete a policy from the SPD. 563 */ 564 int 565 ipsec_delete_policy(struct ipsec_policy *ipo) 566 { 567 struct ipsec_acquire *ipa; 568 int err = 0; 569 570 /* Delete from SPD. */ 571 if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET)) 572 err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr, 573 (struct sockaddr *) 0, 574 (struct sockaddr *) &ipo->ipo_mask, 575 0, (struct rtentry **) 0); 576 577 if (ipo->ipo_tdb != NULL) 578 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 579 ipo_tdb_next); 580 581 while ((ipa = TAILQ_FIRST(&ipo->ipo_acquires)) != NULL) 582 ipsp_delete_acquire(ipa); 583 584 TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list); 585 586 if (ipo->ipo_srcid) 587 ipsp_reffree(ipo->ipo_srcid); 588 if (ipo->ipo_dstid) 589 ipsp_reffree(ipo->ipo_dstid); 590 if (ipo->ipo_local_cred) 591 ipsp_reffree(ipo->ipo_local_cred); 592 if (ipo->ipo_local_auth) 593 ipsp_reffree(ipo->ipo_local_cred); 594 595 pool_put(&ipsec_policy_pool, ipo); 596 597 ipsec_in_use--; 598 599 return err; 600 } 601 602 #ifdef notyet 603 /* 604 * Add a policy to the SPD. 605 */ 606 struct ipsec_policy * 607 ipsec_add_policy(struct sockaddr_encap *dst, struct sockaddr_encap *mask, 608 union sockaddr_union *sdst, int type, int sproto) 609 { 610 struct sockaddr_encap encapgw; 611 struct ipsec_policy *ipon; 612 613 if (ipsec_policy_pool_initialized == 0) { 614 ipsec_policy_pool_initialized = 1; 615 pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy), 616 0, 0, PR_FREEHEADER, "ipsec policy", 0, NULL, NULL, 617 M_IPSEC_POLICY); 618 } 619 620 ipon = pool_get(&ipsec_policy_pool, 0); 621 if (ipon == NULL) 622 return NULL; 623 624 bzero(ipon, sizeof(struct ipsec_policy)); 625 bzero((caddr_t) &encapgw, sizeof(struct sockaddr_encap)); 626 627 encapgw.sen_len = SENT_LEN; 628 encapgw.sen_family = PF_KEY; 629 encapgw.sen_type = SENT_IPSP; 630 encapgw.sen_ipsp = ipon; 631 632 if (rtrequest(RTM_ADD, (struct sockaddr *) dst, 633 (struct sockaddr *) &encapgw, (struct sockaddr *) mask, 634 RTF_UP | RTF_GATEWAY | RTF_STATIC, (struct rtentry **) 0) != 0) { 635 DPRINTF(("ipsec_add_policy: failed to add policy\n")); 636 pool_put(&ipsec_policy_pool, ipon); 637 return NULL; 638 } 639 640 ipsec_in_use++; 641 642 bcopy(dst, &ipon->ipo_addr, sizeof(struct sockaddr_encap)); 643 bcopy(mask, &ipon->ipo_mask, sizeof(struct sockaddr_encap)); 644 bcopy(sdst, &ipon->ipo_dst, sizeof(union sockaddr_union)); 645 ipon->ipo_sproto = sproto; 646 ipon->ipo_type = type; 647 648 TAILQ_INIT(&ipon->ipo_acquires); 649 TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list); 650 651 return ipon; 652 } 653 #endif 654 655 /* 656 * Delete a pending IPsec acquire record. 657 */ 658 void 659 ipsp_delete_acquire(void *v) 660 { 661 struct ipsec_acquire *ipa = v; 662 663 timeout_del(&ipa->ipa_timeout); 664 TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next); 665 if (ipa->ipa_policy != NULL) 666 TAILQ_REMOVE(&ipa->ipa_policy->ipo_acquires, ipa, 667 ipa_ipo_next); 668 pool_put(&ipsec_acquire_pool, ipa); 669 } 670 671 /* 672 * Find out if there's an ACQUIRE pending. 673 * XXX Need a better structure. 674 */ 675 struct ipsec_acquire * 676 ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw) 677 { 678 struct ipsec_acquire *ipa; 679 680 TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) { 681 if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len)) 682 return ipa; 683 } 684 685 return NULL; 686 } 687 688 /* 689 * Signal key management that we need an SA. If we're given an mbuf, store 690 * it and retransmit the packet if/when we have an SA in place. 691 */ 692 int 693 ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw, 694 union sockaddr_union *laddr, struct sockaddr_encap *ddst, struct mbuf *m) 695 { 696 struct ipsec_acquire *ipa; 697 #ifdef INET6 698 int i; 699 #endif 700 701 /* Check whether request has been made already. */ 702 if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL) 703 return 0; 704 705 /* Add request in cache and proceed. */ 706 if (ipsec_acquire_pool_initialized == 0) { 707 ipsec_acquire_pool_initialized = 1; 708 pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire), 709 0, 0, PR_FREEHEADER, "ipsec acquire", 0, NULL, 710 NULL, M_IPSEC_POLICY); 711 } 712 713 ipa = pool_get(&ipsec_acquire_pool, 0); 714 if (ipa == NULL) 715 return ENOMEM; 716 717 bzero(ipa, sizeof(struct ipsec_acquire)); 718 bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union)); 719 720 timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa); 721 722 ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN; 723 ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY; 724 725 /* Just copy the right information. */ 726 switch (ipo->ipo_addr.sen_type) { 727 #ifdef INET 728 case SENT_IP4: 729 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4; 730 ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction; 731 ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction; 732 733 if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY || 734 ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY || 735 ipsp_is_unspecified(ipo->ipo_dst)) { 736 ipa->ipa_info.sen_ip_src = ddst->sen_ip_src; 737 ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST; 738 } else { 739 ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src; 740 ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src; 741 } 742 743 if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY || 744 ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY || 745 ipsp_is_unspecified(ipo->ipo_dst)) { 746 ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst; 747 ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST; 748 } else { 749 ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst; 750 ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst; 751 } 752 753 ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto; 754 ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto; 755 756 if (ipo->ipo_addr.sen_proto) { 757 ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport; 758 ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport; 759 760 ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport; 761 ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport; 762 } 763 break; 764 #endif /* INET */ 765 766 #ifdef INET6 767 case SENT_IP6: 768 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6; 769 ipa->ipa_info.sen_ip6_direction = 770 ipo->ipo_addr.sen_ip6_direction; 771 ipa->ipa_mask.sen_ip6_direction = 772 ipo->ipo_mask.sen_ip6_direction; 773 774 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) || 775 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) || 776 ipsp_is_unspecified(ipo->ipo_dst)) { 777 ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src; 778 for (i = 0; i < 16; i++) 779 ipa->ipa_mask.sen_ip6_src.s6_addr8[i] = 0xff; 780 } else { 781 ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src; 782 ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src; 783 } 784 785 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) || 786 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) || 787 ipsp_is_unspecified(ipo->ipo_dst)) { 788 ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst; 789 for (i = 0; i < 16; i++) 790 ipa->ipa_mask.sen_ip6_dst.s6_addr8[i] = 0xff; 791 } else { 792 ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst; 793 ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst; 794 } 795 796 ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto; 797 ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto; 798 799 if (ipo->ipo_mask.sen_ip6_proto) { 800 ipa->ipa_info.sen_ip6_sport = 801 ipo->ipo_addr.sen_ip6_sport; 802 ipa->ipa_mask.sen_ip6_sport = 803 ipo->ipo_mask.sen_ip6_sport; 804 ipa->ipa_info.sen_ip6_dport = 805 ipo->ipo_addr.sen_ip6_dport; 806 ipa->ipa_mask.sen_ip6_dport = 807 ipo->ipo_mask.sen_ip6_dport; 808 } 809 break; 810 #endif /* INET6 */ 811 812 default: 813 pool_put(&ipsec_acquire_pool, ipa); 814 return 0; 815 } 816 817 timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz); 818 819 TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next); 820 TAILQ_INSERT_TAIL(&ipo->ipo_acquires, ipa, ipa_ipo_next); 821 ipa->ipa_policy = ipo; 822 823 /* PF_KEYv2 notification message. */ 824 return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst); 825 } 826 827 /* 828 * Deal with PCB security requirements. 829 */ 830 struct tdb * 831 ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction, 832 struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo) 833 { 834 /* XXX */ 835 if (ipo != NULL) 836 return ipo->ipo_tdb; 837 else 838 return NULL; 839 } 840 841 /* 842 * Find a pending ACQUIRE record based on its sequence number. 843 * XXX Need to use a better data structure. 844 */ 845 struct ipsec_acquire * 846 ipsec_get_acquire(u_int32_t seq) 847 { 848 struct ipsec_acquire *ipa; 849 850 TAILQ_FOREACH (ipa, &ipsec_acquire_head, ipa_ipo_next) 851 if (ipa->ipa_seq == seq) 852 return ipa; 853 854 return NULL; 855 } 856