2 * Copyright (C) 2006-2017 Tobias Brunner
3 * Copyright (C) 2016 Andreas Steffen
4 * Copyright (C) 2005-2008 Martin Willi
5 * Copyright (C) 2006 Daniel Roethlisberger
6 * Copyright (C) 2005 Jan Hutter
7 * HSR Hochschule fuer Technik Rapperswil
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2 of the License, or (at your
12 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
28 #include <collections/array.h>
30 ENUM(child_sa_state_names
, CHILD_CREATED
, CHILD_DESTROYING
,
44 typedef struct private_child_sa_t private_child_sa_t
;
47 * Private data of a child_sa_t object.
49 struct private_child_sa_t
{
51 * Public interface of child_sa_t.
66 * our actually used SPI, 0 if unused
71 * others used SPI, 0 if unused
76 * our Compression Parameter Index (CPI) used, 0 if unused
81 * others Compression Parameter Index (CPI) used, 0 if unused
86 * Array for local traffic selectors
91 * Array for remote traffic selectors
96 * Outbound encryption key cached during a rekeying
101 * Outbound integrity key cached during a rekeying
106 * Whether the outbound SA has only been registered yet during a rekeying
108 bool outbound_registered
;
111 * Whether the peer supports TFCv3
116 * Protocol used to protect this SA, ESP|AH
118 protocol_id_t protocol
;
121 * reqid used for this child_sa
126 * Did we allocate/confirm and must release the reqid?
128 bool reqid_allocated
;
131 * Is the reqid statically configured
136 * Unique CHILD_SA identifier
141 * Whether FWD policieis in the outbound direction should be installed
143 bool policies_fwd_out
;
146 * inbound mark used for this child_sa
151 * outbound mark used for this child_sa
156 * absolute time when rekeying is scheduled
161 * absolute time when the SA expires
166 * absolute time when SA has been installed
171 * state of the CHILD_SA
173 child_sa_state_t state
;
176 * TRUE if this CHILD_SA is used to install trap policies
181 * Specifies if UDP encapsulation is enabled (NAT traversal)
186 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
188 ipcomp_transform_t ipcomp
;
191 * mode this SA uses, tunnel/transport
196 * Action to enforce if peer closes the CHILD_SA
198 action_t close_action
;
201 * Action to enforce if peer is considered dead
208 proposal_t
*proposal
;
211 * config used to create this child
216 * time of last use in seconds (inbound)
221 * time of last use in seconds (outbound)
223 time_t other_usetime
;
226 * last number of inbound bytes
228 uint64_t my_usebytes
;
231 * last number of outbound bytes
233 uint64_t other_usebytes
;
236 * last number of inbound packets
238 uint64_t my_usepackets
;
241 * last number of outbound bytes
243 uint64_t other_usepackets
;
247 * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
249 static inline uint8_t proto_ike2ip(protocol_id_t protocol
)
262 METHOD(child_sa_t
, get_name
, char*,
263 private_child_sa_t
*this)
265 return this->config
->get_name(this->config
);
268 METHOD(child_sa_t
, get_reqid
, uint32_t,
269 private_child_sa_t
*this)
274 METHOD(child_sa_t
, get_unique_id
, uint32_t,
275 private_child_sa_t
*this)
277 return this->unique_id
;
280 METHOD(child_sa_t
, get_config
, child_cfg_t
*,
281 private_child_sa_t
*this)
286 METHOD(child_sa_t
, set_state
, void,
287 private_child_sa_t
*this, child_sa_state_t state
)
289 charon
->bus
->child_state_change(charon
->bus
, &this->public, state
);
293 METHOD(child_sa_t
, get_state
, child_sa_state_t
,
294 private_child_sa_t
*this)
299 METHOD(child_sa_t
, get_spi
, uint32_t,
300 private_child_sa_t
*this, bool inbound
)
302 return inbound ?
this->my_spi
: this->other_spi
;
305 METHOD(child_sa_t
, get_cpi
, uint16_t,
306 private_child_sa_t
*this, bool inbound
)
308 return inbound ?
this->my_cpi
: this->other_cpi
;
311 METHOD(child_sa_t
, get_protocol
, protocol_id_t
,
312 private_child_sa_t
*this)
314 return this->protocol
;
317 METHOD(child_sa_t
, set_protocol
, void,
318 private_child_sa_t
*this, protocol_id_t protocol
)
320 this->protocol
= protocol
;
323 METHOD(child_sa_t
, get_mode
, ipsec_mode_t
,
324 private_child_sa_t
*this)
329 METHOD(child_sa_t
, set_mode
, void,
330 private_child_sa_t
*this, ipsec_mode_t mode
)
335 METHOD(child_sa_t
, has_encap
, bool,
336 private_child_sa_t
*this)
341 METHOD(child_sa_t
, get_ipcomp
, ipcomp_transform_t
,
342 private_child_sa_t
*this)
347 METHOD(child_sa_t
, set_ipcomp
, void,
348 private_child_sa_t
*this, ipcomp_transform_t ipcomp
)
350 this->ipcomp
= ipcomp
;
353 METHOD(child_sa_t
, set_close_action
, void,
354 private_child_sa_t
*this, action_t action
)
356 this->close_action
= action
;
359 METHOD(child_sa_t
, get_close_action
, action_t
,
360 private_child_sa_t
*this)
362 return this->close_action
;
365 METHOD(child_sa_t
, set_dpd_action
, void,
366 private_child_sa_t
*this, action_t action
)
368 this->dpd_action
= action
;
371 METHOD(child_sa_t
, get_dpd_action
, action_t
,
372 private_child_sa_t
*this)
374 return this->dpd_action
;
377 METHOD(child_sa_t
, get_proposal
, proposal_t
*,
378 private_child_sa_t
*this)
380 return this->proposal
;
383 METHOD(child_sa_t
, set_proposal
, void,
384 private_child_sa_t
*this, proposal_t
*proposal
)
386 this->proposal
= proposal
->clone(proposal
);
389 METHOD(child_sa_t
, create_ts_enumerator
, enumerator_t
*,
390 private_child_sa_t
*this, bool local
)
394 return array_create_enumerator(this->my_ts
);
396 return array_create_enumerator(this->other_ts
);
399 typedef struct policy_enumerator_t policy_enumerator_t
;
402 * Private policy enumerator
404 struct policy_enumerator_t
{
405 /** implements enumerator_t */
407 /** enumerator over own TS */
409 /** enumerator over others TS */
411 /** array of others TS, to recreate enumerator */
413 /** currently enumerating TS for "me" side */
414 traffic_selector_t
*ts
;
417 METHOD(enumerator_t
, policy_enumerate
, bool,
418 policy_enumerator_t
*this, traffic_selector_t
**my_out
,
419 traffic_selector_t
**other_out
)
421 traffic_selector_t
*other_ts
;
423 while (this->ts
|| this->mine
->enumerate(this->mine
, &this->ts
))
425 if (!this->other
->enumerate(this->other
, &other_ts
))
426 { /* end of others list, restart with new of mine */
427 this->other
->destroy(this->other
);
428 this->other
= array_create_enumerator(this->array
);
432 if (this->ts
->get_type(this->ts
) != other_ts
->get_type(other_ts
))
433 { /* family mismatch */
436 if (this->ts
->get_protocol(this->ts
) &&
437 other_ts
->get_protocol(other_ts
) &&
438 this->ts
->get_protocol(this->ts
) != other_ts
->get_protocol(other_ts
))
439 { /* protocol mismatch */
448 *other_out
= other_ts
;
455 METHOD(enumerator_t
, policy_destroy
, void,
456 policy_enumerator_t
*this)
458 this->mine
->destroy(this->mine
);
459 this->other
->destroy(this->other
);
463 METHOD(child_sa_t
, create_policy_enumerator
, enumerator_t
*,
464 private_child_sa_t
*this)
466 policy_enumerator_t
*e
;
470 .enumerate
= (void*)_policy_enumerate
,
471 .destroy
= _policy_destroy
,
473 .mine
= array_create_enumerator(this->my_ts
),
474 .other
= array_create_enumerator(this->other_ts
),
475 .array
= this->other_ts
,
483 * update the cached usebytes
484 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
485 * are available, and NOT_SUPPORTED if the kernel interface does not support
486 * querying the usebytes.
488 static status_t
update_usebytes(private_child_sa_t
*this, bool inbound
)
490 status_t status
= FAILED
;
491 uint64_t bytes
, packets
;
498 kernel_ipsec_sa_id_t id
= {
499 .src
= this->other_addr
,
500 .dst
= this->my_addr
,
502 .proto
= proto_ike2ip(this->protocol
),
504 kernel_ipsec_query_sa_t query
= {};
506 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
507 &bytes
, &packets
, &time
);
508 if (status
== SUCCESS
)
510 if (bytes
> this->my_usebytes
)
512 this->my_usebytes
= bytes
;
513 this->my_usepackets
= packets
;
516 this->my_usetime
= time
;
530 kernel_ipsec_sa_id_t id
= {
531 .src
= this->my_addr
,
532 .dst
= this->other_addr
,
533 .spi
= this->other_spi
,
534 .proto
= proto_ike2ip(this->protocol
),
535 .mark
= this->mark_out
,
537 kernel_ipsec_query_sa_t query
= {};
539 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
540 &bytes
, &packets
, &time
);
541 if (status
== SUCCESS
)
543 if (bytes
> this->other_usebytes
)
545 this->other_usebytes
= bytes
;
546 this->other_usepackets
= packets
;
549 this->other_usetime
= time
;
563 * updates the cached usetime
565 static bool update_usetime(private_child_sa_t
*this, bool inbound
)
567 enumerator_t
*enumerator
;
568 traffic_selector_t
*my_ts
, *other_ts
;
571 enumerator
= create_policy_enumerator(this);
572 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
578 kernel_ipsec_policy_id_t id
= {
582 .mark
= this->mark_in
,
584 kernel_ipsec_query_policy_t query
= {};
586 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
589 last_use
= max(last_use
, in
);
591 if (this->mode
!= MODE_TRANSPORT
)
594 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
597 last_use
= max(last_use
, fwd
);
603 kernel_ipsec_policy_id_t id
= {
607 .mark
= this->mark_out
,
608 .interface
= this->config
->get_interface(this->config
),
610 kernel_ipsec_query_policy_t query
= {};
612 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
615 last_use
= max(last_use
, out
);
619 enumerator
->destroy(enumerator
);
627 this->my_usetime
= last_use
;
631 this->other_usetime
= last_use
;
636 METHOD(child_sa_t
, get_usestats
, void,
637 private_child_sa_t
*this, bool inbound
,
638 time_t *time
, uint64_t *bytes
, uint64_t *packets
)
640 if ((!bytes
&& !packets
) || update_usebytes(this, inbound
) != FAILED
)
642 /* there was traffic since last update or the kernel interface
643 * does not support querying the number of usebytes.
647 if (!update_usetime(this, inbound
) && !bytes
&& !packets
)
649 /* if policy query did not yield a usetime, query SAs instead */
650 update_usebytes(this, inbound
);
656 *time
= inbound ?
this->my_usetime
: this->other_usetime
;
660 *bytes
= inbound ?
this->my_usebytes
: this->other_usebytes
;
664 *packets
= inbound ?
this->my_usepackets
: this->other_usepackets
;
668 METHOD(child_sa_t
, get_mark
, mark_t
,
669 private_child_sa_t
*this, bool inbound
)
673 return this->mark_in
;
675 return this->mark_out
;
678 METHOD(child_sa_t
, get_lifetime
, time_t,
679 private_child_sa_t
*this, bool hard
)
681 return hard ?
this->expire_time
: this->rekey_time
;
684 METHOD(child_sa_t
, get_installtime
, time_t,
685 private_child_sa_t
*this)
687 return this->install_time
;
690 METHOD(child_sa_t
, alloc_spi
, uint32_t,
691 private_child_sa_t
*this, protocol_id_t protocol
)
693 if (charon
->kernel
->get_spi(charon
->kernel
, this->other_addr
, this->my_addr
,
694 proto_ike2ip(protocol
), &this->my_spi
) == SUCCESS
)
696 /* if we allocate a SPI, but then are unable to establish the SA, we
697 * need to know the protocol family to delete the partial SA */
698 this->protocol
= protocol
;
704 METHOD(child_sa_t
, alloc_cpi
, uint16_t,
705 private_child_sa_t
*this)
707 if (charon
->kernel
->get_cpi(charon
->kernel
, this->other_addr
, this->my_addr
,
708 &this->my_cpi
) == SUCCESS
)
716 * Install the given SA in the kernel
718 static status_t
install_internal(private_child_sa_t
*this, chunk_t encr
,
719 chunk_t integ
, uint32_t spi
, uint16_t cpi
, bool initiator
, bool inbound
,
722 uint16_t enc_alg
= ENCR_UNDEFINED
, int_alg
= AUTH_UNDEFINED
, size
;
723 uint16_t esn
= NO_EXT_SEQ_NUMBERS
;
724 linked_list_t
*my_ts
, *other_ts
, *src_ts
, *dst_ts
;
726 kernel_ipsec_sa_id_t id
;
727 kernel_ipsec_add_sa_t sa
;
728 lifetime_cfg_t
*lifetime
;
734 /* BEET requires the bound address from the traffic selectors */
735 my_ts
= linked_list_create_from_enumerator(
736 array_create_enumerator(this->my_ts
));
737 other_ts
= linked_list_create_from_enumerator(
738 array_create_enumerator(this->other_ts
));
740 /* now we have to decide which spi to use. Use self allocated, if "in",
741 * or the one in the proposal, if not "in" (others). Additionally,
742 * source and dest host switch depending on the role */
746 src
= this->other_addr
;
747 if (this->my_spi
== spi
)
748 { /* alloc_spi has been called, do an SA update */
759 dst
= this->other_addr
;
760 this->other_spi
= spi
;
761 this->other_cpi
= cpi
;
767 tfc
= this->config
->get_tfc(this->config
);
771 DBG2(DBG_CHD
, "adding %s %N SA", inbound ?
"inbound" : "outbound",
772 protocol_id_names
, this->protocol
);
774 /* send SA down to the kernel */
775 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), src
, dst
);
777 this->proposal
->get_algorithm(this->proposal
, ENCRYPTION_ALGORITHM
,
779 this->proposal
->get_algorithm(this->proposal
, INTEGRITY_ALGORITHM
,
781 this->proposal
->get_algorithm(this->proposal
, EXTENDED_SEQUENCE_NUMBERS
,
784 if (!this->reqid_allocated
&& !this->static_reqid
)
786 status
= charon
->kernel
->alloc_reqid(charon
->kernel
, my_ts
, other_ts
,
787 this->mark_in
, this->mark_out
, &this->reqid
);
788 if (status
!= SUCCESS
)
790 my_ts
->destroy(my_ts
);
791 other_ts
->destroy(other_ts
);
794 this->reqid_allocated
= TRUE
;
797 lifetime
= this->config
->get_lifetime(this->config
, TRUE
);
799 now
= time_monotonic(NULL
);
800 if (lifetime
->time
.rekey
)
802 if (this->rekey_time
)
804 this->rekey_time
= min(this->rekey_time
, now
+ lifetime
->time
.rekey
);
808 this->rekey_time
= now
+ lifetime
->time
.rekey
;
811 if (lifetime
->time
.life
)
813 this->expire_time
= now
+ lifetime
->time
.life
;
816 if (!lifetime
->time
.jitter
&& !inbound
)
817 { /* avoid triggering multiple rekey events */
818 lifetime
->time
.rekey
= 0;
821 id
= (kernel_ipsec_sa_id_t
){
825 .proto
= proto_ike2ip(this->protocol
),
826 .mark
= inbound ?
(mark_t
){} : this->mark_out
,
828 sa
= (kernel_ipsec_add_sa_t
){
829 .reqid
= this->reqid
,
833 .interface
= inbound ? NULL
: this->config
->get_interface(this->config
),
834 .lifetime
= lifetime
,
839 .replay_window
= this->config
->get_replay_window(this->config
),
841 .ipcomp
= this->ipcomp
,
843 .encap
= this->encap
,
844 .hw_offload
= this->config
->has_option(this->config
, OPT_HW_OFFLOAD
),
846 .initiator
= initiator
,
851 status
= charon
->kernel
->add_sa(charon
->kernel
, &id
, &sa
);
853 my_ts
->destroy(my_ts
);
854 other_ts
->destroy(other_ts
);
860 METHOD(child_sa_t
, install
, status_t
,
861 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
862 uint16_t cpi
, bool initiator
, bool inbound
, bool tfcv3
)
864 return install_internal(this, encr
, integ
, spi
, cpi
, initiator
, inbound
,
869 * Check kernel interface if policy updates are required
871 static bool require_policy_update()
875 f
= charon
->kernel
->get_features(charon
->kernel
);
876 return !(f
& KERNEL_NO_POLICY_UPDATES
);
880 * Prepare SA config to install/delete policies
882 static void prepare_sa_cfg(private_child_sa_t
*this, ipsec_sa_cfg_t
*my_sa
,
883 ipsec_sa_cfg_t
*other_sa
)
885 enumerator_t
*enumerator
;
887 *my_sa
= (ipsec_sa_cfg_t
){
889 .reqid
= this->reqid
,
891 .transform
= this->ipcomp
,
896 my_sa
->ipcomp
.cpi
= this->my_cpi
;
897 other_sa
->ipcomp
.cpi
= this->other_cpi
;
899 if (this->protocol
== PROTO_ESP
)
901 my_sa
->esp
.use
= TRUE
;
902 my_sa
->esp
.spi
= this->my_spi
;
903 other_sa
->esp
.use
= TRUE
;
904 other_sa
->esp
.spi
= this->other_spi
;
908 my_sa
->ah
.use
= TRUE
;
909 my_sa
->ah
.spi
= this->my_spi
;
910 other_sa
->ah
.use
= TRUE
;
911 other_sa
->ah
.spi
= this->other_spi
;
914 enumerator
= create_policy_enumerator(this);
915 while (enumerator
->enumerate(enumerator
, NULL
, NULL
))
917 my_sa
->policy_count
++;
918 other_sa
->policy_count
++;
920 enumerator
->destroy(enumerator
);
924 * Install inbound policie(s): in, fwd
926 static status_t
install_policies_inbound(private_child_sa_t
*this,
927 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
928 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
929 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
930 policy_priority_t priority
, uint32_t manual_prio
)
932 kernel_ipsec_policy_id_t in_id
= {
936 .mark
= this->mark_in
,
938 kernel_ipsec_manage_policy_t in_policy
= {
941 .manual_prio
= manual_prio
,
946 status_t status
= SUCCESS
;
948 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
949 if (this->mode
!= MODE_TRANSPORT
)
951 in_id
.dir
= POLICY_FWD
;
952 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
958 * Install outbound policie(s): out, [fwd]
960 static status_t
install_policies_outbound(private_child_sa_t
*this,
961 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
962 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
963 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
964 policy_priority_t priority
, uint32_t manual_prio
)
966 kernel_ipsec_policy_id_t out_id
= {
970 .mark
= this->mark_out
,
971 .interface
= this->config
->get_interface(this->config
),
973 kernel_ipsec_manage_policy_t out_policy
= {
976 .manual_prio
= manual_prio
,
981 status_t status
= SUCCESS
;
983 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
, &out_policy
);
985 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
987 /* install an "outbound" FWD policy in case there is a drop policy
988 * matching outbound forwarded traffic, to allow another tunnel to use
989 * the reversed subnets and do the same we don't set a reqid (this also
990 * allows the kernel backend to distinguish between the two types of
991 * FWD policies). To avoid problems with symmetrically overlapping
992 * policies of two SAs we install them with reduced priority. As they
993 * basically act as bypass policies for drop policies we use a higher
994 * priority than is used for them. */
995 out_id
.dir
= POLICY_FWD
;
997 if (priority
== POLICY_PRIORITY_DEFAULT
)
999 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1001 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
,
1003 /* reset the reqid for any other further policies */
1004 other_sa
->reqid
= this->reqid
;
1010 * Install all policies
1012 static status_t
install_policies_internal(private_child_sa_t
*this,
1013 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1014 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1015 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1016 policy_priority_t priority
, uint32_t manual_prio
)
1018 status_t status
= SUCCESS
;
1020 status
|= install_policies_inbound(this, my_addr
, other_addr
, my_ts
,
1021 other_ts
, my_sa
, other_sa
, type
,
1022 priority
, manual_prio
);
1023 status
|= install_policies_outbound(this, my_addr
, other_addr
, my_ts
,
1024 other_ts
, my_sa
, other_sa
, type
,
1025 priority
, manual_prio
);
1030 * Delete inbound policies: in, fwd
1032 static void del_policies_inbound(private_child_sa_t
*this,
1033 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1034 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1035 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1036 policy_priority_t priority
, uint32_t manual_prio
)
1038 kernel_ipsec_policy_id_t in_id
= {
1042 .mark
= this->mark_in
,
1044 kernel_ipsec_manage_policy_t in_policy
= {
1047 .manual_prio
= manual_prio
,
1053 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1055 if (this->mode
!= MODE_TRANSPORT
)
1057 in_id
.dir
= POLICY_FWD
;
1058 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1063 * Delete outbound policies: out, [fwd]
1065 static void del_policies_outbound(private_child_sa_t
*this,
1066 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1067 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1068 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1069 policy_priority_t priority
, uint32_t manual_prio
)
1071 kernel_ipsec_policy_id_t out_id
= {
1075 .mark
= this->mark_out
,
1076 .interface
= this->config
->get_interface(this->config
),
1078 kernel_ipsec_manage_policy_t out_policy
= {
1081 .manual_prio
= manual_prio
,
1087 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1089 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1091 out_id
.dir
= POLICY_FWD
;
1092 other_sa
->reqid
= 0;
1093 if (priority
== POLICY_PRIORITY_DEFAULT
)
1095 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1097 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1098 other_sa
->reqid
= this->reqid
;
1103 * Delete in- and outbound policies
1105 static void del_policies_internal(private_child_sa_t
*this,
1106 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1107 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1108 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1109 policy_priority_t priority
, uint32_t manual_prio
)
1111 del_policies_outbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1112 other_sa
, type
, priority
, manual_prio
);
1113 del_policies_inbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1114 other_sa
, type
, priority
, manual_prio
);
1117 METHOD(child_sa_t
, set_policies
, void,
1118 private_child_sa_t
*this, linked_list_t
*my_ts_list
,
1119 linked_list_t
*other_ts_list
)
1121 enumerator_t
*enumerator
;
1122 traffic_selector_t
*my_ts
, *other_ts
;
1124 if (array_count(this->my_ts
))
1126 array_destroy_offset(this->my_ts
,
1127 offsetof(traffic_selector_t
, destroy
));
1128 this->my_ts
= array_create(0, 0);
1130 enumerator
= my_ts_list
->create_enumerator(my_ts_list
);
1131 while (enumerator
->enumerate(enumerator
, &my_ts
))
1133 array_insert(this->my_ts
, ARRAY_TAIL
, my_ts
->clone(my_ts
));
1135 enumerator
->destroy(enumerator
);
1136 array_sort(this->my_ts
, (void*)traffic_selector_cmp
, NULL
);
1138 if (array_count(this->other_ts
))
1140 array_destroy_offset(this->other_ts
,
1141 offsetof(traffic_selector_t
, destroy
));
1142 this->other_ts
= array_create(0, 0);
1144 enumerator
= other_ts_list
->create_enumerator(other_ts_list
);
1145 while (enumerator
->enumerate(enumerator
, &other_ts
))
1147 array_insert(this->other_ts
, ARRAY_TAIL
, other_ts
->clone(other_ts
));
1149 enumerator
->destroy(enumerator
);
1150 array_sort(this->other_ts
, (void*)traffic_selector_cmp
, NULL
);
1153 METHOD(child_sa_t
, install_policies
, status_t
,
1154 private_child_sa_t
*this)
1156 enumerator_t
*enumerator
;
1157 linked_list_t
*my_ts_list
, *other_ts_list
;
1158 traffic_selector_t
*my_ts
, *other_ts
;
1159 status_t status
= SUCCESS
;
1161 if (!this->reqid_allocated
&& !this->static_reqid
)
1163 my_ts_list
= linked_list_create_from_enumerator(
1164 array_create_enumerator(this->my_ts
));
1165 other_ts_list
= linked_list_create_from_enumerator(
1166 array_create_enumerator(this->other_ts
));
1167 status
= charon
->kernel
->alloc_reqid(
1168 charon
->kernel
, my_ts_list
, other_ts_list
,
1169 this->mark_in
, this->mark_out
, &this->reqid
);
1170 my_ts_list
->destroy(my_ts_list
);
1171 other_ts_list
->destroy(other_ts_list
);
1172 if (status
!= SUCCESS
)
1176 this->reqid_allocated
= TRUE
;
1179 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1181 policy_priority_t priority
;
1182 ipsec_sa_cfg_t my_sa
, other_sa
;
1183 uint32_t manual_prio
;
1185 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1186 manual_prio
= this->config
->get_manual_prio(this->config
);
1188 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1189 * entry) we install a trap policy */
1190 this->trap
= this->state
== CHILD_CREATED
;
1191 priority
= this->trap ? POLICY_PRIORITY_ROUTED
1192 : POLICY_PRIORITY_DEFAULT
;
1194 /* enumerate pairs of traffic selectors */
1195 enumerator
= create_policy_enumerator(this);
1196 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1198 /* install outbound drop policy to avoid packets leaving unencrypted
1199 * when updating policies */
1200 if (priority
== POLICY_PRIORITY_DEFAULT
&& manual_prio
== 0 &&
1201 require_policy_update() && !this->outbound_registered
)
1203 status
|= install_policies_outbound(this, this->my_addr
,
1204 this->other_addr
, my_ts
, other_ts
,
1205 &my_sa
, &other_sa
, POLICY_DROP
,
1206 POLICY_PRIORITY_FALLBACK
, 0);
1209 status
|= install_policies_inbound(this, this->my_addr
,
1210 this->other_addr
, my_ts
, other_ts
,
1211 &my_sa
, &other_sa
, POLICY_IPSEC
,
1212 priority
, manual_prio
);
1214 if (!this->outbound_registered
)
1216 status
|= install_policies_outbound(this, this->my_addr
,
1217 this->other_addr
, my_ts
, other_ts
,
1218 &my_sa
, &other_sa
, POLICY_IPSEC
,
1219 priority
, manual_prio
);
1222 if (status
!= SUCCESS
)
1227 enumerator
->destroy(enumerator
);
1230 if (status
== SUCCESS
&& this->trap
)
1232 set_state(this, CHILD_ROUTED
);
1237 METHOD(child_sa_t
, register_outbound
, void,
1238 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
1239 uint16_t cpi
, bool tfcv3
)
1241 DBG2(DBG_CHD
, "registering outbound %N SA", protocol_id_names
,
1243 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), this->my_addr
,
1246 this->other_spi
= spi
;
1247 this->other_cpi
= cpi
;
1248 this->encr_r
= chunk_clone(encr
);
1249 this->integ_r
= chunk_clone(integ
);
1250 this->tfcv3
= tfcv3
;
1251 this->outbound_registered
= TRUE
;
1254 METHOD(child_sa_t
, install_outbound
, status_t
,
1255 private_child_sa_t
*this)
1257 enumerator_t
*enumerator
;
1258 traffic_selector_t
*my_ts
, *other_ts
;
1261 this->outbound_registered
= FALSE
;
1263 status
= install_internal(this, this->encr_r
, this->integ_r
,
1264 this->other_spi
, this->other_cpi
, FALSE
, FALSE
,
1266 chunk_clear(&this->encr_r
);
1267 chunk_clear(&this->integ_r
);
1268 if (status
!= SUCCESS
)
1272 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1274 ipsec_sa_cfg_t my_sa
, other_sa
;
1275 uint32_t manual_prio
;
1277 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1278 manual_prio
= this->config
->get_manual_prio(this->config
);
1280 enumerator
= create_policy_enumerator(this);
1281 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1283 /* install outbound drop policy to avoid packets leaving unencrypted
1284 * when updating policies */
1285 if (manual_prio
== 0 && require_policy_update())
1287 status
|= install_policies_outbound(this, this->my_addr
,
1288 this->other_addr
, my_ts
, other_ts
,
1289 &my_sa
, &other_sa
, POLICY_DROP
,
1290 POLICY_PRIORITY_FALLBACK
, 0);
1292 status
|= install_policies_outbound(this, this->my_addr
,
1293 this->other_addr
, my_ts
, other_ts
,
1294 &my_sa
, &other_sa
, POLICY_IPSEC
,
1295 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1296 if (status
!= SUCCESS
)
1301 enumerator
->destroy(enumerator
);
1307 * Callback to reinstall a virtual IP
1309 static void reinstall_vip(host_t
*vip
, host_t
*me
)
1313 if (charon
->kernel
->get_interface(charon
->kernel
, me
, &iface
))
1315 charon
->kernel
->del_ip(charon
->kernel
, vip
, -1, TRUE
);
1316 charon
->kernel
->add_ip(charon
->kernel
, vip
, -1, iface
);
1321 METHOD(child_sa_t
, update
, status_t
,
1322 private_child_sa_t
*this, host_t
*me
, host_t
*other
, linked_list_t
*vips
,
1325 child_sa_state_t old
;
1326 bool transport_proxy_mode
;
1328 /* anything changed at all? */
1329 if (me
->equals(me
, this->my_addr
) &&
1330 other
->equals(other
, this->other_addr
) && this->encap
== encap
)
1336 set_state(this, CHILD_UPDATING
);
1337 transport_proxy_mode
= this->mode
== MODE_TRANSPORT
&&
1338 this->config
->has_option(this->config
,
1341 if (!transport_proxy_mode
)
1343 /* update our (initiator) SA */
1346 kernel_ipsec_sa_id_t id
= {
1347 .src
= this->other_addr
,
1348 .dst
= this->my_addr
,
1349 .spi
= this->my_spi
,
1350 .proto
= proto_ike2ip(this->protocol
),
1352 kernel_ipsec_update_sa_t sa
= {
1353 .cpi
= this->ipcomp
!= IPCOMP_NONE ?
this->my_cpi
: 0,
1356 .encap
= this->encap
,
1359 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1360 &sa
) == NOT_SUPPORTED
)
1362 set_state(this, old
);
1363 return NOT_SUPPORTED
;
1367 /* update his (responder) SA */
1368 if (this->other_spi
)
1370 kernel_ipsec_sa_id_t id
= {
1371 .src
= this->my_addr
,
1372 .dst
= this->other_addr
,
1373 .spi
= this->other_spi
,
1374 .proto
= proto_ike2ip(this->protocol
),
1375 .mark
= this->mark_out
,
1377 kernel_ipsec_update_sa_t sa
= {
1378 .cpi
= this->ipcomp
!= IPCOMP_NONE ?
this->other_cpi
: 0,
1381 .encap
= this->encap
,
1384 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1385 &sa
) == NOT_SUPPORTED
)
1387 set_state(this, old
);
1388 return NOT_SUPPORTED
;
1393 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1394 require_policy_update())
1396 if (!me
->ip_equals(me
, this->my_addr
) ||
1397 !other
->ip_equals(other
, this->other_addr
))
1399 ipsec_sa_cfg_t my_sa
, other_sa
;
1400 enumerator_t
*enumerator
;
1401 traffic_selector_t
*my_ts
, *other_ts
;
1402 uint32_t manual_prio
;
1404 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1405 manual_prio
= this->config
->get_manual_prio(this->config
);
1407 /* always use high priorities, as hosts getting updated are INSTALLED */
1408 enumerator
= create_policy_enumerator(this);
1409 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1411 traffic_selector_t
*old_my_ts
= NULL
, *old_other_ts
= NULL
;
1413 /* remove old policies first */
1414 del_policies_internal(this, this->my_addr
, this->other_addr
,
1415 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
,
1416 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1418 /* check if we have to update a "dynamic" traffic selector */
1419 if (!me
->ip_equals(me
, this->my_addr
) &&
1420 my_ts
->is_host(my_ts
, this->my_addr
))
1422 old_my_ts
= my_ts
->clone(my_ts
);
1423 my_ts
->set_address(my_ts
, me
);
1425 if (!other
->ip_equals(other
, this->other_addr
) &&
1426 other_ts
->is_host(other_ts
, this->other_addr
))
1428 old_other_ts
= other_ts
->clone(other_ts
);
1429 other_ts
->set_address(other_ts
, other
);
1432 /* we reinstall the virtual IP to handle interface roaming
1434 vips
->invoke_function(vips
, (void*)reinstall_vip
, me
);
1436 /* reinstall updated policies */
1437 install_policies_internal(this, me
, other
, my_ts
, other_ts
,
1438 &my_sa
, &other_sa
, POLICY_IPSEC
,
1439 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1441 /* update fallback policies after the new policy is in place */
1442 if (manual_prio
== 0)
1444 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1446 old_other_ts ?
: other_ts
,
1447 &my_sa
, &other_sa
, POLICY_DROP
,
1448 POLICY_PRIORITY_FALLBACK
, 0);
1449 install_policies_outbound(this, me
, other
, my_ts
, other_ts
,
1450 &my_sa
, &other_sa
, POLICY_DROP
,
1451 POLICY_PRIORITY_FALLBACK
, 0);
1453 DESTROY_IF(old_my_ts
);
1454 DESTROY_IF(old_other_ts
);
1456 enumerator
->destroy(enumerator
);
1460 if (!transport_proxy_mode
)
1463 if (!me
->equals(me
, this->my_addr
))
1465 this->my_addr
->destroy(this->my_addr
);
1466 this->my_addr
= me
->clone(me
);
1468 if (!other
->equals(other
, this->other_addr
))
1470 this->other_addr
->destroy(this->other_addr
);
1471 this->other_addr
= other
->clone(other
);
1475 this->encap
= encap
;
1476 set_state(this, old
);
1481 METHOD(child_sa_t
, destroy
, void,
1482 private_child_sa_t
*this)
1484 enumerator_t
*enumerator
;
1485 traffic_selector_t
*my_ts
, *other_ts
;
1486 policy_priority_t priority
;
1488 priority
= this->trap ? POLICY_PRIORITY_ROUTED
: POLICY_PRIORITY_DEFAULT
;
1490 set_state(this, CHILD_DESTROYING
);
1492 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1494 ipsec_sa_cfg_t my_sa
, other_sa
;
1495 uint32_t manual_prio
;
1497 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1498 manual_prio
= this->config
->get_manual_prio(this->config
);
1500 /* delete all policies in the kernel */
1501 enumerator
= create_policy_enumerator(this);
1502 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1504 del_policies_internal(this, this->my_addr
, this->other_addr
,
1505 my_ts
, other_ts
, &my_sa
, &other_sa
,
1506 POLICY_IPSEC
, priority
, manual_prio
);
1507 if (priority
== POLICY_PRIORITY_DEFAULT
&& manual_prio
== 0 &&
1508 require_policy_update())
1510 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1511 my_ts
, other_ts
, &my_sa
, &other_sa
,
1512 POLICY_DROP
, POLICY_PRIORITY_FALLBACK
, 0);
1515 enumerator
->destroy(enumerator
);
1518 /* delete SAs in the kernel, if they are set up */
1521 kernel_ipsec_sa_id_t id
= {
1522 .src
= this->other_addr
,
1523 .dst
= this->my_addr
,
1524 .spi
= this->my_spi
,
1525 .proto
= proto_ike2ip(this->protocol
),
1527 kernel_ipsec_del_sa_t sa
= {
1528 .cpi
= this->my_cpi
,
1530 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1532 if (this->other_spi
)
1534 kernel_ipsec_sa_id_t id
= {
1535 .src
= this->my_addr
,
1536 .dst
= this->other_addr
,
1537 .spi
= this->other_spi
,
1538 .proto
= proto_ike2ip(this->protocol
),
1539 .mark
= this->mark_out
,
1541 kernel_ipsec_del_sa_t sa
= {
1542 .cpi
= this->other_cpi
,
1544 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1547 if (this->reqid_allocated
)
1549 if (charon
->kernel
->release_reqid(charon
->kernel
,
1550 this->reqid
, this->mark_in
, this->mark_out
) != SUCCESS
)
1552 DBG1(DBG_CHD
, "releasing reqid %u failed", this->reqid
);
1556 array_destroy_offset(this->my_ts
, offsetof(traffic_selector_t
, destroy
));
1557 array_destroy_offset(this->other_ts
, offsetof(traffic_selector_t
, destroy
));
1558 this->my_addr
->destroy(this->my_addr
);
1559 this->other_addr
->destroy(this->other_addr
);
1560 DESTROY_IF(this->proposal
);
1561 this->config
->destroy(this->config
);
1562 chunk_clear(&this->encr_r
);
1563 chunk_clear(&this->integ_r
);
1568 * Get proxy address for one side, if any
1570 static host_t
* get_proxy_addr(child_cfg_t
*config
, host_t
*ike
, bool local
)
1572 host_t
*host
= NULL
;
1574 enumerator_t
*enumerator
;
1575 linked_list_t
*ts_list
, *list
;
1576 traffic_selector_t
*ts
;
1578 list
= linked_list_create_with_items(ike
, NULL
);
1579 ts_list
= config
->get_traffic_selectors(config
, local
, NULL
, list
);
1580 list
->destroy(list
);
1582 enumerator
= ts_list
->create_enumerator(ts_list
);
1583 while (enumerator
->enumerate(enumerator
, &ts
))
1585 if (ts
->is_host(ts
, NULL
) && ts
->to_subnet(ts
, &host
, &mask
))
1587 DBG1(DBG_CHD
, "%s address: %H is a transport mode proxy for %H",
1588 local ?
"my" : "other", ike
, host
);
1592 enumerator
->destroy(enumerator
);
1593 ts_list
->destroy_offset(ts_list
, offsetof(traffic_selector_t
, destroy
));
1597 host
= ike
->clone(ike
);
1603 * Described in header.
1605 child_sa_t
* child_sa_create(host_t
*me
, host_t
* other
,
1606 child_cfg_t
*config
, uint32_t rekey
, bool encap
,
1607 u_int mark_in
, u_int mark_out
)
1609 private_child_sa_t
*this;
1610 static refcount_t unique_id
= 0, unique_mark
= 0;
1615 .get_name
= _get_name
,
1616 .get_reqid
= _get_reqid
,
1617 .get_unique_id
= _get_unique_id
,
1618 .get_config
= _get_config
,
1619 .get_state
= _get_state
,
1620 .set_state
= _set_state
,
1621 .get_spi
= _get_spi
,
1622 .get_cpi
= _get_cpi
,
1623 .get_protocol
= _get_protocol
,
1624 .set_protocol
= _set_protocol
,
1625 .get_mode
= _get_mode
,
1626 .set_mode
= _set_mode
,
1627 .get_proposal
= _get_proposal
,
1628 .set_proposal
= _set_proposal
,
1629 .get_lifetime
= _get_lifetime
,
1630 .get_installtime
= _get_installtime
,
1631 .get_usestats
= _get_usestats
,
1632 .get_mark
= _get_mark
,
1633 .has_encap
= _has_encap
,
1634 .get_ipcomp
= _get_ipcomp
,
1635 .set_ipcomp
= _set_ipcomp
,
1636 .get_close_action
= _get_close_action
,
1637 .set_close_action
= _set_close_action
,
1638 .get_dpd_action
= _get_dpd_action
,
1639 .set_dpd_action
= _set_dpd_action
,
1640 .alloc_spi
= _alloc_spi
,
1641 .alloc_cpi
= _alloc_cpi
,
1642 .install
= _install
,
1643 .register_outbound
= _register_outbound
,
1644 .install_outbound
= _install_outbound
,
1646 .set_policies
= _set_policies
,
1647 .install_policies
= _install_policies
,
1648 .create_ts_enumerator
= _create_ts_enumerator
,
1649 .create_policy_enumerator
= _create_policy_enumerator
,
1650 .destroy
= _destroy
,
1653 .ipcomp
= IPCOMP_NONE
,
1654 .state
= CHILD_CREATED
,
1655 .my_ts
= array_create(0, 0),
1656 .other_ts
= array_create(0, 0),
1657 .protocol
= PROTO_NONE
,
1658 .mode
= MODE_TUNNEL
,
1659 .close_action
= config
->get_close_action(config
),
1660 .dpd_action
= config
->get_dpd_action(config
),
1661 .reqid
= config
->get_reqid(config
),
1662 .unique_id
= ref_get(&unique_id
),
1663 .mark_in
= config
->get_mark(config
, TRUE
),
1664 .mark_out
= config
->get_mark(config
, FALSE
),
1665 .install_time
= time_monotonic(NULL
),
1666 .policies_fwd_out
= config
->has_option(config
, OPT_FWD_OUT_POLICIES
),
1669 this->config
= config
;
1670 config
->get_ref(config
);
1674 this->mark_in
.value
= mark_in
;
1678 this->mark_out
.value
= mark_out
;
1680 if (this->mark_in
.value
== MARK_UNIQUE
||
1681 this->mark_out
.value
== MARK_UNIQUE
)
1683 mark
= ref_get(&unique_mark
);
1684 if (this->mark_in
.value
== MARK_UNIQUE
)
1686 this->mark_in
.value
= mark
;
1688 if (this->mark_out
.value
== MARK_UNIQUE
)
1690 this->mark_out
.value
= mark
;
1696 /* reuse old reqid if we are rekeying an existing CHILD_SA. While the
1697 * reqid cache would find the same reqid for our selectors, this does
1698 * not work in a special case: If an SA is triggered by a trap policy,
1699 * but the negotiated SA gets narrowed, we still must reuse the same
1700 * reqid to successfully "trigger" the SA on the kernel level. Rekeying
1701 * such an SA requires an explicit reqid, as the cache currently knows
1702 * the original selectors only for that reqid. */
1705 this->reqid
= rekey
;
1709 this->reqid
= charon
->traps
->find_reqid(charon
->traps
, config
);
1714 this->static_reqid
= TRUE
;
1717 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1718 if (config
->get_mode(config
) == MODE_TRANSPORT
&&
1719 config
->has_option(config
, OPT_PROXY_MODE
))
1721 this->mode
= MODE_TRANSPORT
;
1723 this->my_addr
= get_proxy_addr(config
, me
, TRUE
);
1724 this->other_addr
= get_proxy_addr(config
, other
, FALSE
);
1728 this->my_addr
= me
->clone(me
);
1729 this->other_addr
= other
->clone(other
);
1731 return &this->public;