2 * Copyright (C) 2006-2019 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 ENUM_FLAGS(child_sa_outbound_state_names
, CHILD_OUTBOUND_REGISTERED
, CHILD_OUTBOUND_POLICIES
,
50 typedef struct private_child_sa_t private_child_sa_t
;
53 * Private data of a child_sa_t object.
55 struct private_child_sa_t
{
57 * Public interface of child_sa_t.
72 * our actually used SPI, 0 if unused
77 * others used SPI, 0 if unused
82 * our Compression Parameter Index (CPI) used, 0 if unused
87 * others Compression Parameter Index (CPI) used, 0 if unused
92 * Array for local traffic selectors
97 * Array for remote traffic selectors
102 * Outbound encryption key cached during a rekeying
107 * Outbound integrity key cached during a rekeying
112 * Whether the outbound SA has only been registered yet during a rekeying
114 child_sa_outbound_state_t outbound_state
;
117 * Whether the peer supports TFCv3
122 * The outbound SPI of the CHILD_SA that replaced this one during a rekeying
127 * Protocol used to protect this SA, ESP|AH
129 protocol_id_t protocol
;
132 * reqid used for this child_sa
137 * Did we allocate/confirm and must release the reqid?
139 bool reqid_allocated
;
142 * Is the reqid statically configured
147 * Unique CHILD_SA identifier
152 * Whether FWD policieis in the outbound direction should be installed
154 bool policies_fwd_out
;
157 * Inbound interface ID
162 * Outbound interface ID
167 * inbound mark used for this child_sa
172 * outbound mark used for this child_sa
177 * absolute time when rekeying is scheduled
182 * absolute time when the SA expires
187 * absolute time when SA has been installed
192 * state of the CHILD_SA
194 child_sa_state_t state
;
197 * TRUE if this CHILD_SA is used to install trap policies
202 * Specifies if UDP encapsulation is enabled (NAT traversal)
207 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
209 ipcomp_transform_t ipcomp
;
212 * mode this SA uses, tunnel/transport
217 * Action to enforce if peer closes the CHILD_SA
219 action_t close_action
;
222 * Action to enforce if peer is considered dead
229 proposal_t
*proposal
;
232 * config used to create this child
237 * time of last use in seconds (inbound)
242 * time of last use in seconds (outbound)
244 time_t other_usetime
;
247 * last number of inbound bytes
249 uint64_t my_usebytes
;
252 * last number of outbound bytes
254 uint64_t other_usebytes
;
257 * last number of inbound packets
259 uint64_t my_usepackets
;
262 * last number of outbound bytes
264 uint64_t other_usepackets
;
268 * Convert an IKEv2 specific protocol identifier to the IP protocol identifier
270 static inline uint8_t proto_ike2ip(protocol_id_t protocol
)
284 * Returns the mark to use on the inbound SA
286 static inline mark_t
mark_in_sa(private_child_sa_t
*this)
288 if (this->config
->has_option(this->config
, OPT_MARK_IN_SA
))
290 return this->mark_in
;
295 METHOD(child_sa_t
, get_name
, char*,
296 private_child_sa_t
*this)
298 return this->config
->get_name(this->config
);
301 METHOD(child_sa_t
, get_reqid
, uint32_t,
302 private_child_sa_t
*this)
307 METHOD(child_sa_t
, get_unique_id
, uint32_t,
308 private_child_sa_t
*this)
310 return this->unique_id
;
313 METHOD(child_sa_t
, get_config
, child_cfg_t
*,
314 private_child_sa_t
*this)
319 METHOD(child_sa_t
, set_state
, void,
320 private_child_sa_t
*this, child_sa_state_t state
)
322 if (this->state
!= state
)
324 DBG2(DBG_CHD
, "CHILD_SA %s{%d} state change: %N => %N",
325 get_name(this), this->unique_id
,
326 child_sa_state_names
, this->state
,
327 child_sa_state_names
, state
);
328 charon
->bus
->child_state_change(charon
->bus
, &this->public, state
);
333 METHOD(child_sa_t
, get_state
, child_sa_state_t
,
334 private_child_sa_t
*this)
339 METHOD(child_sa_t
, get_outbound_state
, child_sa_outbound_state_t
,
340 private_child_sa_t
*this)
342 return this->outbound_state
;
345 METHOD(child_sa_t
, get_spi
, uint32_t,
346 private_child_sa_t
*this, bool inbound
)
348 return inbound
? this->my_spi
: this->other_spi
;
351 METHOD(child_sa_t
, get_cpi
, uint16_t,
352 private_child_sa_t
*this, bool inbound
)
354 return inbound
? this->my_cpi
: this->other_cpi
;
357 METHOD(child_sa_t
, get_protocol
, protocol_id_t
,
358 private_child_sa_t
*this)
360 return this->protocol
;
363 METHOD(child_sa_t
, set_protocol
, void,
364 private_child_sa_t
*this, protocol_id_t protocol
)
366 this->protocol
= protocol
;
369 METHOD(child_sa_t
, get_mode
, ipsec_mode_t
,
370 private_child_sa_t
*this)
375 METHOD(child_sa_t
, set_mode
, void,
376 private_child_sa_t
*this, ipsec_mode_t mode
)
381 METHOD(child_sa_t
, has_encap
, bool,
382 private_child_sa_t
*this)
387 METHOD(child_sa_t
, get_ipcomp
, ipcomp_transform_t
,
388 private_child_sa_t
*this)
393 METHOD(child_sa_t
, set_ipcomp
, void,
394 private_child_sa_t
*this, ipcomp_transform_t ipcomp
)
396 this->ipcomp
= ipcomp
;
399 METHOD(child_sa_t
, set_close_action
, void,
400 private_child_sa_t
*this, action_t action
)
402 this->close_action
= action
;
405 METHOD(child_sa_t
, get_close_action
, action_t
,
406 private_child_sa_t
*this)
408 return this->close_action
;
411 METHOD(child_sa_t
, set_dpd_action
, void,
412 private_child_sa_t
*this, action_t action
)
414 this->dpd_action
= action
;
417 METHOD(child_sa_t
, get_dpd_action
, action_t
,
418 private_child_sa_t
*this)
420 return this->dpd_action
;
423 METHOD(child_sa_t
, get_proposal
, proposal_t
*,
424 private_child_sa_t
*this)
426 return this->proposal
;
429 METHOD(child_sa_t
, set_proposal
, void,
430 private_child_sa_t
*this, proposal_t
*proposal
)
432 this->proposal
= proposal
->clone(proposal
);
435 METHOD(child_sa_t
, create_ts_enumerator
, enumerator_t
*,
436 private_child_sa_t
*this, bool local
)
440 return array_create_enumerator(this->my_ts
);
442 return array_create_enumerator(this->other_ts
);
445 typedef struct policy_enumerator_t policy_enumerator_t
;
448 * Private policy enumerator
450 struct policy_enumerator_t
{
451 /** implements enumerator_t */
453 /** enumerator over own TS */
455 /** enumerator over others TS */
457 /** array of others TS, to recreate enumerator */
459 /** currently enumerating TS for "me" side */
460 traffic_selector_t
*ts
;
463 METHOD(enumerator_t
, policy_enumerate
, bool,
464 policy_enumerator_t
*this, va_list args
)
466 traffic_selector_t
*other_ts
, **my_out
, **other_out
;
468 VA_ARGS_VGET(args
, my_out
, other_out
);
470 while (this->ts
|| this->mine
->enumerate(this->mine
, &this->ts
))
472 if (!this->other
->enumerate(this->other
, &other_ts
))
473 { /* end of others list, restart with new of mine */
474 this->other
->destroy(this->other
);
475 this->other
= array_create_enumerator(this->array
);
479 if (this->ts
->get_type(this->ts
) != other_ts
->get_type(other_ts
))
480 { /* family mismatch */
483 if (this->ts
->get_protocol(this->ts
) &&
484 other_ts
->get_protocol(other_ts
) &&
485 this->ts
->get_protocol(this->ts
) != other_ts
->get_protocol(other_ts
))
486 { /* protocol mismatch */
495 *other_out
= other_ts
;
502 METHOD(enumerator_t
, policy_destroy
, void,
503 policy_enumerator_t
*this)
505 this->mine
->destroy(this->mine
);
506 this->other
->destroy(this->other
);
510 METHOD(child_sa_t
, create_policy_enumerator
, enumerator_t
*,
511 private_child_sa_t
*this)
513 policy_enumerator_t
*e
;
517 .enumerate
= enumerator_enumerate_default
,
518 .venumerate
= _policy_enumerate
,
519 .destroy
= _policy_destroy
,
521 .mine
= array_create_enumerator(this->my_ts
),
522 .other
= array_create_enumerator(this->other_ts
),
523 .array
= this->other_ts
,
531 * update the cached usebytes
532 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
533 * are available, and NOT_SUPPORTED if the kernel interface does not support
534 * querying the usebytes.
536 static status_t
update_usebytes(private_child_sa_t
*this, bool inbound
)
538 status_t status
= FAILED
;
539 uint64_t bytes
, packets
;
546 kernel_ipsec_sa_id_t id
= {
547 .src
= this->other_addr
,
548 .dst
= this->my_addr
,
550 .proto
= proto_ike2ip(this->protocol
),
551 .mark
= mark_in_sa(this),
552 .if_id
= this->if_id_in
,
554 kernel_ipsec_query_sa_t query
= {};
556 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
557 &bytes
, &packets
, &time
);
558 if (status
== SUCCESS
)
560 if (bytes
> this->my_usebytes
)
562 this->my_usebytes
= bytes
;
563 this->my_usepackets
= packets
;
566 this->my_usetime
= time
;
578 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
580 kernel_ipsec_sa_id_t id
= {
581 .src
= this->my_addr
,
582 .dst
= this->other_addr
,
583 .spi
= this->other_spi
,
584 .proto
= proto_ike2ip(this->protocol
),
585 .mark
= this->mark_out
,
586 .if_id
= this->if_id_out
,
588 kernel_ipsec_query_sa_t query
= {};
590 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
591 &bytes
, &packets
, &time
);
592 if (status
== SUCCESS
)
594 if (bytes
> this->other_usebytes
)
596 this->other_usebytes
= bytes
;
597 this->other_usepackets
= packets
;
600 this->other_usetime
= time
;
614 * updates the cached usetime
616 static bool update_usetime(private_child_sa_t
*this, bool inbound
)
618 enumerator_t
*enumerator
;
619 traffic_selector_t
*my_ts
, *other_ts
;
622 enumerator
= create_policy_enumerator(this);
623 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
629 kernel_ipsec_policy_id_t id
= {
633 .mark
= this->mark_in
,
634 .if_id
= this->if_id_in
,
636 kernel_ipsec_query_policy_t query
= {};
638 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
641 last_use
= max(last_use
, in
);
643 if (this->mode
!= MODE_TRANSPORT
)
646 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
649 last_use
= max(last_use
, fwd
);
655 kernel_ipsec_policy_id_t id
= {
659 .mark
= this->mark_out
,
660 .if_id
= this->if_id_out
,
661 .interface
= this->config
->get_interface(this->config
),
663 kernel_ipsec_query_policy_t query
= {};
665 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
668 last_use
= max(last_use
, out
);
672 enumerator
->destroy(enumerator
);
680 this->my_usetime
= last_use
;
684 this->other_usetime
= last_use
;
689 METHOD(child_sa_t
, get_usestats
, void,
690 private_child_sa_t
*this, bool inbound
,
691 time_t *time
, uint64_t *bytes
, uint64_t *packets
)
693 if ((!bytes
&& !packets
) || update_usebytes(this, inbound
) != FAILED
)
695 /* there was traffic since last update or the kernel interface
696 * does not support querying the number of usebytes.
700 if (!update_usetime(this, inbound
) && !bytes
&& !packets
)
702 /* if policy query did not yield a usetime, query SAs instead */
703 update_usebytes(this, inbound
);
709 *time
= inbound
? this->my_usetime
: this->other_usetime
;
713 *bytes
= inbound
? this->my_usebytes
: this->other_usebytes
;
717 *packets
= inbound
? this->my_usepackets
: this->other_usepackets
;
721 METHOD(child_sa_t
, get_mark
, mark_t
,
722 private_child_sa_t
*this, bool inbound
)
724 return inbound
? this->mark_in
: this->mark_out
;
727 METHOD(child_sa_t
, get_if_id
, uint32_t,
728 private_child_sa_t
*this, bool inbound
)
730 return inbound
? this->if_id_in
: this->if_id_out
;
733 METHOD(child_sa_t
, get_lifetime
, time_t,
734 private_child_sa_t
*this, bool hard
)
736 return hard
? this->expire_time
: this->rekey_time
;
739 METHOD(child_sa_t
, get_installtime
, time_t,
740 private_child_sa_t
*this)
742 return this->install_time
;
745 METHOD(child_sa_t
, alloc_spi
, uint32_t,
746 private_child_sa_t
*this, protocol_id_t protocol
)
748 if (charon
->kernel
->get_spi(charon
->kernel
, this->other_addr
, this->my_addr
,
749 proto_ike2ip(protocol
), &this->my_spi
) == SUCCESS
)
751 /* if we allocate a SPI, but then are unable to establish the SA, we
752 * need to know the protocol family to delete the partial SA */
753 this->protocol
= protocol
;
759 METHOD(child_sa_t
, alloc_cpi
, uint16_t,
760 private_child_sa_t
*this)
762 if (charon
->kernel
->get_cpi(charon
->kernel
, this->other_addr
, this->my_addr
,
763 &this->my_cpi
) == SUCCESS
)
771 * Install the given SA in the kernel
773 static status_t
install_internal(private_child_sa_t
*this, chunk_t encr
,
774 chunk_t integ
, uint32_t spi
, uint16_t cpi
, bool initiator
, bool inbound
,
777 uint16_t enc_alg
= ENCR_UNDEFINED
, int_alg
= AUTH_UNDEFINED
, size
;
778 uint16_t esn
= NO_EXT_SEQ_NUMBERS
;
779 linked_list_t
*my_ts
, *other_ts
, *src_ts
, *dst_ts
;
781 kernel_ipsec_sa_id_t id
;
782 kernel_ipsec_add_sa_t sa
;
783 lifetime_cfg_t
*lifetime
;
789 /* BEET requires the bound address from the traffic selectors */
790 my_ts
= linked_list_create_from_enumerator(
791 array_create_enumerator(this->my_ts
));
792 other_ts
= linked_list_create_from_enumerator(
793 array_create_enumerator(this->other_ts
));
795 /* now we have to decide which spi to use. Use self allocated, if "in",
796 * or the one in the proposal, if not "in" (others). Additionally,
797 * source and dest host switch depending on the role */
801 src
= this->other_addr
;
802 if (this->my_spi
== spi
)
803 { /* alloc_spi has been called, do an SA update */
814 dst
= this->other_addr
;
815 this->other_spi
= spi
;
816 this->other_cpi
= cpi
;
822 tfc
= this->config
->get_tfc(this->config
);
824 this->outbound_state
|= CHILD_OUTBOUND_SA
;
827 DBG2(DBG_CHD
, "adding %s %N SA", inbound
? "inbound" : "outbound",
828 protocol_id_names
, this->protocol
);
830 /* send SA down to the kernel */
831 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), src
, dst
);
833 this->proposal
->get_algorithm(this->proposal
, ENCRYPTION_ALGORITHM
,
835 this->proposal
->get_algorithm(this->proposal
, INTEGRITY_ALGORITHM
,
837 this->proposal
->get_algorithm(this->proposal
, EXTENDED_SEQUENCE_NUMBERS
,
840 if (int_alg
== AUTH_HMAC_SHA2_256_128
&&
841 this->config
->has_option(this->config
, OPT_SHA256_96
))
843 DBG2(DBG_CHD
, " using %N with 96-bit truncation",
844 integrity_algorithm_names
, int_alg
);
845 int_alg
= AUTH_HMAC_SHA2_256_96
;
848 if (!this->reqid_allocated
&& !this->static_reqid
)
850 status
= charon
->kernel
->alloc_reqid(charon
->kernel
, my_ts
, other_ts
,
851 this->mark_in
, this->mark_out
, this->if_id_in
,
852 this->if_id_out
, &this->reqid
);
853 if (status
!= SUCCESS
)
855 my_ts
->destroy(my_ts
);
856 other_ts
->destroy(other_ts
);
859 this->reqid_allocated
= TRUE
;
862 lifetime
= this->config
->get_lifetime(this->config
, TRUE
);
864 now
= time_monotonic(NULL
);
865 if (lifetime
->time
.rekey
)
867 if (this->rekey_time
)
869 this->rekey_time
= min(this->rekey_time
, now
+ lifetime
->time
.rekey
);
873 this->rekey_time
= now
+ lifetime
->time
.rekey
;
876 if (lifetime
->time
.life
)
878 this->expire_time
= now
+ lifetime
->time
.life
;
881 if (!lifetime
->time
.jitter
&& !inbound
)
882 { /* avoid triggering multiple rekey events */
883 lifetime
->time
.rekey
= 0;
886 id
= (kernel_ipsec_sa_id_t
){
890 .proto
= proto_ike2ip(this->protocol
),
891 .mark
= inbound
? mark_in_sa(this) : this->mark_out
,
892 .if_id
= inbound
? this->if_id_in
: this->if_id_out
,
894 sa
= (kernel_ipsec_add_sa_t
){
895 .reqid
= this->reqid
,
899 .interface
= inbound
? NULL
: this->config
->get_interface(this->config
),
900 .lifetime
= lifetime
,
905 .replay_window
= this->config
->get_replay_window(this->config
),
907 .ipcomp
= this->ipcomp
,
909 .encap
= this->encap
,
910 .hw_offload
= this->config
->get_hw_offload(this->config
),
911 .mark
= this->config
->get_set_mark(this->config
, inbound
),
913 .copy_df
= !this->config
->has_option(this->config
, OPT_NO_COPY_DF
),
914 .copy_ecn
= !this->config
->has_option(this->config
, OPT_NO_COPY_ECN
),
915 .copy_dscp
= this->config
->get_copy_dscp(this->config
),
916 .initiator
= initiator
,
921 if (sa
.mark
.value
== MARK_SAME
)
923 sa
.mark
.value
= inbound
? this->mark_in
.value
: this->mark_out
.value
;
926 status
= charon
->kernel
->add_sa(charon
->kernel
, &id
, &sa
);
928 my_ts
->destroy(my_ts
);
929 other_ts
->destroy(other_ts
);
935 METHOD(child_sa_t
, install
, status_t
,
936 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
937 uint16_t cpi
, bool initiator
, bool inbound
, bool tfcv3
)
939 return install_internal(this, encr
, integ
, spi
, cpi
, initiator
, inbound
,
944 * Check kernel interface if policy updates are required
946 static bool require_policy_update()
950 f
= charon
->kernel
->get_features(charon
->kernel
);
951 return !(f
& KERNEL_NO_POLICY_UPDATES
);
955 * Prepare SA config to install/delete policies
957 static void prepare_sa_cfg(private_child_sa_t
*this, ipsec_sa_cfg_t
*my_sa
,
958 ipsec_sa_cfg_t
*other_sa
)
960 enumerator_t
*enumerator
;
962 *my_sa
= (ipsec_sa_cfg_t
){
964 .reqid
= this->reqid
,
966 .transform
= this->ipcomp
,
971 my_sa
->ipcomp
.cpi
= this->my_cpi
;
972 other_sa
->ipcomp
.cpi
= this->other_cpi
;
974 if (this->protocol
== PROTO_ESP
)
976 my_sa
->esp
.use
= TRUE
;
977 my_sa
->esp
.spi
= this->my_spi
;
978 other_sa
->esp
.use
= TRUE
;
979 other_sa
->esp
.spi
= this->other_spi
;
983 my_sa
->ah
.use
= TRUE
;
984 my_sa
->ah
.spi
= this->my_spi
;
985 other_sa
->ah
.use
= TRUE
;
986 other_sa
->ah
.spi
= this->other_spi
;
989 enumerator
= create_policy_enumerator(this);
990 while (enumerator
->enumerate(enumerator
, NULL
, NULL
))
992 my_sa
->policy_count
++;
993 other_sa
->policy_count
++;
995 enumerator
->destroy(enumerator
);
999 * Install inbound policies: in, fwd
1001 static status_t
install_policies_inbound(private_child_sa_t
*this,
1002 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1003 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1004 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1005 policy_priority_t priority
, uint32_t manual_prio
)
1007 kernel_ipsec_policy_id_t in_id
= {
1011 .mark
= this->mark_in
,
1012 .if_id
= this->if_id_in
,
1014 kernel_ipsec_manage_policy_t in_policy
= {
1017 .manual_prio
= manual_prio
,
1022 status_t status
= SUCCESS
;
1024 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
1025 if (this->mode
!= MODE_TRANSPORT
)
1027 in_id
.dir
= POLICY_FWD
;
1028 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
1034 * Install outbound policies: out, [fwd]
1036 static status_t
install_policies_outbound(private_child_sa_t
*this,
1037 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1038 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1039 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1040 policy_priority_t priority
, uint32_t manual_prio
)
1042 kernel_ipsec_policy_id_t out_id
= {
1046 .mark
= this->mark_out
,
1047 .if_id
= this->if_id_out
,
1048 .interface
= this->config
->get_interface(this->config
),
1050 kernel_ipsec_manage_policy_t out_policy
= {
1053 .manual_prio
= manual_prio
,
1058 status_t status
= SUCCESS
;
1060 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
, &out_policy
);
1062 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1064 /* install an "outbound" FWD policy in case there is a drop policy
1065 * matching outbound forwarded traffic, to allow another tunnel to use
1066 * the reversed subnets and do the same we don't set a reqid (this also
1067 * allows the kernel backend to distinguish between the two types of
1068 * FWD policies). To avoid problems with symmetrically overlapping
1069 * policies of two SAs we install them with reduced priority. As they
1070 * basically act as bypass policies for drop policies we use a higher
1071 * priority than is used for them. */
1072 out_id
.dir
= POLICY_FWD
;
1073 other_sa
->reqid
= 0;
1074 if (priority
== POLICY_PRIORITY_DEFAULT
)
1076 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1078 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
,
1080 /* reset the reqid for any other further policies */
1081 other_sa
->reqid
= this->reqid
;
1087 * Install all policies
1089 static status_t
install_policies_internal(private_child_sa_t
*this,
1090 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1091 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1092 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1093 policy_priority_t priority
, uint32_t manual_prio
, bool outbound
)
1095 status_t status
= SUCCESS
;
1097 status
|= install_policies_inbound(this, my_addr
, other_addr
, my_ts
,
1098 other_ts
, my_sa
, other_sa
, type
, priority
, manual_prio
);
1101 status
|= install_policies_outbound(this, my_addr
, other_addr
, my_ts
,
1102 other_ts
, my_sa
, other_sa
, type
, priority
, manual_prio
);
1108 * Delete inbound policies: in, fwd
1110 static void del_policies_inbound(private_child_sa_t
*this,
1111 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1112 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1113 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1114 policy_priority_t priority
, uint32_t manual_prio
)
1116 kernel_ipsec_policy_id_t in_id
= {
1120 .mark
= this->mark_in
,
1121 .if_id
= this->if_id_in
,
1123 kernel_ipsec_manage_policy_t in_policy
= {
1126 .manual_prio
= manual_prio
,
1132 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1134 if (this->mode
!= MODE_TRANSPORT
)
1136 in_id
.dir
= POLICY_FWD
;
1137 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1142 * Delete outbound policies: out, [fwd]
1144 static void del_policies_outbound(private_child_sa_t
*this,
1145 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1146 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1147 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1148 policy_priority_t priority
, uint32_t manual_prio
)
1150 kernel_ipsec_policy_id_t out_id
= {
1154 .mark
= this->mark_out
,
1155 .if_id
= this->if_id_out
,
1156 .interface
= this->config
->get_interface(this->config
),
1158 kernel_ipsec_manage_policy_t out_policy
= {
1161 .manual_prio
= manual_prio
,
1167 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1169 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1171 out_id
.dir
= POLICY_FWD
;
1172 other_sa
->reqid
= 0;
1173 if (priority
== POLICY_PRIORITY_DEFAULT
)
1175 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1177 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1178 other_sa
->reqid
= this->reqid
;
1183 * Delete in- and outbound policies
1185 static void del_policies_internal(private_child_sa_t
*this,
1186 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1187 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1188 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1189 policy_priority_t priority
, uint32_t manual_prio
, bool outbound
)
1193 del_policies_outbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1194 other_sa
, type
, priority
, manual_prio
);
1196 del_policies_inbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1197 other_sa
, type
, priority
, manual_prio
);
1200 METHOD(child_sa_t
, set_policies
, void,
1201 private_child_sa_t
*this, linked_list_t
*my_ts_list
,
1202 linked_list_t
*other_ts_list
)
1204 enumerator_t
*enumerator
;
1205 traffic_selector_t
*my_ts
, *other_ts
;
1207 if (array_count(this->my_ts
))
1209 array_destroy_offset(this->my_ts
,
1210 offsetof(traffic_selector_t
, destroy
));
1211 this->my_ts
= array_create(0, 0);
1213 enumerator
= my_ts_list
->create_enumerator(my_ts_list
);
1214 while (enumerator
->enumerate(enumerator
, &my_ts
))
1216 array_insert(this->my_ts
, ARRAY_TAIL
, my_ts
->clone(my_ts
));
1218 enumerator
->destroy(enumerator
);
1219 array_sort(this->my_ts
, (void*)traffic_selector_cmp
, NULL
);
1221 if (array_count(this->other_ts
))
1223 array_destroy_offset(this->other_ts
,
1224 offsetof(traffic_selector_t
, destroy
));
1225 this->other_ts
= array_create(0, 0);
1227 enumerator
= other_ts_list
->create_enumerator(other_ts_list
);
1228 while (enumerator
->enumerate(enumerator
, &other_ts
))
1230 array_insert(this->other_ts
, ARRAY_TAIL
, other_ts
->clone(other_ts
));
1232 enumerator
->destroy(enumerator
);
1233 array_sort(this->other_ts
, (void*)traffic_selector_cmp
, NULL
);
1236 METHOD(child_sa_t
, install_policies
, status_t
,
1237 private_child_sa_t
*this)
1239 enumerator_t
*enumerator
;
1240 linked_list_t
*my_ts_list
, *other_ts_list
;
1241 traffic_selector_t
*my_ts
, *other_ts
;
1242 status_t status
= SUCCESS
;
1243 bool install_outbound
= FALSE
;
1245 if (!this->reqid_allocated
&& !this->static_reqid
)
1247 my_ts_list
= linked_list_create_from_enumerator(
1248 array_create_enumerator(this->my_ts
));
1249 other_ts_list
= linked_list_create_from_enumerator(
1250 array_create_enumerator(this->other_ts
));
1251 status
= charon
->kernel
->alloc_reqid(
1252 charon
->kernel
, my_ts_list
, other_ts_list
,
1253 this->mark_in
, this->mark_out
, this->if_id_in
,
1254 this->if_id_out
, &this->reqid
);
1255 my_ts_list
->destroy(my_ts_list
);
1256 other_ts_list
->destroy(other_ts_list
);
1257 if (status
!= SUCCESS
)
1261 this->reqid_allocated
= TRUE
;
1264 if (!(this->outbound_state
& CHILD_OUTBOUND_REGISTERED
))
1266 install_outbound
= TRUE
;
1267 this->outbound_state
|= CHILD_OUTBOUND_POLICIES
;
1270 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1272 policy_priority_t priority
;
1273 ipsec_sa_cfg_t my_sa
, other_sa
;
1274 uint32_t manual_prio
;
1276 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1277 manual_prio
= this->config
->get_manual_prio(this->config
);
1279 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1280 * entry) we install a trap policy */
1281 this->trap
= this->state
== CHILD_CREATED
;
1282 priority
= this->trap
? POLICY_PRIORITY_ROUTED
1283 : POLICY_PRIORITY_DEFAULT
;
1285 /* enumerate pairs of traffic selectors */
1286 enumerator
= create_policy_enumerator(this);
1287 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1289 status
|= install_policies_internal(this, this->my_addr
,
1290 this->other_addr
, my_ts
, other_ts
,
1291 &my_sa
, &other_sa
, POLICY_IPSEC
, priority
,
1292 manual_prio
, install_outbound
);
1293 if (status
!= SUCCESS
)
1298 enumerator
->destroy(enumerator
);
1301 if (status
== SUCCESS
&& this->trap
)
1303 set_state(this, CHILD_ROUTED
);
1308 METHOD(child_sa_t
, register_outbound
, status_t
,
1309 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
1310 uint16_t cpi
, bool tfcv3
)
1314 /* if the kernel supports installing SPIs with policies we install the
1315 * SA immediately as it will only be used once we update the policies */
1316 if (charon
->kernel
->get_features(charon
->kernel
) & KERNEL_POLICY_SPI
)
1318 status
= install_internal(this, encr
, integ
, spi
, cpi
, FALSE
, FALSE
,
1323 DBG2(DBG_CHD
, "registering outbound %N SA", protocol_id_names
,
1325 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), this->my_addr
,
1328 this->other_spi
= spi
;
1329 this->other_cpi
= cpi
;
1330 this->encr_r
= chunk_clone(encr
);
1331 this->integ_r
= chunk_clone(integ
);
1332 this->tfcv3
= tfcv3
;
1335 this->outbound_state
|= CHILD_OUTBOUND_REGISTERED
;
1339 METHOD(child_sa_t
, install_outbound
, status_t
,
1340 private_child_sa_t
*this)
1342 enumerator_t
*enumerator
;
1343 traffic_selector_t
*my_ts
, *other_ts
;
1344 status_t status
= SUCCESS
;
1346 if (!(this->outbound_state
& CHILD_OUTBOUND_SA
))
1348 status
= install_internal(this, this->encr_r
, this->integ_r
,
1349 this->other_spi
, this->other_cpi
, FALSE
,
1350 FALSE
, this->tfcv3
);
1351 chunk_clear(&this->encr_r
);
1352 chunk_clear(&this->integ_r
);
1354 this->outbound_state
&= ~CHILD_OUTBOUND_REGISTERED
;
1355 if (status
!= SUCCESS
)
1359 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1360 !(this->outbound_state
& CHILD_OUTBOUND_POLICIES
))
1362 ipsec_sa_cfg_t my_sa
, other_sa
;
1363 uint32_t manual_prio
;
1365 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1366 manual_prio
= this->config
->get_manual_prio(this->config
);
1368 enumerator
= create_policy_enumerator(this);
1369 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1371 status
|= install_policies_outbound(this, this->my_addr
,
1372 this->other_addr
, my_ts
, other_ts
,
1373 &my_sa
, &other_sa
, POLICY_IPSEC
,
1374 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1375 if (status
!= SUCCESS
)
1380 enumerator
->destroy(enumerator
);
1382 this->outbound_state
|= CHILD_OUTBOUND_POLICIES
;
1386 METHOD(child_sa_t
, remove_outbound
, void,
1387 private_child_sa_t
*this)
1389 enumerator_t
*enumerator
;
1390 traffic_selector_t
*my_ts
, *other_ts
;
1392 if (!(this->outbound_state
& CHILD_OUTBOUND_SA
))
1394 if (this->outbound_state
& CHILD_OUTBOUND_REGISTERED
)
1396 chunk_clear(&this->encr_r
);
1397 chunk_clear(&this->integ_r
);
1398 this->outbound_state
= CHILD_OUTBOUND_NONE
;
1403 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1404 (this->outbound_state
& CHILD_OUTBOUND_POLICIES
))
1406 ipsec_sa_cfg_t my_sa
, other_sa
;
1407 uint32_t manual_prio
;
1409 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1410 manual_prio
= this->config
->get_manual_prio(this->config
);
1412 enumerator
= create_policy_enumerator(this);
1413 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1415 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1416 my_ts
, other_ts
, &my_sa
, &other_sa
,
1417 POLICY_IPSEC
, POLICY_PRIORITY_DEFAULT
,
1420 enumerator
->destroy(enumerator
);
1423 kernel_ipsec_sa_id_t id
= {
1424 .src
= this->my_addr
,
1425 .dst
= this->other_addr
,
1426 .spi
= this->other_spi
,
1427 .proto
= proto_ike2ip(this->protocol
),
1428 .mark
= this->mark_out
,
1429 .if_id
= this->if_id_out
,
1431 kernel_ipsec_del_sa_t sa
= {
1432 .cpi
= this->other_cpi
,
1434 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1435 this->outbound_state
= CHILD_OUTBOUND_NONE
;
1438 METHOD(child_sa_t
, set_rekey_spi
, void,
1439 private_child_sa_t
*this, uint32_t spi
)
1441 this->rekey_spi
= spi
;
1444 METHOD(child_sa_t
, get_rekey_spi
, uint32_t,
1445 private_child_sa_t
*this)
1447 return this->rekey_spi
;
1450 CALLBACK(reinstall_vip
, void,
1451 host_t
*vip
, va_list args
)
1456 VA_ARGS_VGET(args
, me
);
1457 if (charon
->kernel
->get_interface(charon
->kernel
, me
, &iface
))
1459 charon
->kernel
->del_ip(charon
->kernel
, vip
, -1, TRUE
);
1460 charon
->kernel
->add_ip(charon
->kernel
, vip
, -1, iface
);
1466 * Update addresses and encap state of IPsec SAs in the kernel
1468 static status_t
update_sas(private_child_sa_t
*this, host_t
*me
, host_t
*other
,
1471 /* update our (initiator) SA */
1474 kernel_ipsec_sa_id_t id
= {
1475 .src
= this->other_addr
,
1476 .dst
= this->my_addr
,
1477 .spi
= this->my_spi
,
1478 .proto
= proto_ike2ip(this->protocol
),
1479 .mark
= mark_in_sa(this),
1480 .if_id
= this->if_id_in
,
1482 kernel_ipsec_update_sa_t sa
= {
1483 .cpi
= this->ipcomp
!= IPCOMP_NONE
? this->my_cpi
: 0,
1486 .encap
= this->encap
,
1489 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1490 &sa
) == NOT_SUPPORTED
)
1492 return NOT_SUPPORTED
;
1496 /* update his (responder) SA */
1497 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
1499 kernel_ipsec_sa_id_t id
= {
1500 .src
= this->my_addr
,
1501 .dst
= this->other_addr
,
1502 .spi
= this->other_spi
,
1503 .proto
= proto_ike2ip(this->protocol
),
1504 .mark
= this->mark_out
,
1505 .if_id
= this->if_id_out
,
1507 kernel_ipsec_update_sa_t sa
= {
1508 .cpi
= this->ipcomp
!= IPCOMP_NONE
? this->other_cpi
: 0,
1511 .encap
= this->encap
,
1514 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1515 &sa
) == NOT_SUPPORTED
)
1517 return NOT_SUPPORTED
;
1520 /* we currently ignore the actual return values above */
1524 METHOD(child_sa_t
, update
, status_t
,
1525 private_child_sa_t
*this, host_t
*me
, host_t
*other
, linked_list_t
*vips
,
1528 child_sa_state_t old
;
1529 bool transport_proxy_mode
;
1531 /* anything changed at all? */
1532 if (me
->equals(me
, this->my_addr
) &&
1533 other
->equals(other
, this->other_addr
) && this->encap
== encap
)
1539 set_state(this, CHILD_UPDATING
);
1540 transport_proxy_mode
= this->mode
== MODE_TRANSPORT
&&
1541 this->config
->has_option(this->config
,
1544 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1545 require_policy_update())
1547 ipsec_sa_cfg_t my_sa
, other_sa
;
1548 enumerator_t
*enumerator
;
1549 traffic_selector_t
*my_ts
, *other_ts
;
1550 uint32_t manual_prio
;
1554 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1555 manual_prio
= this->config
->get_manual_prio(this->config
);
1556 outbound
= (this->outbound_state
& CHILD_OUTBOUND_POLICIES
);
1558 enumerator
= create_policy_enumerator(this);
1559 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1561 /* install drop policy to avoid traffic leaks, acquires etc. */
1564 install_policies_outbound(this, this->my_addr
, this->other_addr
,
1565 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_DROP
,
1566 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1568 /* remove old policies */
1569 del_policies_internal(this, this->my_addr
, this->other_addr
,
1570 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
,
1571 POLICY_PRIORITY_DEFAULT
, manual_prio
, outbound
);
1573 enumerator
->destroy(enumerator
);
1575 /* update the IPsec SAs */
1576 state
= update_sas(this, me
, other
, encap
);
1578 enumerator
= create_policy_enumerator(this);
1579 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1581 traffic_selector_t
*old_my_ts
= NULL
, *old_other_ts
= NULL
;
1583 /* reinstall the previous policies if we can't update the SAs */
1584 if (state
== NOT_SUPPORTED
)
1586 install_policies_internal(this, this->my_addr
, this->other_addr
,
1587 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
,
1588 POLICY_PRIORITY_DEFAULT
, manual_prio
, outbound
);
1592 /* check if we have to update a "dynamic" traffic selector */
1593 if (!me
->ip_equals(me
, this->my_addr
) &&
1594 my_ts
->is_host(my_ts
, this->my_addr
))
1596 old_my_ts
= my_ts
->clone(my_ts
);
1597 my_ts
->set_address(my_ts
, me
);
1599 if (!other
->ip_equals(other
, this->other_addr
) &&
1600 other_ts
->is_host(other_ts
, this->other_addr
))
1602 old_other_ts
= other_ts
->clone(other_ts
);
1603 other_ts
->set_address(other_ts
, other
);
1606 /* we reinstall the virtual IP to handle interface roaming
1608 vips
->invoke_function(vips
, reinstall_vip
, me
);
1610 /* reinstall updated policies */
1611 install_policies_internal(this, me
, other
, my_ts
, other_ts
,
1612 &my_sa
, &other_sa
, POLICY_IPSEC
,
1613 POLICY_PRIORITY_DEFAULT
, manual_prio
, outbound
);
1615 /* remove the drop policy */
1618 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1619 old_my_ts
?: my_ts
, old_other_ts
?: other_ts
,
1620 &my_sa
, &other_sa
, POLICY_DROP
,
1621 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1624 DESTROY_IF(old_my_ts
);
1625 DESTROY_IF(old_other_ts
);
1627 enumerator
->destroy(enumerator
);
1629 if (state
== NOT_SUPPORTED
)
1631 set_state(this, old
);
1632 return NOT_SUPPORTED
;
1636 else if (!transport_proxy_mode
)
1638 if (update_sas(this, me
, other
, encap
) == NOT_SUPPORTED
)
1640 set_state(this, old
);
1641 return NOT_SUPPORTED
;
1645 if (!transport_proxy_mode
)
1648 if (!me
->equals(me
, this->my_addr
))
1650 this->my_addr
->destroy(this->my_addr
);
1651 this->my_addr
= me
->clone(me
);
1653 if (!other
->equals(other
, this->other_addr
))
1655 this->other_addr
->destroy(this->other_addr
);
1656 this->other_addr
= other
->clone(other
);
1660 this->encap
= encap
;
1661 set_state(this, old
);
1666 METHOD(child_sa_t
, destroy
, void,
1667 private_child_sa_t
*this)
1669 enumerator_t
*enumerator
;
1670 traffic_selector_t
*my_ts
, *other_ts
;
1671 policy_priority_t priority
;
1673 priority
= this->trap
? POLICY_PRIORITY_ROUTED
: POLICY_PRIORITY_DEFAULT
;
1675 set_state(this, CHILD_DESTROYING
);
1677 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1679 ipsec_sa_cfg_t my_sa
, other_sa
;
1680 uint32_t manual_prio
;
1683 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1684 manual_prio
= this->config
->get_manual_prio(this->config
);
1685 del_outbound
= (this->outbound_state
& CHILD_OUTBOUND_POLICIES
) ||
1688 /* delete all policies in the kernel */
1689 enumerator
= create_policy_enumerator(this);
1690 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1692 del_policies_internal(this, this->my_addr
,
1693 this->other_addr
, my_ts
, other_ts
, &my_sa
, &other_sa
,
1694 POLICY_IPSEC
, priority
, manual_prio
, del_outbound
);
1696 enumerator
->destroy(enumerator
);
1699 /* delete SAs in the kernel, if they are set up */
1702 kernel_ipsec_sa_id_t id
= {
1703 .src
= this->other_addr
,
1704 .dst
= this->my_addr
,
1705 .spi
= this->my_spi
,
1706 .proto
= proto_ike2ip(this->protocol
),
1707 .mark
= mark_in_sa(this),
1708 .if_id
= this->if_id_in
,
1710 kernel_ipsec_del_sa_t sa
= {
1711 .cpi
= this->my_cpi
,
1713 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1715 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
1717 kernel_ipsec_sa_id_t id
= {
1718 .src
= this->my_addr
,
1719 .dst
= this->other_addr
,
1720 .spi
= this->other_spi
,
1721 .proto
= proto_ike2ip(this->protocol
),
1722 .mark
= this->mark_out
,
1723 .if_id
= this->if_id_out
,
1725 kernel_ipsec_del_sa_t sa
= {
1726 .cpi
= this->other_cpi
,
1728 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1731 if (this->reqid_allocated
)
1733 if (charon
->kernel
->release_reqid(charon
->kernel
,
1734 this->reqid
, this->mark_in
, this->mark_out
,
1735 this->if_id_in
, this->if_id_out
) != SUCCESS
)
1737 DBG1(DBG_CHD
, "releasing reqid %u failed", this->reqid
);
1741 array_destroy_offset(this->my_ts
, offsetof(traffic_selector_t
, destroy
));
1742 array_destroy_offset(this->other_ts
, offsetof(traffic_selector_t
, destroy
));
1743 this->my_addr
->destroy(this->my_addr
);
1744 this->other_addr
->destroy(this->other_addr
);
1745 DESTROY_IF(this->proposal
);
1746 this->config
->destroy(this->config
);
1747 chunk_clear(&this->encr_r
);
1748 chunk_clear(&this->integ_r
);
1753 * Get proxy address for one side, if any
1755 static host_t
* get_proxy_addr(child_cfg_t
*config
, host_t
*ike
, bool local
)
1757 host_t
*host
= NULL
;
1759 enumerator_t
*enumerator
;
1760 linked_list_t
*ts_list
, *list
;
1761 traffic_selector_t
*ts
;
1763 list
= linked_list_create_with_items(ike
, NULL
);
1764 ts_list
= config
->get_traffic_selectors(config
, local
, NULL
, list
, FALSE
);
1765 list
->destroy(list
);
1767 enumerator
= ts_list
->create_enumerator(ts_list
);
1768 while (enumerator
->enumerate(enumerator
, &ts
))
1770 if (ts
->is_host(ts
, NULL
) && ts
->to_subnet(ts
, &host
, &mask
))
1772 DBG1(DBG_CHD
, "%s address: %H is a transport mode proxy for %H",
1773 local
? "my" : "other", ike
, host
);
1777 enumerator
->destroy(enumerator
);
1778 ts_list
->destroy_offset(ts_list
, offsetof(traffic_selector_t
, destroy
));
1782 host
= ike
->clone(ike
);
1788 * Described in header.
1790 child_sa_t
* child_sa_create(host_t
*me
, host_t
* other
,
1791 child_cfg_t
*config
, uint32_t reqid
, bool encap
,
1792 uint32_t mark_in
, uint32_t mark_out
,
1793 uint32_t if_id_in
, uint32_t if_id_out
)
1795 private_child_sa_t
*this;
1796 static refcount_t unique_id
= 0, unique_mark
= 0, unique_if_id
= 0;
1800 .get_name
= _get_name
,
1801 .get_reqid
= _get_reqid
,
1802 .get_unique_id
= _get_unique_id
,
1803 .get_config
= _get_config
,
1804 .get_state
= _get_state
,
1805 .set_state
= _set_state
,
1806 .get_outbound_state
= _get_outbound_state
,
1807 .get_spi
= _get_spi
,
1808 .get_cpi
= _get_cpi
,
1809 .get_protocol
= _get_protocol
,
1810 .set_protocol
= _set_protocol
,
1811 .get_mode
= _get_mode
,
1812 .set_mode
= _set_mode
,
1813 .get_proposal
= _get_proposal
,
1814 .set_proposal
= _set_proposal
,
1815 .get_lifetime
= _get_lifetime
,
1816 .get_installtime
= _get_installtime
,
1817 .get_usestats
= _get_usestats
,
1818 .get_mark
= _get_mark
,
1819 .get_if_id
= _get_if_id
,
1820 .has_encap
= _has_encap
,
1821 .get_ipcomp
= _get_ipcomp
,
1822 .set_ipcomp
= _set_ipcomp
,
1823 .get_close_action
= _get_close_action
,
1824 .set_close_action
= _set_close_action
,
1825 .get_dpd_action
= _get_dpd_action
,
1826 .set_dpd_action
= _set_dpd_action
,
1827 .alloc_spi
= _alloc_spi
,
1828 .alloc_cpi
= _alloc_cpi
,
1829 .install
= _install
,
1830 .register_outbound
= _register_outbound
,
1831 .install_outbound
= _install_outbound
,
1832 .remove_outbound
= _remove_outbound
,
1833 .set_rekey_spi
= _set_rekey_spi
,
1834 .get_rekey_spi
= _get_rekey_spi
,
1836 .set_policies
= _set_policies
,
1837 .install_policies
= _install_policies
,
1838 .create_ts_enumerator
= _create_ts_enumerator
,
1839 .create_policy_enumerator
= _create_policy_enumerator
,
1840 .destroy
= _destroy
,
1843 .ipcomp
= IPCOMP_NONE
,
1844 .state
= CHILD_CREATED
,
1845 .my_ts
= array_create(0, 0),
1846 .other_ts
= array_create(0, 0),
1847 .protocol
= PROTO_NONE
,
1848 .mode
= MODE_TUNNEL
,
1849 .close_action
= config
->get_close_action(config
),
1850 .dpd_action
= config
->get_dpd_action(config
),
1851 .reqid
= config
->get_reqid(config
),
1852 .unique_id
= ref_get(&unique_id
),
1853 .mark_in
= config
->get_mark(config
, TRUE
),
1854 .mark_out
= config
->get_mark(config
, FALSE
),
1855 .if_id_in
= config
->get_if_id(config
, TRUE
),
1856 .if_id_out
= config
->get_if_id(config
, FALSE
),
1857 .install_time
= time_monotonic(NULL
),
1858 .policies_fwd_out
= config
->has_option(config
, OPT_FWD_OUT_POLICIES
),
1861 this->config
= config
;
1862 config
->get_ref(config
);
1866 this->mark_in
.value
= mark_in
;
1870 this->mark_out
.value
= mark_out
;
1874 this->if_id_in
= if_id_in
;
1878 this->if_id_out
= if_id_out
;
1881 if (MARK_IS_UNIQUE(this->mark_in
.value
) ||
1882 MARK_IS_UNIQUE(this->mark_out
.value
))
1884 refcount_t mark
= 0;
1885 bool unique_dir
= this->mark_in
.value
== MARK_UNIQUE_DIR
||
1886 this->mark_out
.value
== MARK_UNIQUE_DIR
;
1890 mark
= ref_get(&unique_mark
);
1892 if (MARK_IS_UNIQUE(this->mark_in
.value
))
1894 this->mark_in
.value
= unique_dir
? ref_get(&unique_mark
) : mark
;
1896 if (MARK_IS_UNIQUE(this->mark_out
.value
))
1898 this->mark_out
.value
= unique_dir
? ref_get(&unique_mark
) : mark
;
1902 if (IF_ID_IS_UNIQUE(this->if_id_in
) ||
1903 IF_ID_IS_UNIQUE(this->if_id_out
))
1905 refcount_t if_id
= 0;
1906 bool unique_dir
= this->if_id_in
== IF_ID_UNIQUE_DIR
||
1907 this->if_id_out
== IF_ID_UNIQUE_DIR
;
1911 if_id
= ref_get(&unique_if_id
);
1913 if (IF_ID_IS_UNIQUE(this->if_id_in
))
1915 this->if_id_in
= unique_dir
? ref_get(&unique_if_id
) : if_id
;
1917 if (IF_ID_IS_UNIQUE(this->if_id_out
))
1919 this->if_id_out
= unique_dir
? ref_get(&unique_if_id
) : if_id
;
1925 /* reuse old reqid if we are rekeying an existing CHILD_SA and when
1926 * initiating a trap policy. While the reqid cache would find the same
1927 * reqid for our selectors, this does not work in a special case: If an
1928 * SA is triggered by a trap policy, but the negotiated TS get
1929 * narrowed, we still must reuse the same reqid to successfully
1930 * replace the temporary SA on the kernel level. Rekeying such an SA
1931 * requires an explicit reqid, as the cache currently knows the original
1932 * selectors only for that reqid. */
1933 this->reqid
= reqid
;
1937 this->static_reqid
= TRUE
;
1940 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1941 if (config
->get_mode(config
) == MODE_TRANSPORT
&&
1942 config
->has_option(config
, OPT_PROXY_MODE
))
1944 this->mode
= MODE_TRANSPORT
;
1946 this->my_addr
= get_proxy_addr(config
, me
, TRUE
);
1947 this->other_addr
= get_proxy_addr(config
, other
, FALSE
);
1951 this->my_addr
= me
->clone(me
);
1952 this->other_addr
= other
->clone(other
);
1954 return &this->public;