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