1 /* $OpenBSD: policy.c,v 1.81 2021/04/09 09:15:04 tobhe Exp $ */ 2 3 /* 4 * Copyright (c) 2020-2021 Tobias Heider <tobhe@openbsd.org> 5 * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> 6 * Copyright (c) 2001 Daniel Hartmeier 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose with or without fee is hereby granted, provided that the above 10 * copyright notice and this permission notice appear in all copies. 11 * 12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 19 */ 20 21 #include <sys/queue.h> 22 #include <sys/socket.h> 23 #include <sys/uio.h> 24 #include <sys/tree.h> 25 26 #include <netinet/in.h> 27 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <unistd.h> 31 #include <string.h> 32 #include <errno.h> 33 #include <fcntl.h> 34 #include <event.h> 35 36 #include "iked.h" 37 #include "ikev2.h" 38 39 static __inline int 40 sa_cmp(struct iked_sa *, struct iked_sa *); 41 static __inline int 42 sa_dstid_cmp(struct iked_sa *, struct iked_sa *); 43 static __inline int 44 user_cmp(struct iked_user *, struct iked_user *); 45 static __inline int 46 childsa_cmp(struct iked_childsa *, struct iked_childsa *); 47 static __inline int 48 flow_cmp(struct iked_flow *, struct iked_flow *); 49 static __inline int 50 addr_cmp(struct iked_addr *, struct iked_addr *, int); 51 static __inline int 52 ts_insert_unique(struct iked_addr *, struct iked_tss *, int); 53 54 static int policy_test_flows(struct iked_policy *, struct iked_policy *); 55 static int proposals_match(struct iked_proposal *, struct iked_proposal *, 56 struct iked_transform **, int); 57 58 void 59 policy_init(struct iked *env) 60 { 61 TAILQ_INIT(&env->sc_policies); 62 TAILQ_INIT(&env->sc_ocsp); 63 RB_INIT(&env->sc_users); 64 RB_INIT(&env->sc_sas); 65 RB_INIT(&env->sc_dstid_sas); 66 RB_INIT(&env->sc_activesas); 67 RB_INIT(&env->sc_activeflows); 68 } 69 70 /* 71 * Lookup an iked policy matching the IKE_AUTH message msg 72 * and store a pointer to the found policy in msg. If no policy 73 * matches a pointer to the default policy is stored in msg. 74 * If 'proposals' is not NULL policy_lookup only returns policies 75 * compatible with 'proposals'. 76 * 77 * Returns 0 on success and -1 if no matching policy was 78 * found and no default exists. 79 */ 80 int 81 policy_lookup(struct iked *env, struct iked_message *msg, 82 struct iked_proposals *proposals, struct iked_flows *flows, 83 int nflows) 84 { 85 struct iked_policy pol; 86 char *s, idstr[IKED_ID_SIZE]; 87 88 89 if (msg->msg_sa != NULL && msg->msg_sa->sa_policy != NULL) { 90 /* Existing SA with policy */ 91 msg->msg_policy = msg->msg_sa->sa_policy; 92 return (0); 93 } 94 95 bzero(&pol, sizeof(pol)); 96 if (proposals != NULL) 97 pol.pol_proposals = *proposals; 98 pol.pol_af = msg->msg_peer.ss_family; 99 if (flows) 100 pol.pol_flows = *flows; 101 pol.pol_nflows = nflows; 102 if (msg->msg_flags & IKED_MSG_FLAGS_USE_TRANSPORT) 103 pol.pol_flags |= IKED_POLICY_TRANSPORT; 104 memcpy(&pol.pol_peer.addr, &msg->msg_peer, sizeof(msg->msg_peer)); 105 memcpy(&pol.pol_local.addr, &msg->msg_local, sizeof(msg->msg_local)); 106 if (msg->msg_id.id_type && 107 ikev2_print_id(&msg->msg_id, idstr, IKED_ID_SIZE) == 0 && 108 (s = strchr(idstr, '/')) != NULL) { 109 pol.pol_peerid.id_type = msg->msg_id.id_type; 110 pol.pol_peerid.id_length = strlen(s+1); 111 strlcpy(pol.pol_peerid.id_data, s+1, 112 sizeof(pol.pol_peerid.id_data)); 113 log_debug("%s: peerid '%s'", __func__, s+1); 114 } 115 116 /* Try to find a matching policy for this message */ 117 if ((msg->msg_policy = policy_test(env, &pol)) != NULL) { 118 log_debug("%s: setting policy '%s'", __func__, 119 msg->msg_policy->pol_name); 120 return (0); 121 } 122 123 /* No matching policy found, try the default */ 124 if ((msg->msg_policy = env->sc_defaultcon) != NULL) 125 return (0); 126 127 /* No policy found */ 128 return (-1); 129 } 130 131 /* 132 * Lookup an iked policy matching the SA sa and store a pointer 133 * to the found policy in SA. 134 * 135 * Returns 0 on success and -1 if no matching policy was 136 * found 137 */ 138 int 139 policy_lookup_sa(struct iked *env, struct iked_sa *sa) 140 { 141 struct iked_policy pol, *pol_found; 142 struct iked_id *lid, *pid; 143 char *s, idstr[IKED_ID_SIZE]; 144 145 /* 146 * The SA should never be without policy. In the case of 147 * 'ikectl reload' the policy is no longer in sc_policies 148 * but is kept alive by the reference from the sa. 149 */ 150 if (sa->sa_policy == NULL) { 151 log_warn("%s: missing SA policy.", SPI_SA(sa, __func__)); 152 return (-1); 153 } 154 155 bzero(&pol, sizeof(pol)); 156 pol.pol_proposals = sa->sa_proposals; 157 pol.pol_af = sa->sa_peer.addr_af; 158 if (sa->sa_used_transport_mode) 159 pol.pol_flags |= IKED_POLICY_TRANSPORT; 160 memcpy(&pol.pol_peer.addr, &sa->sa_peer.addr, sizeof(sa->sa_peer.addr)); 161 memcpy(&pol.pol_local.addr, &sa->sa_local.addr, sizeof(sa->sa_local.addr)); 162 pol.pol_flows = sa->sa_policy->pol_flows; 163 pol.pol_nflows = sa->sa_policy->pol_nflows; 164 165 if (sa->sa_hdr.sh_initiator) { 166 lid = &sa->sa_iid; 167 pid = &sa->sa_rid; 168 } else { 169 lid = &sa->sa_rid; 170 pid = &sa->sa_iid; 171 } 172 173 if (pid->id_type && 174 ikev2_print_id(pid, idstr, IKED_ID_SIZE) == 0 && 175 (s = strchr(idstr, '/')) != NULL) { 176 pol.pol_peerid.id_type = pid->id_type; 177 pol.pol_peerid.id_length = strlen(s+1); 178 strlcpy(pol.pol_peerid.id_data, s+1, 179 sizeof(pol.pol_peerid.id_data)); 180 log_debug("%s: peerid '%s'", __func__, s+1); 181 } 182 183 if (lid->id_type && 184 ikev2_print_id(lid, idstr, IKED_ID_SIZE) == 0 && 185 (s = strchr(idstr, '/')) != NULL) { 186 pol.pol_localid.id_type = lid->id_type; 187 pol.pol_localid.id_length = strlen(s+1); 188 strlcpy(pol.pol_localid.id_data, s+1, 189 sizeof(pol.pol_localid.id_data)); 190 log_debug("%s: localid '%s'", __func__, s+1); 191 } 192 193 /* Try to find a matching policy for this message */ 194 if ((pol_found = policy_test(env, &pol)) != NULL) { 195 log_debug("%s: found policy '%s'", SPI_SA(sa, __func__), 196 pol_found->pol_name); 197 sa->sa_policy = pol_found; 198 return (0); 199 } 200 201 /* No policy found */ 202 return (-1); 203 } 204 205 /* 206 * Find a policy matching the query policy key in the global env. 207 * If multiple matching policies are found the policy with the highest 208 * priority is selected. 209 * 210 * Returns a pointer to a matching policy, or NULL if no policy matches. 211 */ 212 struct iked_policy * 213 policy_test(struct iked *env, struct iked_policy *key) 214 { 215 struct iked_policy *p = NULL, *pol = NULL; 216 unsigned int cnt = 0; 217 218 p = TAILQ_FIRST(&env->sc_policies); 219 while (p != NULL) { 220 cnt++; 221 if (p->pol_flags & IKED_POLICY_SKIP) 222 p = p->pol_skip[IKED_SKIP_FLAGS]; 223 else if (key->pol_af && p->pol_af && 224 key->pol_af != p->pol_af) 225 p = p->pol_skip[IKED_SKIP_AF]; 226 else if (key->pol_ipproto && p->pol_ipproto && 227 key->pol_ipproto != p->pol_ipproto) 228 p = p->pol_skip[IKED_SKIP_PROTO]; 229 else if (sockaddr_cmp((struct sockaddr *)&key->pol_peer.addr, 230 (struct sockaddr *)&p->pol_peer.addr, 231 p->pol_peer.addr_mask) != 0) 232 p = p->pol_skip[IKED_SKIP_DST_ADDR]; 233 else if (sockaddr_cmp((struct sockaddr *)&key->pol_local.addr, 234 (struct sockaddr *)&p->pol_local.addr, 235 p->pol_local.addr_mask) != 0) 236 p = p->pol_skip[IKED_SKIP_SRC_ADDR]; 237 else { 238 /* 239 * Check if flows are requested and if they 240 * are compatible. 241 */ 242 if (key->pol_nflows && policy_test_flows(key, p)) { 243 p = TAILQ_NEXT(p, pol_entry); 244 continue; 245 } 246 /* make sure the peer ID matches */ 247 if (key->pol_peerid.id_type && 248 p->pol_peerid.id_type && 249 (key->pol_peerid.id_type != p->pol_peerid.id_type || 250 memcmp(key->pol_peerid.id_data, 251 p->pol_peerid.id_data, 252 sizeof(key->pol_peerid.id_data)) != 0)) { 253 p = TAILQ_NEXT(p, pol_entry); 254 continue; 255 } 256 257 /* make sure the local ID matches */ 258 if (key->pol_localid.id_type && 259 p->pol_localid.id_type && 260 (key->pol_localid.id_type != p->pol_localid.id_type || 261 memcmp(key->pol_localid.id_data, 262 p->pol_localid.id_data, 263 sizeof(key->pol_localid.id_data)) != 0)) { 264 log_info("%s: localid mismatch", __func__); 265 p = TAILQ_NEXT(p, pol_entry); 266 continue; 267 } 268 269 /* check transport mode */ 270 if ((key->pol_flags & IKED_POLICY_TRANSPORT) && 271 !(p->pol_flags & IKED_POLICY_TRANSPORT)) { 272 p = TAILQ_NEXT(p, pol_entry); 273 continue; 274 } 275 276 /* Make sure the proposals are compatible */ 277 if (TAILQ_FIRST(&key->pol_proposals) && 278 proposals_negotiate(NULL, &p->pol_proposals, 279 &key->pol_proposals, 0) == -1) { 280 p = TAILQ_NEXT(p, pol_entry); 281 continue; 282 } 283 284 /* Policy matched */ 285 pol = p; 286 287 if (pol->pol_flags & IKED_POLICY_QUICK) 288 break; 289 290 /* Continue to find last matching policy */ 291 p = TAILQ_NEXT(p, pol_entry); 292 } 293 } 294 295 return (pol); 296 } 297 298 static int 299 policy_test_flows(struct iked_policy *key, struct iked_policy *p) 300 { 301 struct iked_flow *f; 302 303 for (f = RB_MIN(iked_flows, &key->pol_flows); f != NULL; 304 f = RB_NEXT(iked_flows, &key->pol_flows, f)) 305 if (RB_FIND(iked_flows, &p->pol_flows, f) == NULL) 306 return (-1); 307 308 return (0); 309 } 310 311 #define IKED_SET_SKIP_STEPS(i) \ 312 do { \ 313 while (head[i] != cur) { \ 314 head[i]->pol_skip[i] = cur; \ 315 head[i] = TAILQ_NEXT(head[i], pol_entry); \ 316 } \ 317 } while (0) 318 319 /* This code is derived from pf_calc_skip_steps() from pf.c */ 320 void 321 policy_calc_skip_steps(struct iked_policies *policies) 322 { 323 struct iked_policy *head[IKED_SKIP_COUNT], *cur, *prev; 324 int i; 325 326 cur = TAILQ_FIRST(policies); 327 prev = cur; 328 for (i = 0; i < IKED_SKIP_COUNT; ++i) 329 head[i] = cur; 330 while (cur != NULL) { 331 if (cur->pol_flags & IKED_POLICY_SKIP) 332 IKED_SET_SKIP_STEPS(IKED_SKIP_FLAGS); 333 if (cur->pol_af != AF_UNSPEC && 334 prev->pol_af != AF_UNSPEC && 335 cur->pol_af != prev->pol_af) 336 IKED_SET_SKIP_STEPS(IKED_SKIP_AF); 337 if (cur->pol_ipproto && prev->pol_ipproto && 338 cur->pol_ipproto != prev->pol_ipproto) 339 IKED_SET_SKIP_STEPS(IKED_SKIP_PROTO); 340 if (IKED_ADDR_NEQ(&cur->pol_peer, &prev->pol_peer)) 341 IKED_SET_SKIP_STEPS(IKED_SKIP_DST_ADDR); 342 if (IKED_ADDR_NEQ(&cur->pol_local, &prev->pol_local)) 343 IKED_SET_SKIP_STEPS(IKED_SKIP_SRC_ADDR); 344 345 prev = cur; 346 cur = TAILQ_NEXT(cur, pol_entry); 347 } 348 for (i = 0; i < IKED_SKIP_COUNT; ++i) 349 IKED_SET_SKIP_STEPS(i); 350 } 351 352 void 353 policy_ref(struct iked *env, struct iked_policy *pol) 354 { 355 pol->pol_refcnt++; 356 pol->pol_flags |= IKED_POLICY_REFCNT; 357 } 358 359 void 360 policy_unref(struct iked *env, struct iked_policy *pol) 361 { 362 if (pol == NULL || (pol->pol_flags & IKED_POLICY_REFCNT) == 0) 363 return; 364 if (--(pol->pol_refcnt) <= 0) 365 config_free_policy(env, pol); 366 else { 367 struct iked_sa *tmp; 368 int count = 0; 369 370 TAILQ_FOREACH(tmp, &pol->pol_sapeers, sa_peer_entry) 371 count++; 372 if (count != pol->pol_refcnt) 373 log_warnx("%s: ERROR pol %p pol_refcnt %d != count %d", 374 __func__, pol, pol->pol_refcnt, count); 375 } 376 } 377 378 void 379 sa_state(struct iked *env, struct iked_sa *sa, int state) 380 { 381 const char *a; 382 const char *b; 383 int ostate = sa->sa_state; 384 385 a = print_map(ostate, ikev2_state_map); 386 b = print_map(state, ikev2_state_map); 387 388 sa->sa_state = state; 389 if (ostate != IKEV2_STATE_INIT && 390 !sa_stateok(sa, state)) { 391 log_debug("%s: cannot switch: %s -> %s", 392 SPI_SA(sa, __func__), a, b); 393 sa->sa_state = ostate; 394 } else if (ostate != sa->sa_state) { 395 switch (state) { 396 case IKEV2_STATE_ESTABLISHED: 397 case IKEV2_STATE_CLOSED: 398 log_debug("%s: %s -> %s from %s to %s policy '%s'", 399 SPI_SA(sa, __func__), a, b, 400 print_host((struct sockaddr *)&sa->sa_peer.addr, 401 NULL, 0), 402 print_host((struct sockaddr *)&sa->sa_local.addr, 403 NULL, 0), 404 sa->sa_policy ? sa->sa_policy->pol_name : 405 "<unknown>"); 406 break; 407 default: 408 log_debug("%s: %s -> %s", 409 SPI_SA(sa, __func__), a, b); 410 break; 411 } 412 } 413 414 } 415 416 void 417 sa_stateflags(struct iked_sa *sa, unsigned int flags) 418 { 419 unsigned int require; 420 421 if (sa->sa_state > IKEV2_STATE_SA_INIT) 422 require = sa->sa_statevalid; 423 else 424 require = sa->sa_stateinit; 425 426 log_debug("%s: 0x%04x -> 0x%04x %s (required 0x%04x %s)", __func__, 427 sa->sa_stateflags, sa->sa_stateflags | flags, 428 print_bits(sa->sa_stateflags | flags, IKED_REQ_BITS), require, 429 print_bits(require, IKED_REQ_BITS)); 430 431 sa->sa_stateflags |= flags; 432 } 433 434 int 435 sa_stateok(const struct iked_sa *sa, int state) 436 { 437 unsigned int require; 438 439 if (sa->sa_state < state) 440 return (0); 441 442 if (state == IKEV2_STATE_SA_INIT) 443 require = sa->sa_stateinit; 444 else 445 require = sa->sa_statevalid; 446 447 if (state == IKEV2_STATE_SA_INIT || 448 state == IKEV2_STATE_VALID || 449 state == IKEV2_STATE_EAP_VALID) { 450 log_debug("%s: %s flags 0x%04x, require 0x%04x %s", __func__, 451 print_map(state, ikev2_state_map), 452 (sa->sa_stateflags & require), require, 453 print_bits(require, IKED_REQ_BITS)); 454 455 if ((sa->sa_stateflags & require) != require) 456 return (0); /* not ready, ignore */ 457 } 458 return (1); 459 } 460 461 struct iked_sa * 462 sa_new(struct iked *env, uint64_t ispi, uint64_t rspi, 463 unsigned int initiator, struct iked_policy *pol) 464 { 465 struct iked_sa *sa; 466 struct iked_sa *old; 467 struct iked_id *localid; 468 unsigned int diff; 469 470 if ((ispi == 0 && rspi == 0) || 471 (sa = sa_lookup(env, ispi, rspi, initiator)) == NULL) { 472 /* Create new SA */ 473 if (!initiator && ispi == 0) { 474 log_debug("%s: cannot create responder IKE SA w/o ispi", 475 __func__); 476 return (NULL); 477 } 478 sa = config_new_sa(env, initiator); 479 if (sa == NULL) { 480 log_debug("%s: failed to allocate IKE SA", __func__); 481 return (NULL); 482 } 483 if (!initiator) 484 sa->sa_hdr.sh_ispi = ispi; 485 old = RB_INSERT(iked_sas, &env->sc_sas, sa); 486 if (old && old != sa) { 487 log_warnx("%s: duplicate IKE SA", __func__); 488 config_free_sa(env, sa); 489 return (NULL); 490 } 491 } 492 /* Update rspi in the initator case */ 493 if (initiator && sa->sa_hdr.sh_rspi == 0 && rspi) 494 sa->sa_hdr.sh_rspi = rspi; 495 496 if (pol == NULL && sa->sa_policy == NULL) 497 fatalx("%s: sa %p no policy", __func__, sa); 498 else if (sa->sa_policy == NULL) { 499 /* Increment refcount if the policy has refcounting enabled. */ 500 if (pol->pol_flags & IKED_POLICY_REFCNT) { 501 log_info("%s: sa %p old pol %p pol_refcnt %d", 502 __func__, sa, pol, pol->pol_refcnt); 503 policy_ref(env, pol); 504 } 505 sa->sa_policy = pol; 506 TAILQ_INSERT_TAIL(&pol->pol_sapeers, sa, sa_peer_entry); 507 } else 508 pol = sa->sa_policy; 509 510 sa->sa_statevalid = IKED_REQ_AUTH|IKED_REQ_AUTHVALID|IKED_REQ_SA; 511 if (pol != NULL && pol->pol_auth.auth_eap) { 512 sa->sa_statevalid |= IKED_REQ_CERT|IKED_REQ_EAPVALID; 513 } else if (pol != NULL && pol->pol_auth.auth_method != 514 IKEV2_AUTH_SHARED_KEY_MIC) { 515 sa->sa_statevalid |= IKED_REQ_CERTVALID|IKED_REQ_CERT; 516 } 517 518 if (initiator) { 519 localid = &sa->sa_iid; 520 diff = IKED_REQ_CERTVALID|IKED_REQ_AUTHVALID|IKED_REQ_SA| 521 IKED_REQ_EAPVALID; 522 sa->sa_stateinit = sa->sa_statevalid & ~diff; 523 sa->sa_statevalid = sa->sa_statevalid & diff; 524 } else 525 localid = &sa->sa_rid; 526 527 if (pol != NULL && 528 ikev2_policy2id(&pol->pol_localid, localid, 1) != 0) { 529 log_debug("%s: failed to get local id", __func__); 530 ikev2_ike_sa_setreason(sa, "failed to get local id"); 531 sa_free(env, sa); 532 return (NULL); 533 } 534 535 return (sa); 536 } 537 538 int 539 policy_generate_ts(struct iked_policy *pol) 540 { 541 struct iked_flow *flow; 542 543 /* Generate list of traffic selectors from flows */ 544 RB_FOREACH(flow, iked_flows, &pol->pol_flows) { 545 if (ts_insert_unique(&flow->flow_src, &pol->pol_tssrc, 546 flow->flow_ipproto) == 1) 547 pol->pol_tssrc_count++; 548 if (ts_insert_unique(&flow->flow_dst, &pol->pol_tsdst, 549 flow->flow_ipproto) == 1) 550 pol->pol_tsdst_count++; 551 } 552 if (pol->pol_tssrc_count > IKEV2_MAXNUM_TSS || 553 pol->pol_tsdst_count > IKEV2_MAXNUM_TSS) 554 return (-1); 555 556 return (0); 557 } 558 559 int 560 ts_insert_unique(struct iked_addr *addr, struct iked_tss *tss, int ipproto) 561 { 562 struct iked_ts *ts; 563 564 /* Remove duplicates */ 565 TAILQ_FOREACH(ts, tss, ts_entry) { 566 if (addr_cmp(addr, &ts->ts_addr, 1) == 0) 567 return (0); 568 } 569 570 if ((ts = calloc(1, sizeof(*ts))) == NULL) 571 return (-1); 572 573 ts->ts_ipproto = ipproto; 574 ts->ts_addr = *addr; 575 576 TAILQ_INSERT_TAIL(tss, ts, ts_entry); 577 return (1); 578 } 579 580 void 581 sa_free(struct iked *env, struct iked_sa *sa) 582 { 583 struct iked_sa *osa; 584 585 if (sa->sa_reason) 586 log_info("%s: %s", SPI_SA(sa, __func__), sa->sa_reason); 587 else 588 log_debug("%s: ispi %s rspi %s", SPI_SA(sa, __func__), 589 print_spi(sa->sa_hdr.sh_ispi, 8), 590 print_spi(sa->sa_hdr.sh_rspi, 8)); 591 592 /* IKE rekeying running? (old sa freed before new sa) */ 593 if (sa->sa_nexti) { 594 RB_REMOVE(iked_sas, &env->sc_sas, sa->sa_nexti); 595 if (sa->sa_nexti->sa_dstid_entry_valid) { 596 log_info("%s: nexti established? %s", 597 SPI_SA(sa, __func__), SPI_SA(sa->sa_nexti, NULL)); 598 sa_dstid_remove(env, sa->sa_nexti); 599 } 600 config_free_sa(env, sa->sa_nexti); 601 } 602 if (sa->sa_nextr) { 603 RB_REMOVE(iked_sas, &env->sc_sas, sa->sa_nextr); 604 if (sa->sa_nextr->sa_dstid_entry_valid) { 605 log_info("%s: nextr established? %s", 606 SPI_SA(sa, __func__), SPI_SA(sa->sa_nextr, NULL)); 607 sa_dstid_remove(env, sa->sa_nextr); 608 } 609 config_free_sa(env, sa->sa_nextr); 610 } 611 /* reset matching backpointers (new sa freed before old sa) */ 612 if ((osa = sa->sa_previ) != NULL) { 613 if (osa->sa_nexti == sa) { 614 log_debug("%s: resetting: sa %p == osa->sa_nexti %p" 615 " (osa %p)", 616 SPI_SA(sa, __func__), osa, sa, osa->sa_nexti); 617 osa->sa_nexti = NULL; 618 } else { 619 log_info("%s: inconsistent: sa %p != osa->sa_nexti %p" 620 " (osa %p)", 621 SPI_SA(sa, __func__), osa, sa, osa->sa_nexti); 622 } 623 } 624 if ((osa = sa->sa_prevr) != NULL) { 625 if (osa->sa_nextr == sa) { 626 log_debug("%s: resetting: sa %p == osa->sa_nextr %p" 627 " (osa %p)", 628 SPI_SA(sa, __func__), osa, sa, osa->sa_nextr); 629 osa->sa_nextr = NULL; 630 } else { 631 log_info("%s: inconsistent: sa %p != osa->sa_nextr %p" 632 " (osa %p)", 633 SPI_SA(sa, __func__), osa, sa, osa->sa_nextr); 634 } 635 } 636 RB_REMOVE(iked_sas, &env->sc_sas, sa); 637 if (sa->sa_dstid_entry_valid) 638 sa_dstid_remove(env, sa); 639 config_free_sa(env, sa); 640 } 641 642 void 643 sa_free_flows(struct iked *env, struct iked_saflows *head) 644 { 645 struct iked_flow *flow, *flowtmp; 646 647 TAILQ_FOREACH_SAFE(flow, head, flow_entry, flowtmp) { 648 log_debug("%s: free %p", __func__, flow); 649 650 if (flow->flow_loaded) 651 RB_REMOVE(iked_flows, &env->sc_activeflows, flow); 652 TAILQ_REMOVE(head, flow, flow_entry); 653 (void)pfkey_flow_delete(env->sc_pfkey, flow); 654 flow_free(flow); 655 } 656 } 657 658 659 int 660 sa_address(struct iked_sa *sa, struct iked_addr *addr, struct sockaddr *peer) 661 { 662 bzero(addr, sizeof(*addr)); 663 addr->addr_af = peer->sa_family; 664 addr->addr_port = htons(socket_getport(peer)); 665 memcpy(&addr->addr, peer, peer->sa_len); 666 if (socket_af((struct sockaddr *)&addr->addr, addr->addr_port) == -1) { 667 log_debug("%s: invalid address", __func__); 668 return (-1); 669 } 670 return (0); 671 } 672 673 int 674 sa_configure_iface(struct iked *env, struct iked_sa *sa, int add) 675 { 676 struct iked_flow *saflow; 677 struct iovec iov[4]; 678 int iovcnt; 679 struct sockaddr *caddr; 680 struct sockaddr_in *addr; 681 struct sockaddr_in mask; 682 struct sockaddr_in6 *addr6; 683 struct sockaddr_in6 mask6; 684 int rdomain; 685 686 if (sa->sa_policy == NULL || sa->sa_policy->pol_iface == 0) 687 return (0); 688 689 if (!sa->sa_cp_addr && !sa->sa_cp_addr6) 690 return (0); 691 692 if (sa->sa_cp_addr) { 693 iovcnt = 0; 694 addr = (struct sockaddr_in *)&sa->sa_cp_addr->addr; 695 iov[0].iov_base = addr; 696 iov[0].iov_len = sizeof(*addr); 697 iovcnt++; 698 699 bzero(&mask, sizeof(mask)); 700 mask.sin_addr.s_addr = 701 prefixlen2mask(sa->sa_cp_addr->addr_mask ? 702 sa->sa_cp_addr->addr_mask : 32); 703 mask.sin_family = AF_INET; 704 mask.sin_len = sizeof(mask); 705 iov[1].iov_base = &mask; 706 iov[1].iov_len = sizeof(mask); 707 iovcnt++; 708 709 iov[2].iov_base = &sa->sa_policy->pol_iface; 710 iov[2].iov_len = sizeof(sa->sa_policy->pol_iface); 711 iovcnt++; 712 713 if(proc_composev(&env->sc_ps, PROC_PARENT, 714 add ? IMSG_IF_ADDADDR : IMSG_IF_DELADDR, 715 iov, iovcnt)) 716 return (-1); 717 } 718 if (sa->sa_cp_addr6) { 719 iovcnt = 0; 720 addr6 = (struct sockaddr_in6 *)&sa->sa_cp_addr6->addr; 721 iov[0].iov_base = addr6; 722 iov[0].iov_len = sizeof(*addr6); 723 iovcnt++; 724 725 bzero(&mask6, sizeof(mask6)); 726 prefixlen2mask6(sa->sa_cp_addr6->addr_mask ? 727 sa->sa_cp_addr6->addr_mask : 128, 728 (uint32_t *)&mask6.sin6_addr.s6_addr); 729 mask6.sin6_family = AF_INET6; 730 mask6.sin6_len = sizeof(mask6); 731 iov[1].iov_base = &mask6; 732 iov[1].iov_len = sizeof(mask6); 733 iovcnt++; 734 735 iov[2].iov_base = &sa->sa_policy->pol_iface; 736 iov[2].iov_len = sizeof(sa->sa_policy->pol_iface); 737 iovcnt++; 738 739 if(proc_composev(&env->sc_ps, PROC_PARENT, 740 add ? IMSG_IF_ADDADDR : IMSG_IF_DELADDR, 741 iov, iovcnt)) 742 return (-1); 743 } 744 745 if (add) { 746 /* Add direct route to peer */ 747 if (vroute_setcloneroute(env, getrtable(), 748 (struct sockaddr *)&sa->sa_peer.addr, 0, NULL)) 749 return (-1); 750 } else { 751 if (vroute_setdelroute(env, getrtable(), 752 (struct sockaddr *)&sa->sa_peer.addr, 753 0, NULL)) 754 return (-1); 755 } 756 757 TAILQ_FOREACH(saflow, &sa->sa_flows, flow_entry) { 758 rdomain = saflow->flow_rdomain == -1 ? 759 getrtable() : saflow->flow_rdomain; 760 761 switch(saflow->flow_src.addr_af) { 762 case AF_INET: 763 caddr = (struct sockaddr *)&sa->sa_cp_addr->addr; 764 break; 765 case AF_INET6: 766 caddr = (struct sockaddr *)&sa->sa_cp_addr6->addr; 767 break; 768 default: 769 return (-1); 770 } 771 if (sockaddr_cmp((struct sockaddr *)&saflow->flow_src.addr, 772 caddr, -1) != 0) 773 continue; 774 775 if (add) { 776 if (vroute_setaddroute(env, rdomain, 777 (struct sockaddr *)&saflow->flow_dst.addr, 778 saflow->flow_dst.addr_mask, caddr)) 779 return (-1); 780 } else { 781 if (vroute_setdelroute(env, rdomain, 782 (struct sockaddr *)&saflow->flow_dst.addr, 783 saflow->flow_dst.addr_mask, caddr)) 784 return (-1); 785 } 786 } 787 788 return (0); 789 } 790 791 void 792 childsa_free(struct iked_childsa *csa) 793 { 794 struct iked_childsa *csb; 795 796 if (csa == NULL) 797 return; 798 799 if (csa->csa_loaded) 800 log_info("%s: CHILD SA spi %s is still loaded", 801 csa->csa_ikesa ? SPI_SA(csa->csa_ikesa, __func__) : 802 __func__, 803 print_spi(csa->csa_spi.spi, csa->csa_spi.spi_size)); 804 if ((csb = csa->csa_bundled) != NULL) 805 csb->csa_bundled = NULL; 806 if ((csb = csa->csa_peersa) != NULL) 807 csb->csa_peersa = NULL; 808 ibuf_release(csa->csa_encrkey); 809 ibuf_release(csa->csa_integrkey); 810 free(csa); 811 } 812 813 struct iked_childsa * 814 childsa_lookup(struct iked_sa *sa, uint64_t spi, uint8_t protoid) 815 { 816 struct iked_childsa *csa; 817 818 if (sa == NULL || spi == 0 || protoid == 0) 819 return (NULL); 820 821 TAILQ_FOREACH(csa, &sa->sa_childsas, csa_entry) { 822 if (csa->csa_spi.spi_protoid == protoid && 823 (csa->csa_spi.spi == spi)) 824 break; 825 } 826 return (csa); 827 } 828 829 void 830 flow_free(struct iked_flow *flow) 831 { 832 free(flow); 833 } 834 835 struct iked_sa * 836 sa_lookup(struct iked *env, uint64_t ispi, uint64_t rspi, 837 unsigned int initiator) 838 { 839 struct iked_sa *sa, key; 840 841 key.sa_hdr.sh_ispi = ispi; 842 key.sa_hdr.sh_initiator = initiator; 843 844 if ((sa = RB_FIND(iked_sas, &env->sc_sas, &key)) != NULL) { 845 gettimeofday(&sa->sa_timeused, NULL); 846 847 /* Validate if SPIr matches */ 848 if ((sa->sa_hdr.sh_rspi != 0) && 849 (rspi != 0) && 850 (sa->sa_hdr.sh_rspi != rspi)) 851 return (NULL); 852 } 853 854 return (sa); 855 } 856 857 static __inline int 858 sa_cmp(struct iked_sa *a, struct iked_sa *b) 859 { 860 if (a->sa_hdr.sh_initiator > b->sa_hdr.sh_initiator) 861 return (-1); 862 if (a->sa_hdr.sh_initiator < b->sa_hdr.sh_initiator) 863 return (1); 864 865 if (a->sa_hdr.sh_ispi > b->sa_hdr.sh_ispi) 866 return (-1); 867 if (a->sa_hdr.sh_ispi < b->sa_hdr.sh_ispi) 868 return (1); 869 870 return (0); 871 } 872 873 static struct iked_id * 874 sa_dstid_checked(struct iked_sa *sa) 875 { 876 struct iked_id *id; 877 878 id = IKESA_DSTID(sa); 879 if (id == NULL || id->id_buf == NULL || 880 ibuf_data(id->id_buf) == NULL) 881 return (NULL); 882 if (ibuf_size(id->id_buf) <= id->id_offset) 883 return (NULL); 884 return (id); 885 } 886 887 struct iked_sa * 888 sa_dstid_lookup(struct iked *env, struct iked_sa *key) 889 { 890 struct iked_sa *sa; 891 892 if (sa_dstid_checked(key) == NULL) 893 fatalx("%s: no id for key %p", __func__, key); 894 sa = RB_FIND(iked_dstid_sas, &env->sc_dstid_sas, key); 895 if (sa != NULL && !sa->sa_dstid_entry_valid) 896 fatalx("%s: sa %p not estab (key %p)", __func__, sa, key); 897 return (sa); 898 } 899 900 struct iked_sa * 901 sa_dstid_insert(struct iked *env, struct iked_sa *sa) 902 { 903 struct iked_sa *osa; 904 905 if (sa->sa_dstid_entry_valid) 906 fatalx("%s: sa %p is estab", __func__, sa); 907 if (sa_dstid_checked(sa) == NULL) 908 fatalx("%s: no id for sa %p", __func__, sa); 909 osa = RB_FIND(iked_dstid_sas, &env->sc_dstid_sas, sa); 910 if (osa == NULL) { 911 osa = RB_INSERT(iked_dstid_sas, &env->sc_dstid_sas, sa); 912 if (osa && osa != sa) { 913 log_warnx("%s: duplicate IKE SA", SPI_SA(sa, __func__)); 914 return (osa); 915 } 916 sa->sa_dstid_entry_valid = 1; 917 return (NULL); 918 } 919 if (!osa->sa_dstid_entry_valid) 920 fatalx("%s: osa %p not estab (sa %p)", __func__, osa, sa); 921 return (osa); 922 } 923 924 void 925 sa_dstid_remove(struct iked *env, struct iked_sa *sa) 926 { 927 if (!sa->sa_dstid_entry_valid) 928 fatalx("%s: sa %p is not estab", __func__, sa); 929 if (sa_dstid_checked(sa) == NULL) 930 fatalx("%s: no id for sa %p", __func__, sa); 931 RB_REMOVE(iked_dstid_sas, &env->sc_dstid_sas, sa); 932 sa->sa_dstid_entry_valid = 0; 933 } 934 935 static __inline int 936 sa_dstid_cmp(struct iked_sa *a, struct iked_sa *b) 937 { 938 struct iked_id *aid = NULL, *bid = NULL; 939 size_t alen, blen; 940 uint8_t *aptr, *bptr; 941 942 aid = sa_dstid_checked(a); 943 bid = sa_dstid_checked(b); 944 if (aid == NULL || bid == NULL) 945 fatalx("corrupt IDs"); 946 if (aid->id_type > bid->id_type) 947 return (-1); 948 else if (aid->id_type < bid->id_type) 949 return (1); 950 alen = ibuf_size(aid->id_buf); 951 blen = ibuf_size(bid->id_buf); 952 aptr = ibuf_data(aid->id_buf); 953 bptr = ibuf_data(bid->id_buf); 954 if (aptr == NULL || bptr == NULL) 955 fatalx("corrupt ID bufs"); 956 if (alen <= aid->id_offset || blen <= bid->id_offset) 957 fatalx("corrupt ID lens"); 958 aptr += aid->id_offset; 959 alen -= aid->id_offset; 960 bptr += bid->id_offset; 961 blen -= bid->id_offset; 962 if (alen > blen) 963 return (-1); 964 if (alen < blen) 965 return (1); 966 return (memcmp(aptr, bptr, alen)); 967 } 968 969 static __inline int 970 sa_addrpool_cmp(struct iked_sa *a, struct iked_sa *b) 971 { 972 return (sockaddr_cmp((struct sockaddr *)&a->sa_addrpool->addr, 973 (struct sockaddr *)&b->sa_addrpool->addr, -1)); 974 } 975 976 static __inline int 977 sa_addrpool6_cmp(struct iked_sa *a, struct iked_sa *b) 978 { 979 return (sockaddr_cmp((struct sockaddr *)&a->sa_addrpool6->addr, 980 (struct sockaddr *)&b->sa_addrpool6->addr, -1)); 981 } 982 983 struct iked_user * 984 user_lookup(struct iked *env, const char *user) 985 { 986 struct iked_user key; 987 988 if (strlcpy(key.usr_name, user, 989 sizeof(key.usr_name)) >= sizeof(key.usr_name)) 990 return (NULL); 991 992 return (RB_FIND(iked_users, &env->sc_users, &key)); 993 } 994 995 static __inline int 996 user_cmp(struct iked_user *a, struct iked_user *b) 997 { 998 return (strcmp(a->usr_name, b->usr_name)); 999 } 1000 1001 /* 1002 * Find a matching subset of the proposal lists 'local' and 'peer'. 1003 * The resulting proposal is stored in 'result' if 'result' is not NULL. 1004 * The 'rekey' parameter indicates a CREATE_CHILD_SA exchange where 1005 * an extra group is necessary for PFS. For the initial IKE_AUTH exchange 1006 * the ESP SA proposal never includes an explicit DH group. 1007 * 1008 * Return 0 if a matching subset was found and -1 if no subset was found 1009 * or an error occured. 1010 */ 1011 int 1012 proposals_negotiate(struct iked_proposals *result, struct iked_proposals *local, 1013 struct iked_proposals *peer, int rekey) 1014 { 1015 struct iked_proposal *ppeer = NULL, *plocal, *prop, vpeer, vlocal; 1016 struct iked_transform chosen[IKEV2_XFORMTYPE_MAX]; 1017 struct iked_transform *valid[IKEV2_XFORMTYPE_MAX]; 1018 struct iked_transform *match[IKEV2_XFORMTYPE_MAX]; 1019 unsigned int i, score, chosen_score = 0; 1020 uint8_t protoid = 0; 1021 1022 bzero(valid, sizeof(valid)); 1023 bzero(&vlocal, sizeof(vlocal)); 1024 bzero(&vpeer, sizeof(vpeer)); 1025 1026 if (TAILQ_EMPTY(peer)) { 1027 log_debug("%s: peer did not send %s proposals", __func__, 1028 print_map(protoid, ikev2_saproto_map)); 1029 return (-1); 1030 } 1031 1032 TAILQ_FOREACH(plocal, local, prop_entry) { 1033 TAILQ_FOREACH(ppeer, peer, prop_entry) { 1034 if (ppeer->prop_protoid != plocal->prop_protoid) 1035 continue; 1036 bzero(match, sizeof(match)); 1037 score = proposals_match(plocal, ppeer, match, 1038 rekey); 1039 log_debug("%s: score %d", __func__, score); 1040 if (score && (!chosen_score || score < chosen_score)) { 1041 chosen_score = score; 1042 for (i = 0; i < IKEV2_XFORMTYPE_MAX; i++) { 1043 if ((valid[i] = match[i])) 1044 memcpy(&chosen[i], match[i], 1045 sizeof(chosen[0])); 1046 } 1047 memcpy(&vpeer, ppeer, sizeof(vpeer)); 1048 memcpy(&vlocal, plocal, sizeof(vlocal)); 1049 } 1050 } 1051 if (chosen_score != 0) 1052 break; 1053 } 1054 1055 if (chosen_score == 0) 1056 return (-1); 1057 else if (result == NULL) 1058 return (0); 1059 1060 (void)config_free_proposals(result, vpeer.prop_protoid); 1061 prop = config_add_proposal(result, vpeer.prop_id, vpeer.prop_protoid); 1062 1063 if (vpeer.prop_localspi.spi_size) { 1064 prop->prop_localspi.spi_size = vpeer.prop_localspi.spi_size; 1065 prop->prop_peerspi = vpeer.prop_peerspi; 1066 } 1067 if (vlocal.prop_localspi.spi_size) { 1068 prop->prop_localspi.spi_size = vlocal.prop_localspi.spi_size; 1069 prop->prop_localspi.spi = vlocal.prop_localspi.spi; 1070 } 1071 1072 for (i = 0; i < IKEV2_XFORMTYPE_MAX; i++) { 1073 if (valid[i] == NULL) 1074 continue; 1075 print_debug("%s: score %d: %s %s", __func__, 1076 chosen[i].xform_score, print_map(i, ikev2_xformtype_map), 1077 print_map(chosen[i].xform_id, chosen[i].xform_map)); 1078 if (chosen[i].xform_length) 1079 print_debug(" %d", chosen[i].xform_length); 1080 print_debug("\n"); 1081 1082 if (config_add_transform(prop, chosen[i].xform_type, 1083 chosen[i].xform_id, chosen[i].xform_length, 1084 chosen[i].xform_keylength) != 0) 1085 break; 1086 } 1087 1088 return (0); 1089 } 1090 1091 static int 1092 proposals_match(struct iked_proposal *local, struct iked_proposal *peer, 1093 struct iked_transform **xforms, int rekey) 1094 { 1095 struct iked_transform *tpeer, *tlocal; 1096 unsigned int i, j, type, score, requiredh = 0, nodh = 0, noauth = 0; 1097 uint8_t protoid = peer->prop_protoid; 1098 uint8_t peerxfs[IKEV2_XFORMTYPE_MAX]; 1099 1100 bzero(peerxfs, sizeof(peerxfs)); 1101 1102 for (i = 0; i < peer->prop_nxforms; i++) { 1103 tpeer = peer->prop_xforms + i; 1104 /* If any of the ENC transforms is an AEAD, ignore auth */ 1105 if (tpeer->xform_type == IKEV2_XFORMTYPE_ENCR && 1106 encxf_noauth(tpeer->xform_id)) 1107 noauth = 1; 1108 } 1109 1110 for (i = 0; i < peer->prop_nxforms; i++) { 1111 tpeer = peer->prop_xforms + i; 1112 if (tpeer->xform_type > IKEV2_XFORMTYPE_MAX) 1113 continue; 1114 if (noauth && tpeer->xform_type == IKEV2_XFORMTYPE_INTEGR) 1115 return (0); 1116 1117 /* 1118 * Record all transform types from the peer's proposal, 1119 * because if we want this proposal we have to select 1120 * a transform for each proposed transform type. 1121 */ 1122 peerxfs[tpeer->xform_type] = 1; 1123 1124 for (j = 0; j < local->prop_nxforms; j++) { 1125 tlocal = local->prop_xforms + j; 1126 1127 /* 1128 * We require a DH group for ESP if there is any 1129 * local proposal with DH enabled. 1130 */ 1131 if (rekey && requiredh == 0 && 1132 protoid == IKEV2_SAPROTO_ESP && 1133 tlocal->xform_type == IKEV2_XFORMTYPE_DH && 1134 tlocal->xform_id != IKEV2_XFORMDH_NONE) 1135 requiredh = 1; 1136 1137 /* 1138 * If none is an explicit option, don't require 1139 * DH group. Overrides requiredh = 1. 1140 */ 1141 if (rekey && nodh == 0 && 1142 protoid == IKEV2_SAPROTO_ESP && 1143 tlocal->xform_type == IKEV2_XFORMTYPE_DH && 1144 tlocal->xform_id == IKEV2_XFORMDH_NONE) 1145 nodh = 1; 1146 1147 /* Compare peer and local proposals */ 1148 if (tpeer->xform_type != tlocal->xform_type || 1149 tpeer->xform_id != tlocal->xform_id || 1150 tpeer->xform_length != tlocal->xform_length) 1151 continue; 1152 type = tpeer->xform_type; 1153 1154 if (xforms[type] == NULL || tlocal->xform_score < 1155 xforms[type]->xform_score) { 1156 xforms[type] = tlocal; 1157 } else 1158 continue; 1159 1160 print_debug("%s: xform %d <-> %d (%d): %s %s " 1161 "(keylength %d <-> %d)", __func__, 1162 peer->prop_id, local->prop_id, tlocal->xform_score, 1163 print_map(type, ikev2_xformtype_map), 1164 print_map(tpeer->xform_id, tpeer->xform_map), 1165 tpeer->xform_keylength, tlocal->xform_keylength); 1166 if (tpeer->xform_length) 1167 print_debug(" %d", tpeer->xform_length); 1168 print_debug("\n"); 1169 } 1170 } 1171 1172 for (i = score = 0; i < IKEV2_XFORMTYPE_MAX; i++) { 1173 if (protoid == IKEV2_SAPROTO_IKE && xforms[i] == NULL && 1174 (i == IKEV2_XFORMTYPE_ENCR || i == IKEV2_XFORMTYPE_PRF || 1175 (!noauth && i == IKEV2_XFORMTYPE_INTEGR) || 1176 i == IKEV2_XFORMTYPE_DH)) { 1177 score = 0; 1178 break; 1179 } else if (protoid == IKEV2_SAPROTO_AH && xforms[i] == NULL && 1180 (i == IKEV2_XFORMTYPE_INTEGR || i == IKEV2_XFORMTYPE_ESN)) { 1181 score = 0; 1182 break; 1183 } else if (protoid == IKEV2_SAPROTO_ESP && xforms[i] == NULL && 1184 (i == IKEV2_XFORMTYPE_ENCR || i == IKEV2_XFORMTYPE_ESN || 1185 (requiredh && !nodh && i == IKEV2_XFORMTYPE_DH))) { 1186 score = 0; 1187 break; 1188 } else if (peerxfs[i] && xforms[i] == NULL) { 1189 score = 0; 1190 break; 1191 } else if (xforms[i] == NULL) 1192 continue; 1193 1194 score += xforms[i]->xform_score; 1195 } 1196 1197 return (score); 1198 } 1199 1200 static __inline int 1201 childsa_cmp(struct iked_childsa *a, struct iked_childsa *b) 1202 { 1203 if (a->csa_spi.spi > b->csa_spi.spi) 1204 return (1); 1205 if (a->csa_spi.spi < b->csa_spi.spi) 1206 return (-1); 1207 return (0); 1208 } 1209 1210 static __inline int 1211 addr_cmp(struct iked_addr *a, struct iked_addr *b, int useports) 1212 { 1213 int diff = 0; 1214 1215 diff = sockaddr_cmp((struct sockaddr *)&a->addr, 1216 (struct sockaddr *)&b->addr, 128); 1217 if (!diff) 1218 diff = (int)a->addr_mask - (int)b->addr_mask; 1219 if (!diff && useports) 1220 diff = a->addr_port - b->addr_port; 1221 1222 return (diff); 1223 } 1224 1225 static __inline int 1226 flow_cmp(struct iked_flow *a, struct iked_flow *b) 1227 { 1228 int diff = 0; 1229 1230 if (!diff) 1231 diff = a->flow_rdomain - b->flow_rdomain; 1232 if (!diff) 1233 diff = (int)a->flow_ipproto - (int)b->flow_ipproto; 1234 if (!diff) 1235 diff = (int)a->flow_saproto - (int)b->flow_saproto; 1236 if (!diff) 1237 diff = (int)a->flow_dir - (int)b->flow_dir; 1238 if (!diff) 1239 diff = addr_cmp(&a->flow_dst, &b->flow_dst, 1); 1240 if (!diff) 1241 diff = addr_cmp(&a->flow_src, &b->flow_src, 1); 1242 1243 return (diff); 1244 } 1245 1246 int 1247 flow_equal(struct iked_flow *a, struct iked_flow *b) 1248 { 1249 return (flow_cmp(a, b) == 0); 1250 } 1251 1252 RB_GENERATE(iked_sas, iked_sa, sa_entry, sa_cmp); 1253 RB_GENERATE(iked_dstid_sas, iked_sa, sa_dstid_entry, sa_dstid_cmp); 1254 RB_GENERATE(iked_addrpool, iked_sa, sa_addrpool_entry, sa_addrpool_cmp); 1255 RB_GENERATE(iked_addrpool6, iked_sa, sa_addrpool6_entry, sa_addrpool6_cmp); 1256 RB_GENERATE(iked_users, iked_user, usr_entry, user_cmp); 1257 RB_GENERATE(iked_activesas, iked_childsa, csa_node, childsa_cmp); 1258 RB_GENERATE(iked_flows, iked_flow, flow_node, flow_cmp); 1259