child-sa: Suppress CHILD_SA state changes if there is no change
[strongswan.git] / src / libcharon / sa / child_sa.c
1 /*
2 * Copyright (C) 2006-2017 Tobias Brunner
3 * Copyright (C) 2016 Andreas Steffen
4 * Copyright (C) 2005-2008 Martin Willi
5 * Copyright (C) 2006 Daniel Roethlisberger
6 * Copyright (C) 2005 Jan Hutter
7 * HSR Hochschule fuer Technik Rapperswil
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 */
19
20 #define _GNU_SOURCE
21 #include "child_sa.h"
22
23 #include <stdio.h>
24 #include <string.h>
25 #include <time.h>
26
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 "REKEYED",
38 "RETRYING",
39 "DELETING",
40 "DESTROYING",
41 );
42
43 ENUM_FLAGS(child_sa_outbound_state_names, CHILD_OUTBOUND_REGISTERED, CHILD_OUTBOUND_POLICIES,
44 "REGISTERED",
45 "SA",
46 "POLICIES",
47 );
48
49 typedef struct private_child_sa_t private_child_sa_t;
50
51 /**
52 * Private data of a child_sa_t object.
53 */
54 struct private_child_sa_t {
55 /**
56 * Public interface of child_sa_t.
57 */
58 child_sa_t public;
59
60 /**
61 * address of us
62 */
63 host_t *my_addr;
64
65 /**
66 * address of remote
67 */
68 host_t *other_addr;
69
70 /**
71 * our actually used SPI, 0 if unused
72 */
73 uint32_t my_spi;
74
75 /**
76 * others used SPI, 0 if unused
77 */
78 uint32_t other_spi;
79
80 /**
81 * our Compression Parameter Index (CPI) used, 0 if unused
82 */
83 uint16_t my_cpi;
84
85 /**
86 * others Compression Parameter Index (CPI) used, 0 if unused
87 */
88 uint16_t other_cpi;
89
90 /**
91 * Array for local traffic selectors
92 */
93 array_t *my_ts;
94
95 /**
96 * Array for remote traffic selectors
97 */
98 array_t *other_ts;
99
100 /**
101 * Outbound encryption key cached during a rekeying
102 */
103 chunk_t encr_r;
104
105 /**
106 * Outbound integrity key cached during a rekeying
107 */
108 chunk_t integ_r;
109
110 /**
111 * Whether the outbound SA has only been registered yet during a rekeying
112 */
113 child_sa_outbound_state_t outbound_state;
114
115 /**
116 * Whether the peer supports TFCv3
117 */
118 bool tfcv3;
119
120 /**
121 * The outbound SPI of the CHILD_SA that replaced this one during a rekeying
122 */
123 uint32_t rekey_spi;
124
125 /**
126 * Protocol used to protect this SA, ESP|AH
127 */
128 protocol_id_t protocol;
129
130 /**
131 * reqid used for this child_sa
132 */
133 uint32_t reqid;
134
135 /**
136 * Did we allocate/confirm and must release the reqid?
137 */
138 bool reqid_allocated;
139
140 /**
141 * Is the reqid statically configured
142 */
143 bool static_reqid;
144
145 /**
146 * Unique CHILD_SA identifier
147 */
148 uint32_t unique_id;
149
150 /**
151 * Whether FWD policieis in the outbound direction should be installed
152 */
153 bool policies_fwd_out;
154
155 /**
156 * inbound mark used for this child_sa
157 */
158 mark_t mark_in;
159
160 /**
161 * outbound mark used for this child_sa
162 */
163 mark_t mark_out;
164
165 /**
166 * absolute time when rekeying is scheduled
167 */
168 time_t rekey_time;
169
170 /**
171 * absolute time when the SA expires
172 */
173 time_t expire_time;
174
175 /**
176 * absolute time when SA has been installed
177 */
178 time_t install_time;
179
180 /**
181 * state of the CHILD_SA
182 */
183 child_sa_state_t state;
184
185 /**
186 * TRUE if this CHILD_SA is used to install trap policies
187 */
188 bool trap;
189
190 /**
191 * Specifies if UDP encapsulation is enabled (NAT traversal)
192 */
193 bool encap;
194
195 /**
196 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
197 */
198 ipcomp_transform_t ipcomp;
199
200 /**
201 * mode this SA uses, tunnel/transport
202 */
203 ipsec_mode_t mode;
204
205 /**
206 * Action to enforce if peer closes the CHILD_SA
207 */
208 action_t close_action;
209
210 /**
211 * Action to enforce if peer is considered dead
212 */
213 action_t dpd_action;
214
215 /**
216 * selected proposal
217 */
218 proposal_t *proposal;
219
220 /**
221 * config used to create this child
222 */
223 child_cfg_t *config;
224
225 /**
226 * time of last use in seconds (inbound)
227 */
228 time_t my_usetime;
229
230 /**
231 * time of last use in seconds (outbound)
232 */
233 time_t other_usetime;
234
235 /**
236 * last number of inbound bytes
237 */
238 uint64_t my_usebytes;
239
240 /**
241 * last number of outbound bytes
242 */
243 uint64_t other_usebytes;
244
245 /**
246 * last number of inbound packets
247 */
248 uint64_t my_usepackets;
249
250 /**
251 * last number of outbound bytes
252 */
253 uint64_t other_usepackets;
254 };
255
256 /**
257 * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
258 */
259 static inline uint8_t proto_ike2ip(protocol_id_t protocol)
260 {
261 switch (protocol)
262 {
263 case PROTO_ESP:
264 return IPPROTO_ESP;
265 case PROTO_AH:
266 return IPPROTO_AH;
267 default:
268 return protocol;
269 }
270 }
271
272 METHOD(child_sa_t, get_name, char*,
273 private_child_sa_t *this)
274 {
275 return this->config->get_name(this->config);
276 }
277
278 METHOD(child_sa_t, get_reqid, uint32_t,
279 private_child_sa_t *this)
280 {
281 return this->reqid;
282 }
283
284 METHOD(child_sa_t, get_unique_id, uint32_t,
285 private_child_sa_t *this)
286 {
287 return this->unique_id;
288 }
289
290 METHOD(child_sa_t, get_config, child_cfg_t*,
291 private_child_sa_t *this)
292 {
293 return this->config;
294 }
295
296 METHOD(child_sa_t, set_state, void,
297 private_child_sa_t *this, child_sa_state_t state)
298 {
299 if (this->state != state)
300 {
301 DBG2(DBG_CHD, "CHILD_SA %s{%d} state change: %N => %N",
302 get_name(this), this->unique_id,
303 child_sa_state_names, this->state,
304 child_sa_state_names, state);
305 charon->bus->child_state_change(charon->bus, &this->public, state);
306 this->state = state;
307 }
308 }
309
310 METHOD(child_sa_t, get_state, child_sa_state_t,
311 private_child_sa_t *this)
312 {
313 return this->state;
314 }
315
316 METHOD(child_sa_t, get_outbound_state, child_sa_outbound_state_t,
317 private_child_sa_t *this)
318 {
319 return this->outbound_state;
320 }
321
322 METHOD(child_sa_t, get_spi, uint32_t,
323 private_child_sa_t *this, bool inbound)
324 {
325 return inbound ? this->my_spi : this->other_spi;
326 }
327
328 METHOD(child_sa_t, get_cpi, uint16_t,
329 private_child_sa_t *this, bool inbound)
330 {
331 return inbound ? this->my_cpi : this->other_cpi;
332 }
333
334 METHOD(child_sa_t, get_protocol, protocol_id_t,
335 private_child_sa_t *this)
336 {
337 return this->protocol;
338 }
339
340 METHOD(child_sa_t, set_protocol, void,
341 private_child_sa_t *this, protocol_id_t protocol)
342 {
343 this->protocol = protocol;
344 }
345
346 METHOD(child_sa_t, get_mode, ipsec_mode_t,
347 private_child_sa_t *this)
348 {
349 return this->mode;
350 }
351
352 METHOD(child_sa_t, set_mode, void,
353 private_child_sa_t *this, ipsec_mode_t mode)
354 {
355 this->mode = mode;
356 }
357
358 METHOD(child_sa_t, has_encap, bool,
359 private_child_sa_t *this)
360 {
361 return this->encap;
362 }
363
364 METHOD(child_sa_t, get_ipcomp, ipcomp_transform_t,
365 private_child_sa_t *this)
366 {
367 return this->ipcomp;
368 }
369
370 METHOD(child_sa_t, set_ipcomp, void,
371 private_child_sa_t *this, ipcomp_transform_t ipcomp)
372 {
373 this->ipcomp = ipcomp;
374 }
375
376 METHOD(child_sa_t, set_close_action, void,
377 private_child_sa_t *this, action_t action)
378 {
379 this->close_action = action;
380 }
381
382 METHOD(child_sa_t, get_close_action, action_t,
383 private_child_sa_t *this)
384 {
385 return this->close_action;
386 }
387
388 METHOD(child_sa_t, set_dpd_action, void,
389 private_child_sa_t *this, action_t action)
390 {
391 this->dpd_action = action;
392 }
393
394 METHOD(child_sa_t, get_dpd_action, action_t,
395 private_child_sa_t *this)
396 {
397 return this->dpd_action;
398 }
399
400 METHOD(child_sa_t, get_proposal, proposal_t*,
401 private_child_sa_t *this)
402 {
403 return this->proposal;
404 }
405
406 METHOD(child_sa_t, set_proposal, void,
407 private_child_sa_t *this, proposal_t *proposal)
408 {
409 this->proposal = proposal->clone(proposal);
410 }
411
412 METHOD(child_sa_t, create_ts_enumerator, enumerator_t*,
413 private_child_sa_t *this, bool local)
414 {
415 if (local)
416 {
417 return array_create_enumerator(this->my_ts);
418 }
419 return array_create_enumerator(this->other_ts);
420 }
421
422 typedef struct policy_enumerator_t policy_enumerator_t;
423
424 /**
425 * Private policy enumerator
426 */
427 struct policy_enumerator_t {
428 /** implements enumerator_t */
429 enumerator_t public;
430 /** enumerator over own TS */
431 enumerator_t *mine;
432 /** enumerator over others TS */
433 enumerator_t *other;
434 /** array of others TS, to recreate enumerator */
435 array_t *array;
436 /** currently enumerating TS for "me" side */
437 traffic_selector_t *ts;
438 };
439
440 METHOD(enumerator_t, policy_enumerate, bool,
441 policy_enumerator_t *this, va_list args)
442 {
443 traffic_selector_t *other_ts, **my_out, **other_out;
444
445 VA_ARGS_VGET(args, my_out, other_out);
446
447 while (this->ts || this->mine->enumerate(this->mine, &this->ts))
448 {
449 if (!this->other->enumerate(this->other, &other_ts))
450 { /* end of others list, restart with new of mine */
451 this->other->destroy(this->other);
452 this->other = array_create_enumerator(this->array);
453 this->ts = NULL;
454 continue;
455 }
456 if (this->ts->get_type(this->ts) != other_ts->get_type(other_ts))
457 { /* family mismatch */
458 continue;
459 }
460 if (this->ts->get_protocol(this->ts) &&
461 other_ts->get_protocol(other_ts) &&
462 this->ts->get_protocol(this->ts) != other_ts->get_protocol(other_ts))
463 { /* protocol mismatch */
464 continue;
465 }
466 if (my_out)
467 {
468 *my_out = this->ts;
469 }
470 if (other_out)
471 {
472 *other_out = other_ts;
473 }
474 return TRUE;
475 }
476 return FALSE;
477 }
478
479 METHOD(enumerator_t, policy_destroy, void,
480 policy_enumerator_t *this)
481 {
482 this->mine->destroy(this->mine);
483 this->other->destroy(this->other);
484 free(this);
485 }
486
487 METHOD(child_sa_t, create_policy_enumerator, enumerator_t*,
488 private_child_sa_t *this)
489 {
490 policy_enumerator_t *e;
491
492 INIT(e,
493 .public = {
494 .enumerate = enumerator_enumerate_default,
495 .venumerate = _policy_enumerate,
496 .destroy = _policy_destroy,
497 },
498 .mine = array_create_enumerator(this->my_ts),
499 .other = array_create_enumerator(this->other_ts),
500 .array = this->other_ts,
501 .ts = NULL,
502 );
503
504 return &e->public;
505 }
506
507 /**
508 * update the cached usebytes
509 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
510 * are available, and NOT_SUPPORTED if the kernel interface does not support
511 * querying the usebytes.
512 */
513 static status_t update_usebytes(private_child_sa_t *this, bool inbound)
514 {
515 status_t status = FAILED;
516 uint64_t bytes, packets;
517 time_t time;
518
519 if (inbound)
520 {
521 if (this->my_spi)
522 {
523 kernel_ipsec_sa_id_t id = {
524 .src = this->other_addr,
525 .dst = this->my_addr,
526 .spi = this->my_spi,
527 .proto = proto_ike2ip(this->protocol),
528 };
529 kernel_ipsec_query_sa_t query = {};
530
531 status = charon->kernel->query_sa(charon->kernel, &id, &query,
532 &bytes, &packets, &time);
533 if (status == SUCCESS)
534 {
535 if (bytes > this->my_usebytes)
536 {
537 this->my_usebytes = bytes;
538 this->my_usepackets = packets;
539 if (time)
540 {
541 this->my_usetime = time;
542 }
543 }
544 else
545 {
546 status = FAILED;
547 }
548 }
549 }
550 }
551 else
552 {
553 if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
554 {
555 kernel_ipsec_sa_id_t id = {
556 .src = this->my_addr,
557 .dst = this->other_addr,
558 .spi = this->other_spi,
559 .proto = proto_ike2ip(this->protocol),
560 .mark = this->mark_out,
561 };
562 kernel_ipsec_query_sa_t query = {};
563
564 status = charon->kernel->query_sa(charon->kernel, &id, &query,
565 &bytes, &packets, &time);
566 if (status == SUCCESS)
567 {
568 if (bytes > this->other_usebytes)
569 {
570 this->other_usebytes = bytes;
571 this->other_usepackets = packets;
572 if (time)
573 {
574 this->other_usetime = time;
575 }
576 }
577 else
578 {
579 status = FAILED;
580 }
581 }
582 }
583 }
584 return status;
585 }
586
587 /**
588 * updates the cached usetime
589 */
590 static bool update_usetime(private_child_sa_t *this, bool inbound)
591 {
592 enumerator_t *enumerator;
593 traffic_selector_t *my_ts, *other_ts;
594 time_t last_use = 0;
595
596 enumerator = create_policy_enumerator(this);
597 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
598 {
599 time_t in, out, fwd;
600
601 if (inbound)
602 {
603 kernel_ipsec_policy_id_t id = {
604 .dir = POLICY_IN,
605 .src_ts = other_ts,
606 .dst_ts = my_ts,
607 .mark = this->mark_in,
608 };
609 kernel_ipsec_query_policy_t query = {};
610
611 if (charon->kernel->query_policy(charon->kernel, &id, &query,
612 &in) == SUCCESS)
613 {
614 last_use = max(last_use, in);
615 }
616 if (this->mode != MODE_TRANSPORT)
617 {
618 id.dir = POLICY_FWD;
619 if (charon->kernel->query_policy(charon->kernel, &id, &query,
620 &fwd) == SUCCESS)
621 {
622 last_use = max(last_use, fwd);
623 }
624 }
625 }
626 else
627 {
628 kernel_ipsec_policy_id_t id = {
629 .dir = POLICY_OUT,
630 .src_ts = my_ts,
631 .dst_ts = other_ts,
632 .mark = this->mark_out,
633 .interface = this->config->get_interface(this->config),
634 };
635 kernel_ipsec_query_policy_t query = {};
636
637 if (charon->kernel->query_policy(charon->kernel, &id, &query,
638 &out) == SUCCESS)
639 {
640 last_use = max(last_use, out);
641 }
642 }
643 }
644 enumerator->destroy(enumerator);
645
646 if (last_use == 0)
647 {
648 return FALSE;
649 }
650 if (inbound)
651 {
652 this->my_usetime = last_use;
653 }
654 else
655 {
656 this->other_usetime = last_use;
657 }
658 return TRUE;
659 }
660
661 METHOD(child_sa_t, get_usestats, void,
662 private_child_sa_t *this, bool inbound,
663 time_t *time, uint64_t *bytes, uint64_t *packets)
664 {
665 if ((!bytes && !packets) || update_usebytes(this, inbound) != FAILED)
666 {
667 /* there was traffic since last update or the kernel interface
668 * does not support querying the number of usebytes.
669 */
670 if (time)
671 {
672 if (!update_usetime(this, inbound) && !bytes && !packets)
673 {
674 /* if policy query did not yield a usetime, query SAs instead */
675 update_usebytes(this, inbound);
676 }
677 }
678 }
679 if (time)
680 {
681 *time = inbound ? this->my_usetime : this->other_usetime;
682 }
683 if (bytes)
684 {
685 *bytes = inbound ? this->my_usebytes : this->other_usebytes;
686 }
687 if (packets)
688 {
689 *packets = inbound ? this->my_usepackets : this->other_usepackets;
690 }
691 }
692
693 METHOD(child_sa_t, get_mark, mark_t,
694 private_child_sa_t *this, bool inbound)
695 {
696 if (inbound)
697 {
698 return this->mark_in;
699 }
700 return this->mark_out;
701 }
702
703 METHOD(child_sa_t, get_lifetime, time_t,
704 private_child_sa_t *this, bool hard)
705 {
706 return hard ? this->expire_time : this->rekey_time;
707 }
708
709 METHOD(child_sa_t, get_installtime, time_t,
710 private_child_sa_t *this)
711 {
712 return this->install_time;
713 }
714
715 METHOD(child_sa_t, alloc_spi, uint32_t,
716 private_child_sa_t *this, protocol_id_t protocol)
717 {
718 if (charon->kernel->get_spi(charon->kernel, this->other_addr, this->my_addr,
719 proto_ike2ip(protocol), &this->my_spi) == SUCCESS)
720 {
721 /* if we allocate a SPI, but then are unable to establish the SA, we
722 * need to know the protocol family to delete the partial SA */
723 this->protocol = protocol;
724 return this->my_spi;
725 }
726 return 0;
727 }
728
729 METHOD(child_sa_t, alloc_cpi, uint16_t,
730 private_child_sa_t *this)
731 {
732 if (charon->kernel->get_cpi(charon->kernel, this->other_addr, this->my_addr,
733 &this->my_cpi) == SUCCESS)
734 {
735 return this->my_cpi;
736 }
737 return 0;
738 }
739
740 /**
741 * Install the given SA in the kernel
742 */
743 static status_t install_internal(private_child_sa_t *this, chunk_t encr,
744 chunk_t integ, uint32_t spi, uint16_t cpi, bool initiator, bool inbound,
745 bool tfcv3)
746 {
747 uint16_t enc_alg = ENCR_UNDEFINED, int_alg = AUTH_UNDEFINED, size;
748 uint16_t esn = NO_EXT_SEQ_NUMBERS;
749 linked_list_t *my_ts, *other_ts, *src_ts, *dst_ts;
750 time_t now;
751 kernel_ipsec_sa_id_t id;
752 kernel_ipsec_add_sa_t sa;
753 lifetime_cfg_t *lifetime;
754 uint32_t tfc = 0;
755 host_t *src, *dst;
756 status_t status;
757 bool update = FALSE;
758
759 /* BEET requires the bound address from the traffic selectors */
760 my_ts = linked_list_create_from_enumerator(
761 array_create_enumerator(this->my_ts));
762 other_ts = linked_list_create_from_enumerator(
763 array_create_enumerator(this->other_ts));
764
765 /* now we have to decide which spi to use. Use self allocated, if "in",
766 * or the one in the proposal, if not "in" (others). Additionally,
767 * source and dest host switch depending on the role */
768 if (inbound)
769 {
770 dst = this->my_addr;
771 src = this->other_addr;
772 if (this->my_spi == spi)
773 { /* alloc_spi has been called, do an SA update */
774 update = TRUE;
775 }
776 this->my_spi = spi;
777 this->my_cpi = cpi;
778 dst_ts = my_ts;
779 src_ts = other_ts;
780 }
781 else
782 {
783 src = this->my_addr;
784 dst = this->other_addr;
785 this->other_spi = spi;
786 this->other_cpi = cpi;
787 src_ts = my_ts;
788 dst_ts = other_ts;
789
790 if (tfcv3)
791 {
792 tfc = this->config->get_tfc(this->config);
793 }
794 this->outbound_state |= CHILD_OUTBOUND_SA;
795 }
796
797 DBG2(DBG_CHD, "adding %s %N SA", inbound ? "inbound" : "outbound",
798 protocol_id_names, this->protocol);
799
800 /* send SA down to the kernel */
801 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), src, dst);
802
803 this->proposal->get_algorithm(this->proposal, ENCRYPTION_ALGORITHM,
804 &enc_alg, &size);
805 this->proposal->get_algorithm(this->proposal, INTEGRITY_ALGORITHM,
806 &int_alg, &size);
807 this->proposal->get_algorithm(this->proposal, EXTENDED_SEQUENCE_NUMBERS,
808 &esn, NULL);
809
810 if (int_alg == AUTH_HMAC_SHA2_256_128 &&
811 this->config->has_option(this->config, OPT_SHA256_96))
812 {
813 DBG2(DBG_CHD, " using %N with 96-bit truncation",
814 integrity_algorithm_names, int_alg);
815 int_alg = AUTH_HMAC_SHA2_256_96;
816 }
817
818 if (!this->reqid_allocated && !this->static_reqid)
819 {
820 status = charon->kernel->alloc_reqid(charon->kernel, my_ts, other_ts,
821 this->mark_in, this->mark_out, &this->reqid);
822 if (status != SUCCESS)
823 {
824 my_ts->destroy(my_ts);
825 other_ts->destroy(other_ts);
826 return status;
827 }
828 this->reqid_allocated = TRUE;
829 }
830
831 lifetime = this->config->get_lifetime(this->config, TRUE);
832
833 now = time_monotonic(NULL);
834 if (lifetime->time.rekey)
835 {
836 if (this->rekey_time)
837 {
838 this->rekey_time = min(this->rekey_time, now + lifetime->time.rekey);
839 }
840 else
841 {
842 this->rekey_time = now + lifetime->time.rekey;
843 }
844 }
845 if (lifetime->time.life)
846 {
847 this->expire_time = now + lifetime->time.life;
848 }
849
850 if (!lifetime->time.jitter && !inbound)
851 { /* avoid triggering multiple rekey events */
852 lifetime->time.rekey = 0;
853 }
854
855 id = (kernel_ipsec_sa_id_t){
856 .src = src,
857 .dst = dst,
858 .spi = spi,
859 .proto = proto_ike2ip(this->protocol),
860 .mark = inbound ? (mark_t){} : this->mark_out,
861 };
862 sa = (kernel_ipsec_add_sa_t){
863 .reqid = this->reqid,
864 .mode = this->mode,
865 .src_ts = src_ts,
866 .dst_ts = dst_ts,
867 .interface = inbound ? NULL : this->config->get_interface(this->config),
868 .lifetime = lifetime,
869 .enc_alg = enc_alg,
870 .enc_key = encr,
871 .int_alg = int_alg,
872 .int_key = integ,
873 .replay_window = this->config->get_replay_window(this->config),
874 .tfc = tfc,
875 .ipcomp = this->ipcomp,
876 .cpi = cpi,
877 .encap = this->encap,
878 .hw_offload = this->config->has_option(this->config, OPT_HW_OFFLOAD),
879 .esn = esn,
880 .initiator = initiator,
881 .inbound = inbound,
882 .update = update,
883 };
884
885 status = charon->kernel->add_sa(charon->kernel, &id, &sa);
886
887 my_ts->destroy(my_ts);
888 other_ts->destroy(other_ts);
889 free(lifetime);
890
891 return status;
892 }
893
894 METHOD(child_sa_t, install, status_t,
895 private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
896 uint16_t cpi, bool initiator, bool inbound, bool tfcv3)
897 {
898 return install_internal(this, encr, integ, spi, cpi, initiator, inbound,
899 tfcv3);
900 }
901
902 /**
903 * Check kernel interface if policy updates are required
904 */
905 static bool require_policy_update()
906 {
907 kernel_feature_t f;
908
909 f = charon->kernel->get_features(charon->kernel);
910 return !(f & KERNEL_NO_POLICY_UPDATES);
911 }
912
913 /**
914 * Prepare SA config to install/delete policies
915 */
916 static void prepare_sa_cfg(private_child_sa_t *this, ipsec_sa_cfg_t *my_sa,
917 ipsec_sa_cfg_t *other_sa)
918 {
919 enumerator_t *enumerator;
920
921 *my_sa = (ipsec_sa_cfg_t){
922 .mode = this->mode,
923 .reqid = this->reqid,
924 .ipcomp = {
925 .transform = this->ipcomp,
926 },
927 };
928 *other_sa = *my_sa;
929
930 my_sa->ipcomp.cpi = this->my_cpi;
931 other_sa->ipcomp.cpi = this->other_cpi;
932
933 if (this->protocol == PROTO_ESP)
934 {
935 my_sa->esp.use = TRUE;
936 my_sa->esp.spi = this->my_spi;
937 other_sa->esp.use = TRUE;
938 other_sa->esp.spi = this->other_spi;
939 }
940 else
941 {
942 my_sa->ah.use = TRUE;
943 my_sa->ah.spi = this->my_spi;
944 other_sa->ah.use = TRUE;
945 other_sa->ah.spi = this->other_spi;
946 }
947
948 enumerator = create_policy_enumerator(this);
949 while (enumerator->enumerate(enumerator, NULL, NULL))
950 {
951 my_sa->policy_count++;
952 other_sa->policy_count++;
953 }
954 enumerator->destroy(enumerator);
955 }
956
957 /**
958 * Install inbound policie(s): in, fwd
959 */
960 static status_t install_policies_inbound(private_child_sa_t *this,
961 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
962 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
963 ipsec_sa_cfg_t *other_sa, policy_type_t type,
964 policy_priority_t priority, uint32_t manual_prio)
965 {
966 kernel_ipsec_policy_id_t in_id = {
967 .dir = POLICY_IN,
968 .src_ts = other_ts,
969 .dst_ts = my_ts,
970 .mark = this->mark_in,
971 };
972 kernel_ipsec_manage_policy_t in_policy = {
973 .type = type,
974 .prio = priority,
975 .manual_prio = manual_prio,
976 .src = other_addr,
977 .dst = my_addr,
978 .sa = my_sa,
979 };
980 status_t status = SUCCESS;
981
982 status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
983 if (this->mode != MODE_TRANSPORT)
984 {
985 in_id.dir = POLICY_FWD;
986 status |= charon->kernel->add_policy(charon->kernel, &in_id, &in_policy);
987 }
988 return status;
989 }
990
991 /**
992 * Install outbound policie(s): out, [fwd]
993 */
994 static status_t install_policies_outbound(private_child_sa_t *this,
995 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
996 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
997 ipsec_sa_cfg_t *other_sa, policy_type_t type,
998 policy_priority_t priority, uint32_t manual_prio)
999 {
1000 kernel_ipsec_policy_id_t out_id = {
1001 .dir = POLICY_OUT,
1002 .src_ts = my_ts,
1003 .dst_ts = other_ts,
1004 .mark = this->mark_out,
1005 .interface = this->config->get_interface(this->config),
1006 };
1007 kernel_ipsec_manage_policy_t out_policy = {
1008 .type = type,
1009 .prio = priority,
1010 .manual_prio = manual_prio,
1011 .src = my_addr,
1012 .dst = other_addr,
1013 .sa = other_sa,
1014 };
1015 status_t status = SUCCESS;
1016
1017 status |= charon->kernel->add_policy(charon->kernel, &out_id, &out_policy);
1018
1019 if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
1020 {
1021 /* install an "outbound" FWD policy in case there is a drop policy
1022 * matching outbound forwarded traffic, to allow another tunnel to use
1023 * the reversed subnets and do the same we don't set a reqid (this also
1024 * allows the kernel backend to distinguish between the two types of
1025 * FWD policies). To avoid problems with symmetrically overlapping
1026 * policies of two SAs we install them with reduced priority. As they
1027 * basically act as bypass policies for drop policies we use a higher
1028 * priority than is used for them. */
1029 out_id.dir = POLICY_FWD;
1030 other_sa->reqid = 0;
1031 if (priority == POLICY_PRIORITY_DEFAULT)
1032 {
1033 out_policy.prio = POLICY_PRIORITY_ROUTED;
1034 }
1035 status |= charon->kernel->add_policy(charon->kernel, &out_id,
1036 &out_policy);
1037 /* reset the reqid for any other further policies */
1038 other_sa->reqid = this->reqid;
1039 }
1040 return status;
1041 }
1042
1043 /**
1044 * Install all policies
1045 */
1046 static status_t install_policies_internal(private_child_sa_t *this,
1047 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1048 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1049 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1050 policy_priority_t priority, uint32_t manual_prio)
1051 {
1052 status_t status = SUCCESS;
1053
1054 status |= install_policies_inbound(this, my_addr, other_addr, my_ts,
1055 other_ts, my_sa, other_sa, type,
1056 priority, manual_prio);
1057 status |= install_policies_outbound(this, my_addr, other_addr, my_ts,
1058 other_ts, my_sa, other_sa, type,
1059 priority, manual_prio);
1060 return status;
1061 }
1062
1063 /**
1064 * Delete inbound policies: in, fwd
1065 */
1066 static void del_policies_inbound(private_child_sa_t *this,
1067 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1068 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1069 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1070 policy_priority_t priority, uint32_t manual_prio)
1071 {
1072 kernel_ipsec_policy_id_t in_id = {
1073 .dir = POLICY_IN,
1074 .src_ts = other_ts,
1075 .dst_ts = my_ts,
1076 .mark = this->mark_in,
1077 };
1078 kernel_ipsec_manage_policy_t in_policy = {
1079 .type = type,
1080 .prio = priority,
1081 .manual_prio = manual_prio,
1082 .src = other_addr,
1083 .dst = my_addr,
1084 .sa = my_sa,
1085 };
1086
1087 charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
1088
1089 if (this->mode != MODE_TRANSPORT)
1090 {
1091 in_id.dir = POLICY_FWD;
1092 charon->kernel->del_policy(charon->kernel, &in_id, &in_policy);
1093 }
1094 }
1095
1096 /**
1097 * Delete outbound policies: out, [fwd]
1098 */
1099 static void del_policies_outbound(private_child_sa_t *this,
1100 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1101 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1102 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1103 policy_priority_t priority, uint32_t manual_prio)
1104 {
1105 kernel_ipsec_policy_id_t out_id = {
1106 .dir = POLICY_OUT,
1107 .src_ts = my_ts,
1108 .dst_ts = other_ts,
1109 .mark = this->mark_out,
1110 .interface = this->config->get_interface(this->config),
1111 };
1112 kernel_ipsec_manage_policy_t out_policy = {
1113 .type = type,
1114 .prio = priority,
1115 .manual_prio = manual_prio,
1116 .src = my_addr,
1117 .dst = other_addr,
1118 .sa = other_sa,
1119 };
1120
1121 charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
1122
1123 if (this->mode != MODE_TRANSPORT && this->policies_fwd_out)
1124 {
1125 out_id.dir = POLICY_FWD;
1126 other_sa->reqid = 0;
1127 if (priority == POLICY_PRIORITY_DEFAULT)
1128 {
1129 out_policy.prio = POLICY_PRIORITY_ROUTED;
1130 }
1131 charon->kernel->del_policy(charon->kernel, &out_id, &out_policy);
1132 other_sa->reqid = this->reqid;
1133 }
1134 }
1135
1136 /**
1137 * Delete in- and outbound policies
1138 */
1139 static void del_policies_internal(private_child_sa_t *this,
1140 host_t *my_addr, host_t *other_addr, traffic_selector_t *my_ts,
1141 traffic_selector_t *other_ts, ipsec_sa_cfg_t *my_sa,
1142 ipsec_sa_cfg_t *other_sa, policy_type_t type,
1143 policy_priority_t priority, uint32_t manual_prio)
1144 {
1145 del_policies_outbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
1146 other_sa, type, priority, manual_prio);
1147 del_policies_inbound(this, my_addr, other_addr, my_ts, other_ts, my_sa,
1148 other_sa, type, priority, manual_prio);
1149 }
1150
1151 METHOD(child_sa_t, set_policies, void,
1152 private_child_sa_t *this, linked_list_t *my_ts_list,
1153 linked_list_t *other_ts_list)
1154 {
1155 enumerator_t *enumerator;
1156 traffic_selector_t *my_ts, *other_ts;
1157
1158 if (array_count(this->my_ts))
1159 {
1160 array_destroy_offset(this->my_ts,
1161 offsetof(traffic_selector_t, destroy));
1162 this->my_ts = array_create(0, 0);
1163 }
1164 enumerator = my_ts_list->create_enumerator(my_ts_list);
1165 while (enumerator->enumerate(enumerator, &my_ts))
1166 {
1167 array_insert(this->my_ts, ARRAY_TAIL, my_ts->clone(my_ts));
1168 }
1169 enumerator->destroy(enumerator);
1170 array_sort(this->my_ts, (void*)traffic_selector_cmp, NULL);
1171
1172 if (array_count(this->other_ts))
1173 {
1174 array_destroy_offset(this->other_ts,
1175 offsetof(traffic_selector_t, destroy));
1176 this->other_ts = array_create(0, 0);
1177 }
1178 enumerator = other_ts_list->create_enumerator(other_ts_list);
1179 while (enumerator->enumerate(enumerator, &other_ts))
1180 {
1181 array_insert(this->other_ts, ARRAY_TAIL, other_ts->clone(other_ts));
1182 }
1183 enumerator->destroy(enumerator);
1184 array_sort(this->other_ts, (void*)traffic_selector_cmp, NULL);
1185 }
1186
1187 METHOD(child_sa_t, install_policies, status_t,
1188 private_child_sa_t *this)
1189 {
1190 enumerator_t *enumerator;
1191 linked_list_t *my_ts_list, *other_ts_list;
1192 traffic_selector_t *my_ts, *other_ts;
1193 status_t status = SUCCESS;
1194 bool install_outbound = FALSE;
1195
1196 if (!this->reqid_allocated && !this->static_reqid)
1197 {
1198 my_ts_list = linked_list_create_from_enumerator(
1199 array_create_enumerator(this->my_ts));
1200 other_ts_list = linked_list_create_from_enumerator(
1201 array_create_enumerator(this->other_ts));
1202 status = charon->kernel->alloc_reqid(
1203 charon->kernel, my_ts_list, other_ts_list,
1204 this->mark_in, this->mark_out, &this->reqid);
1205 my_ts_list->destroy(my_ts_list);
1206 other_ts_list->destroy(other_ts_list);
1207 if (status != SUCCESS)
1208 {
1209 return status;
1210 }
1211 this->reqid_allocated = TRUE;
1212 }
1213
1214 if (!(this->outbound_state & CHILD_OUTBOUND_REGISTERED))
1215 {
1216 install_outbound = TRUE;
1217 this->outbound_state |= CHILD_OUTBOUND_POLICIES;
1218 }
1219
1220 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1221 {
1222 policy_priority_t priority;
1223 ipsec_sa_cfg_t my_sa, other_sa;
1224 uint32_t manual_prio;
1225
1226 prepare_sa_cfg(this, &my_sa, &other_sa);
1227 manual_prio = this->config->get_manual_prio(this->config);
1228
1229 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1230 * entry) we install a trap policy */
1231 this->trap = this->state == CHILD_CREATED;
1232 priority = this->trap ? POLICY_PRIORITY_ROUTED
1233 : POLICY_PRIORITY_DEFAULT;
1234
1235 /* enumerate pairs of traffic selectors */
1236 enumerator = create_policy_enumerator(this);
1237 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1238 {
1239 /* install outbound drop policy to avoid packets leaving unencrypted
1240 * when updating policies */
1241 if (priority == POLICY_PRIORITY_DEFAULT && manual_prio == 0 &&
1242 require_policy_update() && install_outbound)
1243 {
1244 status |= install_policies_outbound(this, this->my_addr,
1245 this->other_addr, my_ts, other_ts,
1246 &my_sa, &other_sa, POLICY_DROP,
1247 POLICY_PRIORITY_FALLBACK, 0);
1248 }
1249
1250 status |= install_policies_inbound(this, this->my_addr,
1251 this->other_addr, my_ts, other_ts,
1252 &my_sa, &other_sa, POLICY_IPSEC,
1253 priority, manual_prio);
1254
1255 if (install_outbound)
1256 {
1257 status |= install_policies_outbound(this, this->my_addr,
1258 this->other_addr, my_ts, other_ts,
1259 &my_sa, &other_sa, POLICY_IPSEC,
1260 priority, manual_prio);
1261 }
1262 if (status != SUCCESS)
1263 {
1264 break;
1265 }
1266 }
1267 enumerator->destroy(enumerator);
1268 }
1269
1270 if (status == SUCCESS && this->trap)
1271 {
1272 set_state(this, CHILD_ROUTED);
1273 }
1274 return status;
1275 }
1276
1277 METHOD(child_sa_t, register_outbound, status_t,
1278 private_child_sa_t *this, chunk_t encr, chunk_t integ, uint32_t spi,
1279 uint16_t cpi, bool tfcv3)
1280 {
1281 status_t status;
1282
1283 /* if the kernel supports installing SPIs with policies we install the
1284 * SA immediately as it will only be used once we update the policies */
1285 if (charon->kernel->get_features(charon->kernel) & KERNEL_POLICY_SPI)
1286 {
1287 status = install_internal(this, encr, integ, spi, cpi, FALSE, FALSE,
1288 tfcv3);
1289 }
1290 else
1291 {
1292 DBG2(DBG_CHD, "registering outbound %N SA", protocol_id_names,
1293 this->protocol);
1294 DBG2(DBG_CHD, " SPI 0x%.8x, src %H dst %H", ntohl(spi), this->my_addr,
1295 this->other_addr);
1296
1297 this->other_spi = spi;
1298 this->other_cpi = cpi;
1299 this->encr_r = chunk_clone(encr);
1300 this->integ_r = chunk_clone(integ);
1301 this->tfcv3 = tfcv3;
1302 status = SUCCESS;
1303 }
1304 this->outbound_state |= CHILD_OUTBOUND_REGISTERED;
1305 return status;
1306 }
1307
1308 METHOD(child_sa_t, install_outbound, status_t,
1309 private_child_sa_t *this)
1310 {
1311 enumerator_t *enumerator;
1312 traffic_selector_t *my_ts, *other_ts;
1313 status_t status = SUCCESS;
1314
1315 if (!(this->outbound_state & CHILD_OUTBOUND_SA))
1316 {
1317 status = install_internal(this, this->encr_r, this->integ_r,
1318 this->other_spi, this->other_cpi, FALSE,
1319 FALSE, this->tfcv3);
1320 chunk_clear(&this->encr_r);
1321 chunk_clear(&this->integ_r);
1322 }
1323 this->outbound_state &= ~CHILD_OUTBOUND_REGISTERED;
1324 if (status != SUCCESS)
1325 {
1326 return status;
1327 }
1328 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1329 !(this->outbound_state & CHILD_OUTBOUND_POLICIES))
1330 {
1331 ipsec_sa_cfg_t my_sa, other_sa;
1332 uint32_t manual_prio;
1333
1334 prepare_sa_cfg(this, &my_sa, &other_sa);
1335 manual_prio = this->config->get_manual_prio(this->config);
1336
1337 enumerator = create_policy_enumerator(this);
1338 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1339 {
1340 /* install outbound drop policy to avoid packets leaving unencrypted
1341 * when updating policies */
1342 if (manual_prio == 0 && require_policy_update())
1343 {
1344 status |= install_policies_outbound(this, this->my_addr,
1345 this->other_addr, my_ts, other_ts,
1346 &my_sa, &other_sa, POLICY_DROP,
1347 POLICY_PRIORITY_FALLBACK, 0);
1348 }
1349 status |= install_policies_outbound(this, this->my_addr,
1350 this->other_addr, my_ts, other_ts,
1351 &my_sa, &other_sa, POLICY_IPSEC,
1352 POLICY_PRIORITY_DEFAULT, manual_prio);
1353 if (status != SUCCESS)
1354 {
1355 break;
1356 }
1357 }
1358 enumerator->destroy(enumerator);
1359 }
1360 this->outbound_state |= CHILD_OUTBOUND_POLICIES;
1361 return status;
1362 }
1363
1364 METHOD(child_sa_t, remove_outbound, void,
1365 private_child_sa_t *this)
1366 {
1367 enumerator_t *enumerator;
1368 traffic_selector_t *my_ts, *other_ts;
1369
1370 if (!(this->outbound_state & CHILD_OUTBOUND_SA))
1371 {
1372 if (this->outbound_state & CHILD_OUTBOUND_REGISTERED)
1373 {
1374 chunk_clear(&this->encr_r);
1375 chunk_clear(&this->integ_r);
1376 this->outbound_state = CHILD_OUTBOUND_NONE;
1377 }
1378 return;
1379 }
1380
1381 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1382 (this->outbound_state & CHILD_OUTBOUND_POLICIES))
1383 {
1384 ipsec_sa_cfg_t my_sa, other_sa;
1385 uint32_t manual_prio;
1386
1387 prepare_sa_cfg(this, &my_sa, &other_sa);
1388 manual_prio = this->config->get_manual_prio(this->config);
1389
1390 enumerator = create_policy_enumerator(this);
1391 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1392 {
1393 del_policies_outbound(this, this->my_addr, this->other_addr,
1394 my_ts, other_ts, &my_sa, &other_sa,
1395 POLICY_IPSEC, POLICY_PRIORITY_DEFAULT,
1396 manual_prio);
1397 if (manual_prio == 0 && require_policy_update())
1398 {
1399 del_policies_outbound(this, this->my_addr, this->other_addr,
1400 my_ts, other_ts, &my_sa, &other_sa,
1401 POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
1402 }
1403 }
1404 enumerator->destroy(enumerator);
1405 }
1406
1407 kernel_ipsec_sa_id_t id = {
1408 .src = this->my_addr,
1409 .dst = this->other_addr,
1410 .spi = this->other_spi,
1411 .proto = proto_ike2ip(this->protocol),
1412 .mark = this->mark_out,
1413 };
1414 kernel_ipsec_del_sa_t sa = {
1415 .cpi = this->other_cpi,
1416 };
1417 charon->kernel->del_sa(charon->kernel, &id, &sa);
1418 this->outbound_state = CHILD_OUTBOUND_NONE;
1419 }
1420
1421 METHOD(child_sa_t, set_rekey_spi, void,
1422 private_child_sa_t *this, uint32_t spi)
1423 {
1424 this->rekey_spi = spi;
1425 }
1426
1427 METHOD(child_sa_t, get_rekey_spi, uint32_t,
1428 private_child_sa_t *this)
1429 {
1430 return this->rekey_spi;
1431 }
1432
1433 CALLBACK(reinstall_vip, void,
1434 host_t *vip, va_list args)
1435 {
1436 host_t *me;
1437 char *iface;
1438
1439 VA_ARGS_VGET(args, me);
1440 if (charon->kernel->get_interface(charon->kernel, me, &iface))
1441 {
1442 charon->kernel->del_ip(charon->kernel, vip, -1, TRUE);
1443 charon->kernel->add_ip(charon->kernel, vip, -1, iface);
1444 free(iface);
1445 }
1446 }
1447
1448 METHOD(child_sa_t, update, status_t,
1449 private_child_sa_t *this, host_t *me, host_t *other, linked_list_t *vips,
1450 bool encap)
1451 {
1452 child_sa_state_t old;
1453 bool transport_proxy_mode;
1454
1455 /* anything changed at all? */
1456 if (me->equals(me, this->my_addr) &&
1457 other->equals(other, this->other_addr) && this->encap == encap)
1458 {
1459 return SUCCESS;
1460 }
1461
1462 old = this->state;
1463 set_state(this, CHILD_UPDATING);
1464 transport_proxy_mode = this->mode == MODE_TRANSPORT &&
1465 this->config->has_option(this->config,
1466 OPT_PROXY_MODE);
1467
1468 if (!transport_proxy_mode)
1469 {
1470 /* update our (initiator) SA */
1471 if (this->my_spi)
1472 {
1473 kernel_ipsec_sa_id_t id = {
1474 .src = this->other_addr,
1475 .dst = this->my_addr,
1476 .spi = this->my_spi,
1477 .proto = proto_ike2ip(this->protocol),
1478 };
1479 kernel_ipsec_update_sa_t sa = {
1480 .cpi = this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
1481 .new_src = other,
1482 .new_dst = me,
1483 .encap = this->encap,
1484 .new_encap = encap,
1485 };
1486 if (charon->kernel->update_sa(charon->kernel, &id,
1487 &sa) == NOT_SUPPORTED)
1488 {
1489 set_state(this, old);
1490 return NOT_SUPPORTED;
1491 }
1492 }
1493
1494 /* update his (responder) SA */
1495 if (this->other_spi)
1496 {
1497 kernel_ipsec_sa_id_t id = {
1498 .src = this->my_addr,
1499 .dst = this->other_addr,
1500 .spi = this->other_spi,
1501 .proto = proto_ike2ip(this->protocol),
1502 .mark = this->mark_out,
1503 };
1504 kernel_ipsec_update_sa_t sa = {
1505 .cpi = this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
1506 .new_src = me,
1507 .new_dst = other,
1508 .encap = this->encap,
1509 .new_encap = encap,
1510 };
1511 if (charon->kernel->update_sa(charon->kernel, &id,
1512 &sa) == NOT_SUPPORTED)
1513 {
1514 set_state(this, old);
1515 return NOT_SUPPORTED;
1516 }
1517 }
1518 }
1519
1520 if (!this->config->has_option(this->config, OPT_NO_POLICIES) &&
1521 require_policy_update())
1522 {
1523 if (!me->ip_equals(me, this->my_addr) ||
1524 !other->ip_equals(other, this->other_addr))
1525 {
1526 ipsec_sa_cfg_t my_sa, other_sa;
1527 enumerator_t *enumerator;
1528 traffic_selector_t *my_ts, *other_ts;
1529 uint32_t manual_prio;
1530
1531 prepare_sa_cfg(this, &my_sa, &other_sa);
1532 manual_prio = this->config->get_manual_prio(this->config);
1533
1534 /* always use high priorities, as hosts getting updated are INSTALLED */
1535 enumerator = create_policy_enumerator(this);
1536 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1537 {
1538 traffic_selector_t *old_my_ts = NULL, *old_other_ts = NULL;
1539
1540 /* remove old policies first */
1541 del_policies_internal(this, this->my_addr, this->other_addr,
1542 my_ts, other_ts, &my_sa, &other_sa, POLICY_IPSEC,
1543 POLICY_PRIORITY_DEFAULT, manual_prio);
1544
1545 /* check if we have to update a "dynamic" traffic selector */
1546 if (!me->ip_equals(me, this->my_addr) &&
1547 my_ts->is_host(my_ts, this->my_addr))
1548 {
1549 old_my_ts = my_ts->clone(my_ts);
1550 my_ts->set_address(my_ts, me);
1551 }
1552 if (!other->ip_equals(other, this->other_addr) &&
1553 other_ts->is_host(other_ts, this->other_addr))
1554 {
1555 old_other_ts = other_ts->clone(other_ts);
1556 other_ts->set_address(other_ts, other);
1557 }
1558
1559 /* we reinstall the virtual IP to handle interface roaming
1560 * correctly */
1561 vips->invoke_function(vips, reinstall_vip, me);
1562
1563 /* reinstall updated policies */
1564 install_policies_internal(this, me, other, my_ts, other_ts,
1565 &my_sa, &other_sa, POLICY_IPSEC,
1566 POLICY_PRIORITY_DEFAULT, manual_prio);
1567
1568 /* update fallback policies after the new policy is in place */
1569 if (manual_prio == 0)
1570 {
1571 del_policies_outbound(this, this->my_addr, this->other_addr,
1572 old_my_ts ?: my_ts,
1573 old_other_ts ?: other_ts,
1574 &my_sa, &other_sa, POLICY_DROP,
1575 POLICY_PRIORITY_FALLBACK, 0);
1576 install_policies_outbound(this, me, other, my_ts, other_ts,
1577 &my_sa, &other_sa, POLICY_DROP,
1578 POLICY_PRIORITY_FALLBACK, 0);
1579 }
1580 DESTROY_IF(old_my_ts);
1581 DESTROY_IF(old_other_ts);
1582 }
1583 enumerator->destroy(enumerator);
1584 }
1585 }
1586
1587 if (!transport_proxy_mode)
1588 {
1589 /* apply hosts */
1590 if (!me->equals(me, this->my_addr))
1591 {
1592 this->my_addr->destroy(this->my_addr);
1593 this->my_addr = me->clone(me);
1594 }
1595 if (!other->equals(other, this->other_addr))
1596 {
1597 this->other_addr->destroy(this->other_addr);
1598 this->other_addr = other->clone(other);
1599 }
1600 }
1601
1602 this->encap = encap;
1603 set_state(this, old);
1604
1605 return SUCCESS;
1606 }
1607
1608 METHOD(child_sa_t, destroy, void,
1609 private_child_sa_t *this)
1610 {
1611 enumerator_t *enumerator;
1612 traffic_selector_t *my_ts, *other_ts;
1613 policy_priority_t priority;
1614
1615 priority = this->trap ? POLICY_PRIORITY_ROUTED : POLICY_PRIORITY_DEFAULT;
1616
1617 set_state(this, CHILD_DESTROYING);
1618
1619 if (!this->config->has_option(this->config, OPT_NO_POLICIES))
1620 {
1621 ipsec_sa_cfg_t my_sa, other_sa;
1622 uint32_t manual_prio;
1623 bool del_outbound;
1624
1625 prepare_sa_cfg(this, &my_sa, &other_sa);
1626 manual_prio = this->config->get_manual_prio(this->config);
1627 del_outbound = (this->outbound_state & CHILD_OUTBOUND_POLICIES) ||
1628 this->trap;
1629
1630 /* delete all policies in the kernel */
1631 enumerator = create_policy_enumerator(this);
1632 while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
1633 {
1634 if (del_outbound)
1635 {
1636 del_policies_outbound(this, this->my_addr,
1637 this->other_addr, my_ts, other_ts,
1638 &my_sa, &other_sa, POLICY_IPSEC,
1639 priority, manual_prio);
1640 }
1641 del_policies_inbound(this, this->my_addr, this->other_addr,
1642 my_ts, other_ts, &my_sa, &other_sa,
1643 POLICY_IPSEC, priority, manual_prio);
1644 if (!this->trap && manual_prio == 0 && require_policy_update() &&
1645 del_outbound)
1646 {
1647 del_policies_outbound(this, this->my_addr, this->other_addr,
1648 my_ts, other_ts, &my_sa, &other_sa,
1649 POLICY_DROP, POLICY_PRIORITY_FALLBACK, 0);
1650 }
1651 }
1652 enumerator->destroy(enumerator);
1653 }
1654
1655 /* delete SAs in the kernel, if they are set up */
1656 if (this->my_spi)
1657 {
1658 kernel_ipsec_sa_id_t id = {
1659 .src = this->other_addr,
1660 .dst = this->my_addr,
1661 .spi = this->my_spi,
1662 .proto = proto_ike2ip(this->protocol),
1663 };
1664 kernel_ipsec_del_sa_t sa = {
1665 .cpi = this->my_cpi,
1666 };
1667 charon->kernel->del_sa(charon->kernel, &id, &sa);
1668 }
1669 if (this->other_spi && (this->outbound_state & CHILD_OUTBOUND_SA))
1670 {
1671 kernel_ipsec_sa_id_t id = {
1672 .src = this->my_addr,
1673 .dst = this->other_addr,
1674 .spi = this->other_spi,
1675 .proto = proto_ike2ip(this->protocol),
1676 .mark = this->mark_out,
1677 };
1678 kernel_ipsec_del_sa_t sa = {
1679 .cpi = this->other_cpi,
1680 };
1681 charon->kernel->del_sa(charon->kernel, &id, &sa);
1682 }
1683
1684 if (this->reqid_allocated)
1685 {
1686 if (charon->kernel->release_reqid(charon->kernel,
1687 this->reqid, this->mark_in, this->mark_out) != SUCCESS)
1688 {
1689 DBG1(DBG_CHD, "releasing reqid %u failed", this->reqid);
1690 }
1691 }
1692
1693 array_destroy_offset(this->my_ts, offsetof(traffic_selector_t, destroy));
1694 array_destroy_offset(this->other_ts, offsetof(traffic_selector_t, destroy));
1695 this->my_addr->destroy(this->my_addr);
1696 this->other_addr->destroy(this->other_addr);
1697 DESTROY_IF(this->proposal);
1698 this->config->destroy(this->config);
1699 chunk_clear(&this->encr_r);
1700 chunk_clear(&this->integ_r);
1701 free(this);
1702 }
1703
1704 /**
1705 * Get proxy address for one side, if any
1706 */
1707 static host_t* get_proxy_addr(child_cfg_t *config, host_t *ike, bool local)
1708 {
1709 host_t *host = NULL;
1710 uint8_t mask;
1711 enumerator_t *enumerator;
1712 linked_list_t *ts_list, *list;
1713 traffic_selector_t *ts;
1714
1715 list = linked_list_create_with_items(ike, NULL);
1716 ts_list = config->get_traffic_selectors(config, local, NULL, list);
1717 list->destroy(list);
1718
1719 enumerator = ts_list->create_enumerator(ts_list);
1720 while (enumerator->enumerate(enumerator, &ts))
1721 {
1722 if (ts->is_host(ts, NULL) && ts->to_subnet(ts, &host, &mask))
1723 {
1724 DBG1(DBG_CHD, "%s address: %H is a transport mode proxy for %H",
1725 local ? "my" : "other", ike, host);
1726 break;
1727 }
1728 }
1729 enumerator->destroy(enumerator);
1730 ts_list->destroy_offset(ts_list, offsetof(traffic_selector_t, destroy));
1731
1732 if (!host)
1733 {
1734 host = ike->clone(ike);
1735 }
1736 return host;
1737 }
1738
1739 /**
1740 * Described in header.
1741 */
1742 child_sa_t * child_sa_create(host_t *me, host_t* other,
1743 child_cfg_t *config, uint32_t rekey, bool encap,
1744 u_int mark_in, u_int mark_out)
1745 {
1746 private_child_sa_t *this;
1747 static refcount_t unique_id = 0, unique_mark = 0;
1748 refcount_t mark;
1749
1750 INIT(this,
1751 .public = {
1752 .get_name = _get_name,
1753 .get_reqid = _get_reqid,
1754 .get_unique_id = _get_unique_id,
1755 .get_config = _get_config,
1756 .get_state = _get_state,
1757 .set_state = _set_state,
1758 .get_outbound_state = _get_outbound_state,
1759 .get_spi = _get_spi,
1760 .get_cpi = _get_cpi,
1761 .get_protocol = _get_protocol,
1762 .set_protocol = _set_protocol,
1763 .get_mode = _get_mode,
1764 .set_mode = _set_mode,
1765 .get_proposal = _get_proposal,
1766 .set_proposal = _set_proposal,
1767 .get_lifetime = _get_lifetime,
1768 .get_installtime = _get_installtime,
1769 .get_usestats = _get_usestats,
1770 .get_mark = _get_mark,
1771 .has_encap = _has_encap,
1772 .get_ipcomp = _get_ipcomp,
1773 .set_ipcomp = _set_ipcomp,
1774 .get_close_action = _get_close_action,
1775 .set_close_action = _set_close_action,
1776 .get_dpd_action = _get_dpd_action,
1777 .set_dpd_action = _set_dpd_action,
1778 .alloc_spi = _alloc_spi,
1779 .alloc_cpi = _alloc_cpi,
1780 .install = _install,
1781 .register_outbound = _register_outbound,
1782 .install_outbound = _install_outbound,
1783 .remove_outbound = _remove_outbound,
1784 .set_rekey_spi = _set_rekey_spi,
1785 .get_rekey_spi = _get_rekey_spi,
1786 .update = _update,
1787 .set_policies = _set_policies,
1788 .install_policies = _install_policies,
1789 .create_ts_enumerator = _create_ts_enumerator,
1790 .create_policy_enumerator = _create_policy_enumerator,
1791 .destroy = _destroy,
1792 },
1793 .encap = encap,
1794 .ipcomp = IPCOMP_NONE,
1795 .state = CHILD_CREATED,
1796 .my_ts = array_create(0, 0),
1797 .other_ts = array_create(0, 0),
1798 .protocol = PROTO_NONE,
1799 .mode = MODE_TUNNEL,
1800 .close_action = config->get_close_action(config),
1801 .dpd_action = config->get_dpd_action(config),
1802 .reqid = config->get_reqid(config),
1803 .unique_id = ref_get(&unique_id),
1804 .mark_in = config->get_mark(config, TRUE),
1805 .mark_out = config->get_mark(config, FALSE),
1806 .install_time = time_monotonic(NULL),
1807 .policies_fwd_out = config->has_option(config, OPT_FWD_OUT_POLICIES),
1808 );
1809
1810 this->config = config;
1811 config->get_ref(config);
1812
1813 if (mark_in)
1814 {
1815 this->mark_in.value = mark_in;
1816 }
1817 if (mark_out)
1818 {
1819 this->mark_out.value = mark_out;
1820 }
1821 if (this->mark_in.value == MARK_UNIQUE ||
1822 this->mark_out.value == MARK_UNIQUE)
1823 {
1824 mark = ref_get(&unique_mark);
1825 if (this->mark_in.value == MARK_UNIQUE)
1826 {
1827 this->mark_in.value = mark;
1828 }
1829 if (this->mark_out.value == MARK_UNIQUE)
1830 {
1831 this->mark_out.value = mark;
1832 }
1833 }
1834
1835 if (!this->reqid)
1836 {
1837 /* reuse old reqid if we are rekeying an existing CHILD_SA. While the
1838 * reqid cache would find the same reqid for our selectors, this does
1839 * not work in a special case: If an SA is triggered by a trap policy,
1840 * but the negotiated SA gets narrowed, we still must reuse the same
1841 * reqid to successfully "trigger" the SA on the kernel level. Rekeying
1842 * such an SA requires an explicit reqid, as the cache currently knows
1843 * the original selectors only for that reqid. */
1844 if (rekey)
1845 {
1846 this->reqid = rekey;
1847 }
1848 else
1849 {
1850 this->reqid = charon->traps->find_reqid(charon->traps, config);
1851 }
1852 }
1853 else
1854 {
1855 this->static_reqid = TRUE;
1856 }
1857
1858 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1859 if (config->get_mode(config) == MODE_TRANSPORT &&
1860 config->has_option(config, OPT_PROXY_MODE))
1861 {
1862 this->mode = MODE_TRANSPORT;
1863
1864 this->my_addr = get_proxy_addr(config, me, TRUE);
1865 this->other_addr = get_proxy_addr(config, other, FALSE);
1866 }
1867 else
1868 {
1869 this->my_addr = me->clone(me);
1870 this->other_addr = other->clone(other);
1871 }
1872 return &this->public;
1873 }