kernel-interface: Remove reqid parameter from get_spi/get_cpi() methods
[strongswan.git] / src / libcharon / sa / child_sa.c
1 /*
2 * Copyright (C) 2006-2011 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2006 Daniel Roethlisberger
5 * Copyright (C) 2005 Jan Hutter
6 * Hochschule fuer Technik Rapperswil
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 * for more details.
17 */
18
19 #define _GNU_SOURCE
20 #include "child_sa.h"
21
22 #include <stdio.h>
23 #include <string.h>
24 #include <time.h>
25
26 #include <hydra.h>
27 #include <daemon.h>
28 #include <collections/array.h>
29
30 ENUM(child_sa_state_names, CHILD_CREATED, CHILD_DESTROYING,
31 "CREATED",
32 "ROUTED",
33 "INSTALLING",
34 "INSTALLED",
35 "UPDATING",
36 "REKEYING",
37 "RETRYING",
38 "DELETING",
39 "DESTROYING",
40 );
41
42 typedef struct private_child_sa_t private_child_sa_t;
43
44 /**
45 * Private data of a child_sa_t object.
46 */
47 struct private_child_sa_t {
48 /**
49 * Public interface of child_sa_t.
50 */
51 child_sa_t public;
52
53 /**
54 * address of us
55 */
56 host_t *my_addr;
57
58 /**
59 * address of remote
60 */
61 host_t *other_addr;
62
63 /**
64 * our actually used SPI, 0 if unused
65 */
66 u_int32_t my_spi;
67
68 /**
69 * others used SPI, 0 if unused
70 */
71 u_int32_t other_spi;
72
73 /**
74 * our Compression Parameter Index (CPI) used, 0 if unused
75 */
76 u_int16_t my_cpi;
77
78 /**
79 * others Compression Parameter Index (CPI) used, 0 if unused
80 */
81 u_int16_t other_cpi;
82
83 /**
84 * Array for local traffic selectors
85 */
86 array_t *my_ts;
87
88 /**
89 * Array for remote traffic selectors
90 */
91 array_t *other_ts;
92
93 /**
94 * Protocol used to protect this SA, ESP|AH
95 */
96 protocol_id_t protocol;
97
98 /**
99 * reqid used for this child_sa
100 */
101 u_int32_t reqid;
102
103 /**
104 * inbound mark used for this child_sa
105 */
106 mark_t mark_in;
107
108 /**
109 * outbound mark used for this child_sa
110 */
111 mark_t mark_out;
112
113 /**
114 * absolute time when rekeying is scheduled
115 */
116 time_t rekey_time;
117
118 /**
119 * absolute time when the SA expires
120 */
121 time_t expire_time;
122
123 /**
124 * absolute time when SA has been installed
125 */
126 time_t install_time;
127
128 /**
129 * state of the CHILD_SA
130 */
131 child_sa_state_t state;
132
133 /**
134 * TRUE if this CHILD_SA is used to install trap policies
135 */
136 bool trap;
137
138 /**
139 * Specifies if UDP encapsulation is enabled (NAT traversal)
140 */
141 bool encap;
142
143 /**
144 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
145 */
146 ipcomp_transform_t ipcomp;
147
148 /**
149 * mode this SA uses, tunnel/transport
150 */
151 ipsec_mode_t mode;
152
153 /**
154 * Action to enforce if peer closes the CHILD_SA
155 */
156 action_t close_action;
157
158 /**
159 * Action to enforce if peer is considered dead
160 */
161 action_t dpd_action;
162
163 /**
164 * selected proposal
165 */
166 proposal_t *proposal;
167
168 /**
169 * config used to create this child
170 */
171 child_cfg_t *config;
172
173 /**
174 * time of last use in seconds (inbound)
175 */
176 time_t my_usetime;
177
178 /**
179 * time of last use in seconds (outbound)
180 */
181 time_t other_usetime;
182
183 /**
184 * last number of inbound bytes
185 */
186 u_int64_t my_usebytes;
187
188 /**
189 * last number of outbound bytes
190 */
191 u_int64_t other_usebytes;
192
193 /**
194 * last number of inbound packets
195 */
196 u_int64_t my_usepackets;
197
198 /**
199 * last number of outbound bytes
200 */
201 u_int64_t other_usepackets;
202 };
203
204 /**
205 * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
206 */
207 static inline u_int8_t proto_ike2ip(protocol_id_t protocol)
208 {
209 switch (protocol)
210 {
211 case PROTO_ESP:
212 return IPPROTO_ESP;
213 case PROTO_AH:
214 return IPPROTO_AH;
215 default:
216 return protocol;
217 }
218 }
219
220 METHOD(child_sa_t, get_name, char*,
221 private_child_sa_t *this)
222 {
223 return this->config->get_name(this->config);
224 }
225
226 METHOD(child_sa_t, get_reqid, u_int32_t,
227 private_child_sa_t *this)
228 {
229 return this->reqid;
230 }
231
232 METHOD(child_sa_t, get_config, child_cfg_t*,
233 private_child_sa_t *this)
234 {
235 return this->config;
236 }
237
238 METHOD(child_sa_t, set_state, void,
239 private_child_sa_t *this, child_sa_state_t state)
240 {
241 charon->bus->child_state_change(charon->bus, &this->public, state);
242 this->state = state;
243 }
244
245 METHOD(child_sa_t, get_state, child_sa_state_t,
246 private_child_sa_t *this)
247 {
248 return this->state;
249 }
250
251 METHOD(child_sa_t, get_spi, u_int32_t,
252 private_child_sa_t *this, bool inbound)
253 {
254 return inbound ? this->my_spi : this->other_spi;
255 }
256
257 METHOD(child_sa_t, get_cpi, u_int16_t,
258 private_child_sa_t *this, bool inbound)
259 {
260 return inbound ? this->my_cpi : this->other_cpi;
261 }
262
263 METHOD(child_sa_t, get_protocol, protocol_id_t,
264 private_child_sa_t *this)
265 {
266 return this->protocol;
267 }
268
269 METHOD(child_sa_t, set_protocol, void,
270 private_child_sa_t *this, protocol_id_t protocol)
271 {
272 this->protocol = protocol;
273 }
274
275 METHOD(child_sa_t, get_mode, ipsec_mode_t,
276 private_child_sa_t *this)
277 {
278 return this->mode;
279 }
280
281 METHOD(child_sa_t, set_mode, void,
282 private_child_sa_t *this, ipsec_mode_t mode)
283 {
284 this->mode = mode;
285 }
286
287 METHOD(child_sa_t, has_encap, bool,
288 private_child_sa_t *this)
289 {
290 return this->encap;
291 }
292
293 METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t,
294 private_child_sa_t *this)
295 {
296 return this->ipcomp;
297 }
298
299 METHOD(child_sa_t, set_ipcomp, void,
300 private_child_sa_t *this, ipcomp_transform_t ipcomp)
301 {
302 this->ipcomp = ipcomp;
303 }
304
305 METHOD(child_sa_t, set_close_action, void,
306 private_child_sa_t *this, action_t action)
307 {
308 this->close_action = action;
309 }
310
311 METHOD(child_sa_t, get_close_action, action_t,
312 private_child_sa_t *this)
313 {
314 return this->close_action;
315 }
316
317 METHOD(child_sa_t, set_dpd_action, void,
318 private_child_sa_t *this, action_t action)
319 {
320 this->dpd_action = action;
321 }
322
323 METHOD(child_sa_t, get_dpd_action, action_t,
324 private_child_sa_t *this)
325 {
326 return this->dpd_action;
327 }
328
329 METHOD(child_sa_t, get_proposal, proposal_t*,
330 private_child_sa_t *this)
331 {
332 return this->proposal;
333 }
334
335 METHOD(child_sa_t, set_proposal, void,
336 private_child_sa_t *this, proposal_t *proposal)
337 {
338 this->proposal = proposal->clone(proposal);
339 }
340
341 METHOD(child_sa_t, create_ts_enumerator, enumerator_t*,
342 private_child_sa_t *this, bool local)
343 {
344 if (local)
345 {
346 return array_create_enumerator(this->my_ts);
347 }
348 return array_create_enumerator(this->other_ts);
349 }
350
351 typedef struct policy_enumerator_t policy_enumerator_t;
352
353 /**
354 * Private policy enumerator
355 */
356 struct policy_enumerator_t {
357 /** implements enumerator_t */
358 enumerator_t public;
359 /** enumerator over own TS */
360 enumerator_t *mine;
361 /** enumerator over others TS */
362 enumerator_t *other;
363 /** array of others TS, to recreate enumerator */
364 array_t *array;
365 /** currently enumerating TS for "me" side */
366 traffic_selector_t *ts;
367 };
368
369 METHOD(enumerator_t, policy_enumerate, bool,
370 policy_enumerator_t *this, traffic_selector_t **my_out,
371 traffic_selector_t **other_out)
372 {
373 traffic_selector_t *other_ts;
374
375 while (this->ts || this->mine->enumerate(this->mine, &this->ts))
376 {
377 if (!this->other->enumerate(this->other, &other_ts))
378 { /* end of others list, restart with new of mine */
379 this->other->destroy(this->other);
380 this->other = array_create_enumerator(this->array);
381 this->ts = NULL;
382 continue;
383 }
384 if (this->ts->get_type(this->ts) != other_ts->get_type(other_ts))
385 { /* family mismatch */
386 continue;
387 }
388 if (this->ts->get_protocol(this->ts) &&
389 other_ts->get_protocol(other_ts) &&
390 this->ts->get_protocol(this->ts) != other_ts->get_protocol(other_ts))
391 { /* protocol mismatch */
392 continue;
393 }
394 *my_out = this->ts;
395 *other_out = other_ts;
396 return TRUE;
397 }
398 return FALSE;
399 }
400
401 METHOD(enumerator_t, policy_destroy, void,
402 policy_enumerator_t *this)
403 {
404 this->mine->destroy(this->mine);
405 this->other->destroy(this->other);
406 free(this);
407 }
408
409 METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
410 private_child_sa_t *this)
411 {
412 policy_enumerator_t *e;
413
414 INIT(e,
415 .public = {
416 .enumerate = (void*)_policy_enumerate,
417 .destroy = _policy_destroy,
418 },
419 .mine = array_create_enumerator(this->my_ts),
420 .other = array_create_enumerator(this->other_ts),
421 .array = this->other_ts,
422 .ts = NULL,
423 );
424
425 return &e->public;
426 }
427
428 /**
429 * update the cached usebytes
430 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
431 * are available, and NOT_SUPPORTED if the kernel interface does not support
432 * querying the usebytes.
433 */
434 static status_t update_usebytes(private_child_sa_t *this, bool inbound)
435 {
436 status_t status = FAILED;
437 u_int64_t bytes, packets;
438 time_t time;
439
440 if (inbound)
441 {
442 if (this->my_spi)
443 {
444 status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
445 this->other_addr, this->my_addr, this->my_spi,
446 proto_ike2ip(this->protocol), this->mark_in,
447 &bytes, &packets, &time);
448 if (status == SUCCESS)
449 {
450 if (bytes > this->my_usebytes)
451 {
452 this->my_usebytes = bytes;
453 this->my_usepackets = packets;
454 if (time)
455 {
456 this->my_usetime = time;
457 }
458 return SUCCESS;
459 }
460 return FAILED;
461 }
462 }
463 }
464 else
465 {
466 if (this->other_spi)
467 {
468 status = hydra->kernel_interface->query_sa(hydra->kernel_interface,
469 this->my_addr, this->other_addr, this->other_spi,
470 proto_ike2ip(this->protocol), this->mark_out,
471 &bytes, &packets, &time);
472 if (status == SUCCESS)
473 {
474 if (bytes > this->other_usebytes)
475 {
476 this->other_usebytes = bytes;
477 this->other_usepackets = packets;
478 if (time)
479 {
480 this->other_usetime = time;
481 }
482 return SUCCESS;
483 }
484 return FAILED;
485 }
486 }
487 }
488 return status;
489 }
490
491 /**
492 * updates the cached usetime
493 */
494 static bool update_usetime(private_child_sa_t *this, bool inbound)
495 {
496 enumerator_t *enumerator;
497 traffic_selector_t *my_ts, *other_ts;
498 time_t last_use = 0;
499
500 enumerator = create_policy_enumerator(this);
501 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
502 {
503 time_t in, out, fwd;
504
505 if (inbound)
506 {
507 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
508 other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS)
509 {
510 last_use = max(last_use, in);
511 }
512 if (this->mode != MODE_TRANSPORT)
513 {
514 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
515 other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS)
516 {
517 last_use = max(last_use, fwd);
518 }
519 }
520 }
521 else
522 {
523 if (hydra->kernel_interface->query_policy(hydra->kernel_interface,
524 my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS)
525 {
526 last_use = max(last_use, out);
527 }
528 }
529 }
530 enumerator->destroy(enumerator);
531
532 if (last_use == 0)
533 {
534 return FALSE;
535 }
536 if (inbound)
537 {
538 this->my_usetime = last_use;
539 }
540 else
541 {
542 this->other_usetime = last_use;
543 }
544 return TRUE;
545 }
546
547 METHOD(child_sa_t, get_usestats, void,
548 private_child_sa_t *this, bool inbound,
549 time_t *time, u_int64_t *bytes, u_int64_t *packets)
550 {
551 if ((!bytes && !packets) || update_usebytes(this, inbound) != FAILED)
552 {
553 /* there was traffic since last update or the kernel interface
554 * does not support querying the number of usebytes.
555 */
556 if (time)
557 {
558 if (!update_usetime(this, inbound) && !bytes && !packets)
559 {
560 /* if policy query did not yield a usetime, query SAs instead */
561 update_usebytes(this, inbound);
562 }
563 }
564 }
565 if (time)
566 {
567 *time = inbound ? this->my_usetime : this->other_usetime;
568 }
569 if (bytes)
570 {
571 *bytes = inbound ? this->my_usebytes : this->other_usebytes;
572 }
573 if (packets)
574 {
575 *packets = inbound ? this->my_usepackets : this->other_usepackets;
576 }
577 }
578
579 METHOD(child_sa_t, get_mark, mark_t,
580 private_child_sa_t *this, bool inbound)
581 {
582 if (inbound)
583 {
584 return this->mark_in;
585 }
586 return this->mark_out;
587 }
588
589 METHOD(child_sa_t, get_lifetime, time_t,
590 private_child_sa_t *this, bool hard)
591 {
592 return hard ? this->expire_time : this->rekey_time;
593 }
594
595 METHOD(child_sa_t, get_installtime, time_t,
596 private_child_sa_t *this)
597 {
598 return this->install_time;
599 }
600
601 METHOD(child_sa_t, alloc_spi, u_int32_t,
602 private_child_sa_t *this, protocol_id_t protocol)
603 {
604 if (hydra->kernel_interface->get_spi(hydra->kernel_interface,
605 this->other_addr, this->my_addr,
606 proto_ike2ip(protocol),
607 &this->my_spi) == SUCCESS)
608 {
609 /* if we allocate a SPI, but then are unable to establish the SA, we
610 * need to know the protocol family to delete the partial SA */
611 this->protocol = protocol;
612 return this->my_spi;
613 }
614 return 0;
615 }
616
617 METHOD(child_sa_t, alloc_cpi, u_int16_t,
618 private_child_sa_t *this)
619 {
620 if (hydra->kernel_interface->get_cpi(hydra->kernel_interface,
621 this->other_addr, this->my_addr,
622 &this->my_cpi) == SUCCESS)
623 {
624 return this->my_cpi;
625 }
626 return 0;
627 }
628
629 METHOD(child_sa_t, install, status_t,
630 private_child_sa_t *this, chunk_t encr, chunk_t integ, u_int32_t spi,
631 u_int16_t cpi, bool initiator, bool inbound, bool tfcv3,
632 linked_list_t *my_ts, linked_list_t *other_ts)
633 {
634 u_int16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
635 u_int16_t esn = NO_EXT_SEQ_NUMBERS;
636 traffic_selector_t *src_ts = NULL, *dst_ts = NULL;
637 time_t now;
638 lifetime_cfg_t *lifetime;
639 u_int32_t tfc = 0;
640 host_t *src, *dst;
641 status_t status;
642 bool update = FALSE;
643
644 /* now we have to decide which spi to use. Use self allocated, if "in",
645 * or the one in the proposal, if not "in" (others). Additionally,
646 * source and dest host switch depending on the role */
647 if (inbound)
648 {
649 dst = this->my_addr;
650 src = this->other_addr;
651 if (this->my_spi == spi)
652 { /* alloc_spi has been called, do an SA update */
653 update = TRUE;
654 }
655 this->my_spi = spi;
656 this->my_cpi = cpi;
657 }
658 else
659 {
660 src = this->my_addr;
661 dst = this->other_addr;
662 this->other_spi = spi;
663 this->other_cpi = cpi;
664
665 if (tfcv3)
666 {
667 tfc = this->config->get_tfc(this->config);
668 }
669 }
670
671 DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
672 protocol_id_names, this->protocol);
673
674 /* send SA down to the kernel */
675 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
676
677 this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
678 &enc_alg, &size);
679 this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
680 &int_alg, &size);
681 this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
682 &esn, NULL);
683
684 lifetime = this->config->get_lifetime(this->config);
685
686 now = time_monotonic(NULL);
687 if (lifetime->time.rekey)
688 {
689 if (this->rekey_time)
690 {
691 this->rekey_time = min(this->rekey_time, now + lifetime->time.rekey);
692 }
693 else
694 {
695 this->rekey_time = now + lifetime->time.rekey;
696 }
697 }
698 if (lifetime->time.life)
699 {
700 this->expire_time = now + lifetime->time.life;
701 }
702
703 if (!lifetime->time.jitter && !inbound)
704 { /* avoid triggering multiple rekey events */
705 lifetime->time.rekey = 0;
706 }
707
708 /* BEET requires the bound address from the traffic selectors.
709 * TODO: We add just the first traffic selector for now, as the
710 * kernel accepts a single TS per SA only */
711 if (inbound)
712 {
713 my_ts->get_first(my_ts, (void**)&dst_ts);
714 other_ts->get_first(other_ts, (void**)&src_ts);
715 }
716 else
717 {
718 my_ts->get_first(my_ts, (void**)&src_ts);
719 other_ts->get_first(other_ts, (void**)&dst_ts);
720 }
721
722 status = hydra->kernel_interface->add_sa(hydra->kernel_interface,
723 src, dst, spi, proto_ike2ip(this->protocol), this->reqid,
724 inbound ? this->mark_in : this->mark_out, tfc,
725 lifetime, enc_alg, encr, int_alg, integ, this->mode,
726 this->ipcomp, cpi, this->config->get_replay_window(this->config),
727 initiator, this->encap, esn, update, src_ts, dst_ts);
728
729 free(lifetime);
730
731 return status;
732 }
733
734 /**
735 * Check kernel interface if policy updates are required
736 */
737 static bool require_policy_update()
738 {
739 kernel_feature_t f;
740
741 f = hydra->kernel_interface->get_features(hydra->kernel_interface);
742 return !(f & KERNEL_NO_POLICY_UPDATES);
743 }
744
745 /**
746 * Install 3 policies: out, in and forward
747 */
748 static status_t install_policies_internal(private_child_sa_t *this,
749 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
750 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
751 ipsec_sa_cfg_t *other_sa, policy_type_t type, policy_priority_t priority)
752 {
753 status_t status = SUCCESS;
754 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
755 my_addr, other_addr, my_ts, other_ts,
756 POLICY_OUT, type, other_sa,
757 this->mark_out, priority);
758
759 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
760 other_addr, my_addr, other_ts, my_ts,
761 POLICY_IN, type, my_sa,
762 this->mark_in, priority);
763 if (this->mode != MODE_TRANSPORT)
764 {
765 status |= hydra->kernel_interface->add_policy(hydra->kernel_interface,
766 other_addr, my_addr, other_ts, my_ts,
767 POLICY_FWD, type, my_sa,
768 this->mark_in, priority);
769 }
770 return status;
771 }
772
773 /**
774 * Delete 3 policies: out, in and forward
775 */
776 static void del_policies_internal(private_child_sa_t *this,
777 traffic_selector_t *my_ts, traffic_selector_t *other_ts,
778 policy_priority_t priority)
779 {
780 hydra->kernel_interface->del_policy(hydra->kernel_interface,
781 my_ts, other_ts, POLICY_OUT, this->reqid,
782 this->mark_out, priority);
783 hydra->kernel_interface->del_policy(hydra->kernel_interface,
784 other_ts, my_ts, POLICY_IN, this->reqid,
785 this->mark_in, priority);
786 if (this->mode != MODE_TRANSPORT)
787 {
788 hydra->kernel_interface->del_policy(hydra->kernel_interface,
789 other_ts, my_ts, POLICY_FWD, this->reqid,
790 this->mark_in, priority);
791 }
792 }
793
794 METHOD(child_sa_t, add_policies, status_t,
795 private_child_sa_t *this, linked_list_t *my_ts_list,
796 linked_list_t *other_ts_list)
797 {
798 enumerator_t *enumerator;
799 traffic_selector_t *my_ts, *other_ts;
800 status_t status = SUCCESS;
801
802 /* apply traffic selectors */
803 enumerator = my_ts_list->create_enumerator(my_ts_list);
804 while (enumerator->enumerate(enumerator, &my_ts))
805 {
806 array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts));
807 }
808 enumerator->destroy(enumerator);
809 enumerator = other_ts_list->create_enumerator(other_ts_list);
810 while (enumerator->enumerate(enumerator, &other_ts))
811 {
812 array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts));
813 }
814 enumerator->destroy(enumerator);
815
816 if (this->config->install_policy(this->config))
817 {
818 policy_priority_t priority;
819 ipsec_sa_cfg_t my_sa = {
820 .mode = this->mode,
821 .reqid = this->reqid,
822 .ipcomp = {
823 .transform = this->ipcomp,
824 },
825 }, other_sa = my_sa;
826
827 my_sa.ipcomp.cpi = this->my_cpi;
828 other_sa.ipcomp.cpi = this->other_cpi;
829
830 if (this->protocol == PROTO_ESP)
831 {
832 my_sa.esp.use = TRUE;
833 my_sa.esp.spi = this->my_spi;
834 other_sa.esp.use = TRUE;
835 other_sa.esp.spi = this->other_spi;
836 }
837 else
838 {
839 my_sa.ah.use = TRUE;
840 my_sa.ah.spi = this->my_spi;
841 other_sa.ah.use = TRUE;
842 other_sa.ah.spi = this->other_spi;
843 }
844
845 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
846 * entry) we install a trap policy */
847 this->trap = this->state == CHILD_CREATED;
848 priority = this->trap ? POLICY_PRIORITY_ROUTED
849 : POLICY_PRIORITY_DEFAULT;
850
851 enumerator = create_policy_enumerator(this);
852 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
853 {
854 my_sa.policy_count++;
855 other_sa.policy_count++;
856 }
857 enumerator->destroy(enumerator);
858
859 /* enumerate pairs of traffic selectors */
860 enumerator = create_policy_enumerator(this);
861 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
862 {
863 /* install outbound drop policy to avoid packets leaving unencrypted
864 * when updating policies */
865 if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
866 {
867 status |= install_policies_internal(this, this->my_addr,
868 this->other_addr, my_ts, other_ts,
869 &my_sa, &other_sa, POLICY_DROP,
870 POLICY_PRIORITY_FALLBACK);
871 }
872
873 /* install policies */
874 status |= install_policies_internal(this, this->my_addr,
875 this->other_addr, my_ts, other_ts,
876 &my_sa, &other_sa, POLICY_IPSEC, priority);
877
878 if (status != SUCCESS)
879 {
880 break;
881 }
882 }
883 enumerator->destroy(enumerator);
884 }
885
886 if (status == SUCCESS && this->trap)
887 {
888 set_state(this, CHILD_ROUTED);
889 }
890 return status;
891 }
892
893 /**
894 * Callback to reinstall a virtual IP
895 */
896 static void reinstall_vip(host_t *vip, host_t *me)
897 {
898 char *iface;
899
900 if (hydra->kernel_interface->get_interface(hydra->kernel_interface,
901 me, &iface))
902 {
903 hydra->kernel_interface->del_ip(hydra->kernel_interface, vip, -1, TRUE);
904 hydra->kernel_interface->add_ip(hydra->kernel_interface, vip, -1, iface);
905 free(iface);
906 }
907 }
908
909 METHOD(child_sa_t, update, status_t,
910 private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
911 bool encap)
912 {
913 child_sa_state_t old;
914 bool transport_proxy_mode;
915
916 /* anything changed at all? */
917 if (me->equals(me, this->my_addr) &&
918 other->equals(other, this->other_addr) && this->encap == encap)
919 {
920 return SUCCESS;
921 }
922
923 old = this->state;
924 set_state(this, CHILD_UPDATING);
925 transport_proxy_mode = this->config->use_proxy_mode(this->config) &&
926 this->mode == MODE_TRANSPORT;
927
928 if (!transport_proxy_mode)
929 {
930 /* update our (initiator) SA */
931 if (this->my_spi)
932 {
933 if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
934 this->my_spi, proto_ike2ip(this->protocol),
935 this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
936 this->other_addr, this->my_addr, other, me,
937 this->encap, encap, this->mark_in) == NOT_SUPPORTED)
938 {
939 set_state(this, old);
940 return NOT_SUPPORTED;
941 }
942 }
943
944 /* update his (responder) SA */
945 if (this->other_spi)
946 {
947 if (hydra->kernel_interface->update_sa(hydra->kernel_interface,
948 this->other_spi, proto_ike2ip(this->protocol),
949 this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
950 this->my_addr, this->other_addr, me, other,
951 this->encap, encap, this->mark_out) == NOT_SUPPORTED)
952 {
953 set_state(this, old);
954 return NOT_SUPPORTED;
955 }
956 }
957 }
958
959 if (this->config->install_policy(this->config) && require_policy_update())
960 {
961 ipsec_sa_cfg_t my_sa = {
962 .mode = this->mode,
963 .reqid = this->reqid,
964 .ipcomp = {
965 .transform = this->ipcomp,
966 },
967 }, other_sa = my_sa;
968
969 my_sa.ipcomp.cpi = this->my_cpi;
970 other_sa.ipcomp.cpi = this->other_cpi;
971
972 if (this->protocol == PROTO_ESP)
973 {
974 my_sa.esp.use = TRUE;
975 my_sa.esp.spi = this->my_spi;
976 other_sa.esp.use = TRUE;
977 other_sa.esp.spi = this->other_spi;
978 }
979 else
980 {
981 my_sa.ah.use = TRUE;
982 my_sa.ah.spi = this->my_spi;
983 other_sa.ah.use = TRUE;
984 other_sa.ah.spi = this->other_spi;
985 }
986
987 /* update policies */
988 if (!me->ip_equals(me, this->my_addr) ||
989 !other->ip_equals(other, this->other_addr))
990 {
991 enumerator_t *enumerator;
992 traffic_selector_t *my_ts, *other_ts;
993
994 /* always use high priorities, as hosts getting updated are INSTALLED */
995 enumerator = create_policy_enumerator(this);
996 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
997 {
998 traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
999 /* remove old policies first */
1000 del_policies_internal(this, my_ts, other_ts,
1001 POLICY_PRIORITY_DEFAULT);
1002
1003 /* check if we have to update a "dynamic" traffic selector */
1004 if (!me->ip_equals(me, this->my_addr) &&
1005 my_ts->is_host(my_ts, this->my_addr))
1006 {
1007 old_my_ts = my_ts->clone(my_ts);
1008 my_ts->set_address(my_ts, me);
1009 }
1010 if (!other->ip_equals(other, this->other_addr) &&
1011 other_ts->is_host(other_ts, this->other_addr))
1012 {
1013 old_other_ts = other_ts->clone(other_ts);
1014 other_ts->set_address(other_ts, other);
1015 }
1016
1017 /* we reinstall the virtual IP to handle interface roaming
1018 * correctly */
1019 vips->invoke_function(vips, (void*)reinstall_vip, me);
1020
1021 /* reinstall updated policies */
1022 install_policies_internal(this, me, other, my_ts, other_ts,
1023 &my_sa, &other_sa, POLICY_IPSEC,
1024 POLICY_PRIORITY_DEFAULT);
1025
1026 /* update fallback policies after the new policy is in place */
1027 if (old_my_ts || old_other_ts)
1028 {
1029 del_policies_internal(this, old_my_ts ?: my_ts,
1030 old_other_ts ?: other_ts,
1031 POLICY_PRIORITY_FALLBACK);
1032 install_policies_internal(this, me, other, my_ts, other_ts,
1033 &my_sa, &other_sa, POLICY_DROP,
1034 POLICY_PRIORITY_FALLBACK);
1035 DESTROY_IF(old_my_ts);
1036 DESTROY_IF(old_other_ts);
1037 }
1038 }
1039 enumerator->destroy(enumerator);
1040 }
1041 }
1042
1043 if (!transport_proxy_mode)
1044 {
1045 /* apply hosts */
1046 if (!me->equals(me, this->my_addr))
1047 {
1048 this->my_addr->destroy(this->my_addr);
1049 this->my_addr = me->clone(me);
1050 }
1051 if (!other->equals(other, this->other_addr))
1052 {
1053 this->other_addr->destroy(this->other_addr);
1054 this->other_addr = other->clone(other);
1055 }
1056 }
1057
1058 this->encap = encap;
1059 set_state(this, old);
1060
1061 return SUCCESS;
1062 }
1063
1064 METHOD(child_sa_t, destroy, void,
1065 private_child_sa_t *this)
1066 {
1067 enumerator_t *enumerator;
1068 traffic_selector_t *my_ts, *other_ts;
1069 policy_priority_t priority;
1070
1071 priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
1072
1073 set_state(this, CHILD_DESTROYING);
1074
1075 /* delete SAs in the kernel, if they are set up */
1076 if (this->my_spi)
1077 {
1078 hydra->kernel_interface->del_sa(hydra->kernel_interface,
1079 this->other_addr, this->my_addr, this->my_spi,
1080 proto_ike2ip(this->protocol), this->my_cpi,
1081 this->mark_in);
1082 }
1083 if (this->other_spi)
1084 {
1085 hydra->kernel_interface->del_sa(hydra->kernel_interface,
1086 this->my_addr, this->other_addr, this->other_spi,
1087 proto_ike2ip(this->protocol), this->other_cpi,
1088 this->mark_out);
1089 }
1090
1091 if (this->config->install_policy(this->config))
1092 {
1093 /* delete all policies in the kernel */
1094 enumerator = create_policy_enumerator(this);
1095 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1096 {
1097 del_policies_internal(this, my_ts, other_ts, priority);
1098 if (priority == POLICY_PRIORITY_DEFAULT && require_policy_update())
1099 {
1100 del_policies_internal(this, my_ts, other_ts,
1101 POLICY_PRIORITY_FALLBACK);
1102 }
1103 }
1104 enumerator->destroy(enumerator);
1105 }
1106
1107 array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
1108 array_destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
1109 this->my_addr->destroy(this->my_addr);
1110 this->other_addr->destroy(this->other_addr);
1111 DESTROY_IF(this->proposal);
1112 this->config->destroy(this->config);
1113 free(this);
1114 }
1115
1116 /**
1117 * Get proxy address for one side, if any
1118 */
1119 static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local)
1120 {
1121 host_t *host = NULL;
1122 u_int8_t mask;
1123 enumerator_t *enumerator;
1124 linked_list_t *ts_list, *list;
1125 traffic_selector_t *ts;
1126
1127 list = linked_list_create_with_items(ike, NULL);
1128 ts_list = config->get_traffic_selectors(config, local, NULL, list);
1129 list->destroy(list);
1130
1131 enumerator = ts_list->create_enumerator(ts_list);
1132 while (enumerator->enumerate(enumerator, &ts))
1133 {
1134 if (ts->is_host(ts, NULL) && ts->to_subnet(ts, &host, &mask))
1135 {
1136 DBG1(DBG_CHD, "%s address: %H is a transport mode proxy for %H",
1137 local ? "my" : "other", ike, host);
1138 break;
1139 }
1140 }
1141 enumerator->destroy(enumerator);
1142 ts_list->destroy_offset(ts_list, offsetof(traffic_selector_t, destroy));
1143
1144 if (!host)
1145 {
1146 host = ike->clone(ike);
1147 }
1148 return host;
1149 }
1150
1151 /**
1152 * Described in header.
1153 */
1154 child_sa_t * child_sa_create(host_t *me, host_t* other,
1155 child_cfg_t *config, u_int32_t rekey, bool encap)
1156 {
1157 static refcount_t reqid = 0;
1158 private_child_sa_t *this;
1159
1160 INIT(this,
1161 .public = {
1162 .get_name = _get_name,
1163 .get_reqid = _get_reqid,
1164 .get_config = _get_config,
1165 .get_state = _get_state,
1166 .set_state = _set_state,
1167 .get_spi = _get_spi,
1168 .get_cpi = _get_cpi,
1169 .get_protocol = _get_protocol,
1170 .set_protocol = _set_protocol,
1171 .get_mode = _get_mode,
1172 .set_mode = _set_mode,
1173 .get_proposal = _get_proposal,
1174 .set_proposal = _set_proposal,
1175 .get_lifetime = _get_lifetime,
1176 .get_installtime = _get_installtime,
1177 .get_usestats = _get_usestats,
1178 .get_mark = _get_mark,
1179 .has_encap = _has_encap,
1180 .get_ipcomp = _get_ipcomp,
1181 .set_ipcomp = _set_ipcomp,
1182 .get_close_action = _get_close_action,
1183 .set_close_action = _set_close_action,
1184 .get_dpd_action = _get_dpd_action,
1185 .set_dpd_action = _set_dpd_action,
1186 .alloc_spi = _alloc_spi,
1187 .alloc_cpi = _alloc_cpi,
1188 .install = _install,
1189 .update = _update,
1190 .add_policies = _add_policies,
1191 .create_ts_enumerator = _create_ts_enumerator,
1192 .create_policy_enumerator = _create_policy_enumerator,
1193 .destroy = _destroy,
1194 },
1195 .encap = encap,
1196 .ipcomp = IPCOMP_NONE,
1197 .state = CHILD_CREATED,
1198 .my_ts = array_create(0, 0),
1199 .other_ts = array_create(0, 0),
1200 .protocol = PROTO_NONE,
1201 .mode = MODE_TUNNEL,
1202 .close_action = config->get_close_action(config),
1203 .dpd_action = config->get_dpd_action(config),
1204 .reqid = config->get_reqid(config),
1205 .mark_in = config->get_mark(config, TRUE),
1206 .mark_out = config->get_mark(config, FALSE),
1207 .install_time = time_monotonic(NULL),
1208 );
1209
1210 this->config = config;
1211 config->get_ref(config);
1212
1213 if (!this->reqid)
1214 {
1215 /* reuse old reqid if we are rekeying an existing CHILD_SA */
1216 if (rekey)
1217 {
1218 this->reqid = rekey;
1219 }
1220 else
1221 {
1222 this->reqid = charon->traps->find_reqid(charon->traps, config);
1223 if (!this->reqid)
1224 {
1225 this->reqid = ref_get(&reqid);
1226 }
1227 }
1228 }
1229
1230 if (this->mark_in.value == MARK_REQID)
1231 {
1232 this->mark_in.value = this->reqid;
1233 }
1234 if (this->mark_out.value == MARK_REQID)
1235 {
1236 this->mark_out.value = this->reqid;
1237 }
1238
1239 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1240 if (config->get_mode(config) == MODE_TRANSPORT &&
1241 config->use_proxy_mode(config))
1242 {
1243 this->mode = MODE_TRANSPORT;
1244
1245 this->my_addr = get_proxy_addr(config, me, TRUE);
1246 this->other_addr = get_proxy_addr(config, other, FALSE);
1247 }
1248 else
1249 {
1250 this->my_addr = me->clone(me);
1251 this->other_addr = other->clone(other);
1252 }
1253 return &this->public;
1254 }