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