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