1 /* $OpenBSD: ip_spd.c,v 1.38 2001/08/15 09:50:12 niklas 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 (!bcmp(&sdst, &ipo->ipo_dst, sdst.sa.sa_len) || 331 dignore) { 332 *error = 0; 333 return ipsp_spd_inp(m, af, hlen, error, 334 direction, tdbp, inp, ipo); 335 } 336 } 337 338 /* Check that the cached TDB (if present), is appropriate. */ 339 if (ipo->ipo_tdb) { 340 if ((ipo->ipo_last_searched <= ipsec_last_added) || 341 (ipo->ipo_sproto != ipo->ipo_tdb->tdb_sproto) || 342 bcmp(dignore ? &sdst : &ipo->ipo_dst, 343 &ipo->ipo_tdb->tdb_dst, 344 ipo->ipo_tdb->tdb_dst.sa.sa_len)) 345 goto nomatchout; 346 347 /* Match source ID. */ 348 if (ipo->ipo_srcid) { 349 if (ipo->ipo_tdb->tdb_srcid == NULL || 350 !ipsp_ref_match(ipo->ipo_srcid, 351 ipo->ipo_tdb->tdb_srcid)) 352 goto nomatchout; 353 } 354 355 /* Match destination ID. */ 356 if (ipo->ipo_dstid) { 357 if (ipo->ipo_tdb->tdb_dstid == NULL || 358 !ipsp_ref_match(ipo->ipo_dstid, 359 ipo->ipo_tdb->tdb_dstid)) 360 goto nomatchout; 361 } 362 363 /* Match local credentials used. */ 364 if (ipo->ipo_local_cred) { 365 if (ipo->ipo_tdb->tdb_local_cred == NULL || 366 !ipsp_ref_match(ipo->ipo_local_cred, 367 ipo->ipo_tdb->tdb_local_cred)) 368 goto nomatchout; 369 } 370 371 /* Cached entry is good. */ 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 /* Check whether cached entry applies. */ 482 if (ipo->ipo_tdb) { 483 /* 484 * We only need to check that the correct 485 * security protocol and security gateway are 486 * set; credentials/IDs will be the same, 487 * since the cached entry is linked on this 488 * policy. 489 */ 490 if (ipo->ipo_sproto == ipo->ipo_tdb->tdb_sproto && 491 !bcmp(&ipo->ipo_tdb->tdb_src, 492 dignore ? &ssrc : &ipo->ipo_dst, 493 ipo->ipo_tdb->tdb_src.sa.sa_len)) 494 goto skipinputsearch; 495 496 /* Not applicable, unlink. */ 497 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 498 ipo_tdb_next); 499 ipo->ipo_last_searched = 0; 500 ipo->ipo_tdb = NULL; 501 } 502 503 /* Find whether there exists an appropriate SA. */ 504 if (ipo->ipo_last_searched <= ipsec_last_added) { 505 if (dignore == 0) 506 ipo->ipo_last_searched = time.tv_sec; 507 508 ipo->ipo_tdb = 509 gettdbbysrc(dignore ? &ssrc : &ipo->ipo_dst, 510 ipo, m, af); 511 if (ipo->ipo_tdb) 512 TAILQ_INSERT_TAIL(&ipo->ipo_tdb->tdb_policy_head, 513 ipo, ipo_tdb_next); 514 } 515 skipinputsearch: 516 517 switch (ipo->ipo_type) { 518 case IPSP_IPSEC_REQUIRE: 519 /* If appropriate SA exists, don't acquire another. */ 520 if (ipo->ipo_tdb) { 521 *error = -EINVAL; 522 return NULL; 523 } 524 525 /* Acquire SA through key management. */ 526 if ((*error = ipsp_acquire_sa(ipo, 527 dignore ? &ssrc : &ipo->ipo_dst, 528 signore ? NULL : &ipo->ipo_src, ddst, m)) != 0) 529 return NULL; 530 531 /* Fall through */ 532 case IPSP_IPSEC_DONTACQ: 533 /* Drop packet. */ 534 *error = -EINVAL; 535 return NULL; 536 537 case IPSP_IPSEC_ACQUIRE: 538 /* If appropriate SA exists, don't acquire another. */ 539 if (ipo->ipo_tdb) { 540 *error = 0; 541 return ipsp_spd_inp(m, af, hlen, error, 542 direction, tdbp, inp, ipo); 543 } 544 545 /* Acquire SA through key management. */ 546 ipsp_acquire_sa(ipo, dignore ? &ssrc : &ipo->ipo_dst, 547 signore ? NULL : &ipo->ipo_src, ddst, NULL); 548 549 /* Fall through */ 550 case IPSP_IPSEC_USE: 551 *error = 0; 552 return ipsp_spd_inp(m, af, hlen, error, direction, 553 tdbp, inp, ipo); 554 } 555 } 556 557 /* Shouldn't ever get this far. */ 558 *error = EINVAL; 559 return NULL; 560 } 561 562 /* 563 * Delete a policy from the SPD. 564 */ 565 int 566 ipsec_delete_policy(struct ipsec_policy *ipo) 567 { 568 struct ipsec_acquire *ipa; 569 int err = 0; 570 571 /* Delete from SPD. */ 572 if (!(ipo->ipo_flags & IPSP_POLICY_SOCKET)) 573 err = rtrequest(RTM_DELETE, (struct sockaddr *) &ipo->ipo_addr, 574 (struct sockaddr *) 0, 575 (struct sockaddr *) &ipo->ipo_mask, 576 0, (struct rtentry **) 0); 577 578 if (ipo->ipo_tdb != NULL) 579 TAILQ_REMOVE(&ipo->ipo_tdb->tdb_policy_head, ipo, 580 ipo_tdb_next); 581 582 while ((ipa = TAILQ_FIRST(&ipo->ipo_acquires)) != NULL) 583 ipsp_delete_acquire(ipa); 584 585 TAILQ_REMOVE(&ipsec_policy_head, ipo, ipo_list); 586 587 if (ipo->ipo_srcid) 588 ipsp_reffree(ipo->ipo_srcid); 589 if (ipo->ipo_dstid) 590 ipsp_reffree(ipo->ipo_dstid); 591 if (ipo->ipo_local_cred) 592 ipsp_reffree(ipo->ipo_local_cred); 593 if (ipo->ipo_local_auth) 594 ipsp_reffree(ipo->ipo_local_cred); 595 596 pool_put(&ipsec_policy_pool, ipo); 597 598 ipsec_in_use--; 599 600 return err; 601 } 602 603 #ifdef notyet 604 /* 605 * Add a policy to the SPD. 606 */ 607 struct ipsec_policy * 608 ipsec_add_policy(struct sockaddr_encap *dst, struct sockaddr_encap *mask, 609 union sockaddr_union *sdst, int type, int sproto) 610 { 611 struct sockaddr_encap encapgw; 612 struct ipsec_policy *ipon; 613 614 if (ipsec_policy_pool_initialized == 0) { 615 ipsec_policy_pool_initialized = 1; 616 pool_init(&ipsec_policy_pool, sizeof(struct ipsec_policy), 617 0, 0, PR_FREEHEADER, "ipsec policy", 0, NULL, NULL, 618 M_IPSEC_POLICY); 619 } 620 621 ipon = pool_get(&ipsec_policy_pool, 0); 622 if (ipon == NULL) 623 return NULL; 624 625 bzero(ipon, sizeof(struct ipsec_policy)); 626 bzero((caddr_t) &encapgw, sizeof(struct sockaddr_encap)); 627 628 encapgw.sen_len = SENT_LEN; 629 encapgw.sen_family = PF_KEY; 630 encapgw.sen_type = SENT_IPSP; 631 encapgw.sen_ipsp = ipon; 632 633 if (rtrequest(RTM_ADD, (struct sockaddr *) dst, 634 (struct sockaddr *) &encapgw, (struct sockaddr *) mask, 635 RTF_UP | RTF_GATEWAY | RTF_STATIC, (struct rtentry **) 0) != 0) { 636 DPRINTF(("ipsec_add_policy: failed to add policy\n")); 637 pool_put(&ipsec_policy_pool, ipon); 638 return NULL; 639 } 640 641 ipsec_in_use++; 642 643 bcopy(dst, &ipon->ipo_addr, sizeof(struct sockaddr_encap)); 644 bcopy(mask, &ipon->ipo_mask, sizeof(struct sockaddr_encap)); 645 bcopy(sdst, &ipon->ipo_dst, sizeof(union sockaddr_union)); 646 ipon->ipo_sproto = sproto; 647 ipon->ipo_type = type; 648 649 TAILQ_INIT(&ipon->ipo_acquires); 650 TAILQ_INSERT_HEAD(&ipsec_policy_head, ipon, ipo_list); 651 652 return ipon; 653 } 654 #endif 655 656 /* 657 * Delete a pending IPsec acquire record. 658 */ 659 void 660 ipsp_delete_acquire(void *v) 661 { 662 struct ipsec_acquire *ipa = v; 663 664 timeout_del(&ipa->ipa_timeout); 665 TAILQ_REMOVE(&ipsec_acquire_head, ipa, ipa_next); 666 if (ipa->ipa_policy != NULL) 667 TAILQ_REMOVE(&ipa->ipa_policy->ipo_acquires, ipa, 668 ipa_ipo_next); 669 pool_put(&ipsec_acquire_pool, ipa); 670 } 671 672 /* 673 * Find out if there's an ACQUIRE pending. 674 * XXX Need a better structure. 675 */ 676 struct ipsec_acquire * 677 ipsp_pending_acquire(struct ipsec_policy *ipo, union sockaddr_union *gw) 678 { 679 struct ipsec_acquire *ipa; 680 681 TAILQ_FOREACH (ipa, &ipo->ipo_acquires, ipa_ipo_next) { 682 if (!bcmp(gw, &ipa->ipa_addr, gw->sa.sa_len)) 683 return ipa; 684 } 685 686 return NULL; 687 } 688 689 /* 690 * Signal key management that we need an SA. If we're given an mbuf, store 691 * it and retransmit the packet if/when we have an SA in place. 692 */ 693 int 694 ipsp_acquire_sa(struct ipsec_policy *ipo, union sockaddr_union *gw, 695 union sockaddr_union *laddr, struct sockaddr_encap *ddst, struct mbuf *m) 696 { 697 struct ipsec_acquire *ipa; 698 #ifdef INET6 699 int i; 700 #endif 701 702 /* Check whether request has been made already. */ 703 if ((ipa = ipsp_pending_acquire(ipo, gw)) != NULL) 704 return 0; 705 706 /* Add request in cache and proceed. */ 707 if (ipsec_acquire_pool_initialized == 0) { 708 ipsec_acquire_pool_initialized = 1; 709 pool_init(&ipsec_acquire_pool, sizeof(struct ipsec_acquire), 710 0, 0, PR_FREEHEADER, "ipsec acquire", 0, NULL, 711 NULL, M_IPSEC_POLICY); 712 } 713 714 ipa = pool_get(&ipsec_acquire_pool, 0); 715 if (ipa == NULL) 716 return ENOMEM; 717 718 bzero(ipa, sizeof(struct ipsec_acquire)); 719 bcopy(gw, &ipa->ipa_addr, sizeof(union sockaddr_union)); 720 721 timeout_set(&ipa->ipa_timeout, ipsp_delete_acquire, ipa); 722 723 ipa->ipa_info.sen_len = ipa->ipa_mask.sen_len = SENT_LEN; 724 ipa->ipa_info.sen_family = ipa->ipa_mask.sen_family = PF_KEY; 725 726 /* Just copy the right information. */ 727 switch (ipo->ipo_addr.sen_type) { 728 #ifdef INET 729 case SENT_IP4: 730 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP4; 731 ipa->ipa_info.sen_direction = ipo->ipo_addr.sen_direction; 732 ipa->ipa_mask.sen_direction = ipo->ipo_mask.sen_direction; 733 734 if (ipo->ipo_mask.sen_ip_src.s_addr == INADDR_ANY || 735 ipo->ipo_addr.sen_ip_src.s_addr == INADDR_ANY || 736 ipsp_is_unspecified(ipo->ipo_dst)) { 737 ipa->ipa_info.sen_ip_src = ddst->sen_ip_src; 738 ipa->ipa_mask.sen_ip_src.s_addr = INADDR_BROADCAST; 739 } else { 740 ipa->ipa_info.sen_ip_src = ipo->ipo_addr.sen_ip_src; 741 ipa->ipa_mask.sen_ip_src = ipo->ipo_mask.sen_ip_src; 742 } 743 744 if (ipo->ipo_mask.sen_ip_dst.s_addr == INADDR_ANY || 745 ipo->ipo_addr.sen_ip_dst.s_addr == INADDR_ANY || 746 ipsp_is_unspecified(ipo->ipo_dst)) { 747 ipa->ipa_info.sen_ip_dst = ddst->sen_ip_dst; 748 ipa->ipa_mask.sen_ip_dst.s_addr = INADDR_BROADCAST; 749 } else { 750 ipa->ipa_info.sen_ip_dst = ipo->ipo_addr.sen_ip_dst; 751 ipa->ipa_mask.sen_ip_dst = ipo->ipo_mask.sen_ip_dst; 752 } 753 754 ipa->ipa_info.sen_proto = ipo->ipo_addr.sen_proto; 755 ipa->ipa_mask.sen_proto = ipo->ipo_mask.sen_proto; 756 757 if (ipo->ipo_addr.sen_proto) { 758 ipa->ipa_info.sen_sport = ipo->ipo_addr.sen_sport; 759 ipa->ipa_mask.sen_sport = ipo->ipo_mask.sen_sport; 760 761 ipa->ipa_info.sen_dport = ipo->ipo_addr.sen_dport; 762 ipa->ipa_mask.sen_dport = ipo->ipo_mask.sen_dport; 763 } 764 break; 765 #endif /* INET */ 766 767 #ifdef INET6 768 case SENT_IP6: 769 ipa->ipa_info.sen_type = ipa->ipa_mask.sen_type = SENT_IP6; 770 ipa->ipa_info.sen_ip6_direction = 771 ipo->ipo_addr.sen_ip6_direction; 772 ipa->ipa_mask.sen_ip6_direction = 773 ipo->ipo_mask.sen_ip6_direction; 774 775 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_src) || 776 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_src) || 777 ipsp_is_unspecified(ipo->ipo_dst)) { 778 ipa->ipa_info.sen_ip6_src = ddst->sen_ip6_src; 779 for (i = 0; i < 16; i++) 780 ipa->ipa_mask.sen_ip6_src.s6_addr8[i] = 0xff; 781 } else { 782 ipa->ipa_info.sen_ip6_src = ipo->ipo_addr.sen_ip6_src; 783 ipa->ipa_mask.sen_ip6_src = ipo->ipo_mask.sen_ip6_src; 784 } 785 786 if (IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_mask.sen_ip6_dst) || 787 IN6_IS_ADDR_UNSPECIFIED(&ipo->ipo_addr.sen_ip6_dst) || 788 ipsp_is_unspecified(ipo->ipo_dst)) { 789 ipa->ipa_info.sen_ip6_dst = ddst->sen_ip6_dst; 790 for (i = 0; i < 16; i++) 791 ipa->ipa_mask.sen_ip6_dst.s6_addr8[i] = 0xff; 792 } else { 793 ipa->ipa_info.sen_ip6_dst = ipo->ipo_addr.sen_ip6_dst; 794 ipa->ipa_mask.sen_ip6_dst = ipo->ipo_mask.sen_ip6_dst; 795 } 796 797 ipa->ipa_info.sen_ip6_proto = ipo->ipo_addr.sen_ip6_proto; 798 ipa->ipa_mask.sen_ip6_proto = ipo->ipo_mask.sen_ip6_proto; 799 800 if (ipo->ipo_mask.sen_ip6_proto) { 801 ipa->ipa_info.sen_ip6_sport = 802 ipo->ipo_addr.sen_ip6_sport; 803 ipa->ipa_mask.sen_ip6_sport = 804 ipo->ipo_mask.sen_ip6_sport; 805 ipa->ipa_info.sen_ip6_dport = 806 ipo->ipo_addr.sen_ip6_dport; 807 ipa->ipa_mask.sen_ip6_dport = 808 ipo->ipo_mask.sen_ip6_dport; 809 } 810 break; 811 #endif /* INET6 */ 812 813 default: 814 pool_put(&ipsec_acquire_pool, ipa); 815 return 0; 816 } 817 818 timeout_add(&ipa->ipa_timeout, ipsec_expire_acquire * hz); 819 820 TAILQ_INSERT_TAIL(&ipsec_acquire_head, ipa, ipa_next); 821 TAILQ_INSERT_TAIL(&ipo->ipo_acquires, ipa, ipa_ipo_next); 822 ipa->ipa_policy = ipo; 823 824 /* PF_KEYv2 notification message. */ 825 return pfkeyv2_acquire(ipo, gw, laddr, &ipa->ipa_seq, ddst); 826 } 827 828 /* 829 * Deal with PCB security requirements. 830 */ 831 struct tdb * 832 ipsp_spd_inp(struct mbuf *m, int af, int hlen, int *error, int direction, 833 struct tdb *tdbp, struct inpcb *inp, struct ipsec_policy *ipo) 834 { 835 /* XXX */ 836 if (ipo != NULL) 837 return ipo->ipo_tdb; 838 else 839 return NULL; 840 } 841 842 /* 843 * Find a pending ACQUIRE record based on its sequence number. 844 * XXX Need to use a better data structure. 845 */ 846 struct ipsec_acquire * 847 ipsec_get_acquire(u_int32_t seq) 848 { 849 struct ipsec_acquire *ipa; 850 851 TAILQ_FOREACH (ipa, &ipsec_acquire_head, ipa_ipo_next) 852 if (ipa->ipa_seq == seq) 853 return ipa; 854 855 return NULL; 856 } 857