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