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