1 /* $OpenBSD: ip_spd.c,v 1.41 2002/01/02 20:35:40 deraadt 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 *error = 0; 372 return ipsp_spd_inp(m, af, hlen, error, direction, 373 tdbp, inp, ipo); 374 375 nomatchout: 376 /* Cached TDB was not good. */ 377 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 378 ipo_tdb_next); 379 ipo->ipo_tdb = NULL; 380 ipo->ipo_last_searched = 0; 381 } 382 383 /* 384 * If no SA has been added since the last time we did a 385 * lookup, there's no point searching for one. However, if the 386 * destination gateway is left unspecified (or is all-1's), 387 * always lookup since this is a generic-match rule 388 * (otherwise, we can have situations where SAs to some 389 * destinations exist but are not used, possibly leading to an 390 * explosion in the number of acquired SAs). 391 */ 392 if (ipo->ipo_last_searched <= ipsec_last_added) { 393 /* "Touch" the entry. */ 394 if (dignore == 0) 395 ipo->ipo_last_searched = time.tv_sec; 396 397 /* Find an appropriate SA from the existing ones. */ 398 ipo->ipo_tdb = 399 gettdbbyaddr(dignore ? &sdst : &ipo->ipo_dst, 400 ipo, m, af); 401 if (ipo->ipo_tdb) { 402 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, 403 ipo, ipo_tdb_next); 404 *error = 0; 405 return ipsp_spd_inp(m, af, hlen, error, 406 direction, tdbp, inp, ipo); 407 } 408 } 409 410 /* So, we don't have an SA -- just a policy. */ 411 switch (ipo->ipo_type) { 412 case IPSP_IPSEC_REQUIRE: 413 /* Acquire SA through key management. */ 414 if (ipsp_acquire_sa(ipo, 415 dignore ? &sdst : &ipo->ipo_dst, 416 signore ? NULL : &ipo->ipo_src, ddst, m) != 0) { 417 *error = EACCES; 418 return NULL; 419 } 420 421 /* Fall through */ 422 case IPSP_IPSEC_DONTACQ: 423 *error = -EINVAL; /* Silently drop packet. */ 424 return NULL; 425 426 case IPSP_IPSEC_ACQUIRE: 427 /* Acquire SA through key management. */ 428 ipsp_acquire_sa(ipo, dignore ? &sdst : &ipo->ipo_dst, 429 signore ? NULL : &ipo->ipo_src, ddst, NULL); 430 431 /* Fall through */ 432 case IPSP_IPSEC_USE: 433 *error = 0; 434 return ipsp_spd_inp(m, af, hlen, error, direction, 435 tdbp, inp, ipo); 436 } 437 } else { /* IPSP_DIRECTION_IN */ 438 if (tdbp != NULL) { 439 /* Direct match in the cache. */ 440 if (ipo->ipo_tdb == tdbp) { 441 *error = 0; 442 return ipsp_spd_inp(m, af, hlen, error, 443 direction, tdbp, inp, ipo); 444 } 445 446 if (bcmp(dignore ? &ssrc : &ipo->ipo_dst, 447 &tdbp->tdb_src, tdbp->tdb_src.sa.sa_len) || 448 (ipo->ipo_sproto != tdbp->tdb_sproto)) 449 goto nomatchin; 450 451 /* Match source ID. */ 452 if (ipo->ipo_srcid) { 453 if (tdbp->tdb_dstid == NULL || 454 !ipsp_ref_match(ipo->ipo_srcid, 455 tdbp->tdb_dstid)) 456 goto nomatchin; 457 } 458 459 /* Match destination ID. */ 460 if (ipo->ipo_dstid) { 461 if (tdbp->tdb_srcid == NULL || 462 !ipsp_ref_match(ipo->ipo_dstid, 463 tdbp->tdb_srcid)) 464 goto nomatchin; 465 } 466 467 /* Add it to the cache. */ 468 if (ipo->ipo_tdb) 469 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, 470 ipo, ipo_tdb_next); 471 ipo->ipo_tdb = tdbp; 472 TAILQ_INSERT_TAIL(&tdbp->tdb_policy_head, ipo, 473 ipo_tdb_next); 474 *error = 0; 475 return ipsp_spd_inp(m, af, hlen, error, direction, 476 tdbp, inp, ipo); 477 478 nomatchin: /* Nothing needed here, falling through */ 479 ; 480 } 481 482 /* Check whether cached entry applies. */ 483 if (ipo->ipo_tdb) { 484 /* 485 * We only need to check that the correct 486 * security protocol and security gateway are 487 * set; credentials/IDs will be the same, 488 * since the cached entry is linked on this 489 * policy. 490 */ 491 if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto && 492 !bcmp(&ipo->ipo_tdb->tdb_src, 493 dignore ? &ssrc : &ipo->ipo_dst, 494 ipo->ipo_tdb->tdb_src.sa.sa_len)) 495 goto skipinputsearch; 496 497 /* Not applicable, unlink. */ 498 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 499 ipo_tdb_next); 500 ipo->ipo_last_searched = 0; 501 ipo->ipo_tdb = NULL; 502 } 503 504 /* Find whether there exists an appropriate SA. */ 505 if (ipo->ipo_last_searched <= ipsec_last_added) { 506 if (dignore == 0) 507 ipo->ipo_last_searched = time.tv_sec; 508 509 ipo->ipo_tdb = 510 gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst, 511 ipo, m, af); 512 if (ipo->ipo_tdb) 513 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, 514 ipo, ipo_tdb_next); 515 } 516 skipinputsearch: 517 518 switch (ipo->ipo_type) { 519 case IPSP_IPSEC_REQUIRE: 520 /* If appropriate SA exists, don't acquire another. */ 521 if (ipo->ipo_tdb) { 522 *error = -EINVAL; 523 return NULL; 524 } 525 526 /* Acquire SA through key management. */ 527 if ((*error = ipsp_acquire_sa(ipo, 528 dignore ? &ssrc : &ipo->ipo_dst, 529 signore ? NULL : &ipo->ipo_src, ddst, m)) != 0) 530 return NULL; 531 532 /* Fall through */ 533 case IPSP_IPSEC_DONTACQ: 534 /* Drop packet. */ 535 *error = -EINVAL; 536 return NULL; 537 538 case IPSP_IPSEC_ACQUIRE: 539 /* If appropriate SA exists, don't acquire another. */ 540 if (ipo->ipo_tdb) { 541 *error = 0; 542 return ipsp_spd_inp(m, af, hlen, error, 543 direction, tdbp, inp, ipo); 544 } 545 546 /* Acquire SA through key management. */ 547 ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst, 548 signore ? NULL : &ipo->ipo_src, ddst, NULL); 549 550 /* Fall through */ 551 case IPSP_IPSEC_USE: 552 *error = 0; 553 return ipsp_spd_inp(m, af, hlen, error, direction, 554 tdbp, inp, ipo); 555 } 556 } 557 558 /* Shouldn't ever get this far. */ 559 *error = EINVAL; 560 return NULL; 561 } 562 563 /* 564 * Delete a policy from the SPD. 565 */ 566 int 567 ipsec_delete_policy(struct ipsec_policy *ipo) 568 { 569 struct ipsec_acquire *ipa; 570 int err = 0; 571 572 /* Delete from SPD. */ 573 if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET)) 574 err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr, 575 (struct sockaddr *) 0, 576 (struct sockaddr *) &ipo->ipo_mask, 577 0, (struct rtentry **) 0); 578 579 if (ipo->ipo_tdb != NULL) 580 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 581 ipo_tdb_next); 582 583 while ((ipa = TAILQ_FIRST(&ipo->ipo_acquires)) != NULL) 584 ipsp_delete_acquire(ipa); 585 586 TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list); 587 588 if (ipo->ipo_srcid) 589 ipsp_reffree(ipo->ipo_srcid); 590 if (ipo->ipo_dstid) 591 ipsp_reffree(ipo->ipo_dstid); 592 if (ipo->ipo_local_cred) 593 ipsp_reffree(ipo->ipo_local_cred); 594 if (ipo->ipo_local_auth) 595 ipsp_reffree(ipo->ipo_local_cred); 596 597 pool_put(&ipsec_policy_pool, ipo); 598 599 ipsec_in_use--; 600 601 return err; 602 } 603 604 #ifdef notyet 605 /* 606 * Add a policy to the SPD. 607 */ 608 struct ipsec_policy * 609 ipsec_add_policy(struct sockaddr_encap *dst, struct sockaddr_encap *mask, 610 union sockaddr_union *sdst, int type, int sproto) 611 { 612 struct sockaddr_encap encapgw; 613 struct ipsec_policy *ipon; 614 615 if (ipsec_policy_pool_initialized == 0) { 616 ipsec_policy_pool_initialized = 1; 617 pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy), 618 0, 0, PR_FREEHEADER, "ipsec policy", 0, NULL, NULL, 619 M_IPSEC_POLICY); 620 } 621 622 ipon = pool_get(&ipsec_policy_pool, 0); 623 if (ipon == NULL) 624 return NULL; 625 626 bzero(ipon, sizeof(struct ipsec_policy)); 627 bzero((caddr_t) &encapgw, sizeof(struct sockaddr_encap)); 628 629 encapgw.sen_len = SENT_LEN; 630 encapgw.sen_family = PF_KEY; 631 encapgw.sen_type = SENT_IPSP; 632 encapgw.sen_ipsp = ipon; 633 634 if (rtrequest(RTM_ADD, (struct sockaddr *) dst, 635 (struct sockaddr *) &encapgw, (struct sockaddr *) mask, 636 RTF_UP | RTF_GATEWAY | RTF_STATIC, (struct rtentry **) 0) != 0) { 637 DPRINTF(("ipsec_add_policy: failed to add policy\n")); 638 pool_put(&ipsec_policy_pool, ipon); 639 return NULL; 640 } 641 642 ipsec_in_use++; 643 644 bcopy(dst, &ipon->ipo_addr, sizeof(struct sockaddr_encap)); 645 bcopy(mask, &ipon->ipo_mask, sizeof(struct sockaddr_encap)); 646 bcopy(sdst, &ipon->ipo_dst, sizeof(union sockaddr_union)); 647 ipon->ipo_sproto = sproto; 648 ipon->ipo_type = type; 649 650 TAILQ_INIT(&ipon->ipo_acquires); 651 TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list); 652 653 return ipon; 654 } 655 #endif 656 657 /* 658 * Delete a pending IPsec acquire record. 659 */ 660 void 661 ipsp_delete_acquire(void *v) 662 { 663 struct ipsec_acquire *ipa = v; 664 665 timeout_del(&ipa->ipa_timeout); 666 TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next); 667 if (ipa->ipa_policy != NULL) 668 TAILQ_REMOVE(&ipa->ipa_policy->ipo_acquires, ipa, 669 ipa_ipo_next); 670 pool_put(&ipsec_acquire_pool, ipa); 671 } 672 673 /* 674 * Find out if there's an ACQUIRE pending. 675 * XXX Need a better structure. 676 */ 677 struct ipsec_acquire * 678 ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw) 679 { 680 struct ipsec_acquire *ipa; 681 682 TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) { 683 if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len)) 684 return ipa; 685 } 686 687 return NULL; 688 } 689 690 /* 691 * Signal key management that we need an SA. If we're given an mbuf, store 692 * it and retransmit the packet if/when we have an SA in place. 693 */ 694 int 695 ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw, 696 union sockaddr_union *laddr, struct sockaddr_encap *ddst, struct mbuf *m) 697 { 698 struct ipsec_acquire *ipa; 699 #ifdef INET6 700 int i; 701 #endif 702 703 /* Check whether request has been made already. */ 704 if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL) 705 return 0; 706 707 /* Add request in cache and proceed. */ 708 if (ipsec_acquire_pool_initialized == 0) { 709 ipsec_acquire_pool_initialized = 1; 710 pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire), 711 0, 0, PR_FREEHEADER, "ipsec acquire", 0, NULL, 712 NULL, M_IPSEC_POLICY); 713 } 714 715 ipa = pool_get(&ipsec_acquire_pool, 0); 716 if (ipa == NULL) 717 return ENOMEM; 718 719 bzero(ipa, sizeof(struct ipsec_acquire)); 720 bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union)); 721 722 timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa); 723 724 ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN; 725 ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY; 726 727 /* Just copy the right information. */ 728 switch (ipo->ipo_addr.sen_type) { 729 #ifdef INET 730 case SENT_IP4: 731 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4; 732 ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction; 733 ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction; 734 735 if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY || 736 ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY || 737 ipsp_is_unspecified(ipo->ipo_dst)) { 738 ipa->ipa_info.sen_ip_src = ddst->sen_ip_src; 739 ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST; 740 } else { 741 ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src; 742 ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src; 743 } 744 745 if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY || 746 ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY || 747 ipsp_is_unspecified(ipo->ipo_dst)) { 748 ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst; 749 ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST; 750 } else { 751 ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst; 752 ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst; 753 } 754 755 ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto; 756 ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto; 757 758 if (ipo->ipo_addr.sen_proto) { 759 ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport; 760 ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport; 761 762 ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport; 763 ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport; 764 } 765 break; 766 #endif /* INET */ 767 768 #ifdef INET6 769 case SENT_IP6: 770 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6; 771 ipa->ipa_info.sen_ip6_direction = 772 ipo->ipo_addr.sen_ip6_direction; 773 ipa->ipa_mask.sen_ip6_direction = 774 ipo->ipo_mask.sen_ip6_direction; 775 776 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) || 777 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) || 778 ipsp_is_unspecified(ipo->ipo_dst)) { 779 ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src; 780 for (i = 0; i < 16; i++) 781 ipa->ipa_mask.sen_ip6_src.s6_addr8[i] = 0xff; 782 } else { 783 ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src; 784 ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src; 785 } 786 787 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) || 788 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) || 789 ipsp_is_unspecified(ipo->ipo_dst)) { 790 ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst; 791 for (i = 0; i < 16; i++) 792 ipa->ipa_mask.sen_ip6_dst.s6_addr8[i] = 0xff; 793 } else { 794 ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst; 795 ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst; 796 } 797 798 ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto; 799 ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto; 800 801 if (ipo->ipo_mask.sen_ip6_proto) { 802 ipa->ipa_info.sen_ip6_sport = 803 ipo->ipo_addr.sen_ip6_sport; 804 ipa->ipa_mask.sen_ip6_sport = 805 ipo->ipo_mask.sen_ip6_sport; 806 ipa->ipa_info.sen_ip6_dport = 807 ipo->ipo_addr.sen_ip6_dport; 808 ipa->ipa_mask.sen_ip6_dport = 809 ipo->ipo_mask.sen_ip6_dport; 810 } 811 break; 812 #endif /* INET6 */ 813 814 default: 815 pool_put(&ipsec_acquire_pool, ipa); 816 return 0; 817 } 818 819 timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz); 820 821 TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next); 822 TAILQ_INSERT_TAIL(&ipo->ipo_acquires, ipa, ipa_ipo_next); 823 ipa->ipa_policy = ipo; 824 825 /* PF_KEYv2 notification message. */ 826 return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst); 827 } 828 829 /* 830 * Deal with PCB security requirements. 831 */ 832 struct tdb * 833 ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction, 834 struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo) 835 { 836 /* XXX */ 837 if (ipo != NULL) 838 return ipo->ipo_tdb; 839 else 840 return NULL; 841 } 842 843 /* 844 * Find a pending ACQUIRE record based on its sequence number. 845 * XXX Need to use a better data structure. 846 */ 847 struct ipsec_acquire * 848 ipsec_get_acquire(u_int32_t seq) 849 { 850 struct ipsec_acquire *ipa; 851 852 TAILQ_FOREACH (ipa, &ipsec_acquire_head, ipa_ipo_next) 853 if (ipa->ipa_seq == seq) 854 return ipa; 855 856 return NULL; 857 } 858