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