2 * Copyright (C) 2006-2018 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
,
43 ENUM_FLAGS(child_sa_outbound_state_names
, CHILD_OUTBOUND_REGISTERED
, CHILD_OUTBOUND_POLICIES
,
49 typedef struct private_child_sa_t private_child_sa_t
;
52 * Private data of a child_sa_t object.
54 struct private_child_sa_t
{
56 * Public interface of child_sa_t.
71 * our actually used SPI, 0 if unused
76 * others used SPI, 0 if unused
81 * our Compression Parameter Index (CPI) used, 0 if unused
86 * others Compression Parameter Index (CPI) used, 0 if unused
91 * Array for local traffic selectors
96 * Array for remote traffic selectors
101 * Outbound encryption key cached during a rekeying
106 * Outbound integrity key cached during a rekeying
111 * Whether the outbound SA has only been registered yet during a rekeying
113 child_sa_outbound_state_t outbound_state
;
116 * Whether the peer supports TFCv3
121 * The outbound SPI of the CHILD_SA that replaced this one during a rekeying
126 * Protocol used to protect this SA, ESP|AH
128 protocol_id_t protocol
;
131 * reqid used for this child_sa
136 * Did we allocate/confirm and must release the reqid?
138 bool reqid_allocated
;
141 * Is the reqid statically configured
146 * Unique CHILD_SA identifier
151 * Whether FWD policieis in the outbound direction should be installed
153 bool policies_fwd_out
;
156 * inbound mark used for this child_sa
161 * outbound mark used for this child_sa
166 * absolute time when rekeying is scheduled
171 * absolute time when the SA expires
176 * absolute time when SA has been installed
181 * state of the CHILD_SA
183 child_sa_state_t state
;
186 * TRUE if this CHILD_SA is used to install trap policies
191 * Specifies if UDP encapsulation is enabled (NAT traversal)
196 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
198 ipcomp_transform_t ipcomp
;
201 * mode this SA uses, tunnel/transport
206 * Action to enforce if peer closes the CHILD_SA
208 action_t close_action
;
211 * Action to enforce if peer is considered dead
218 proposal_t
*proposal
;
221 * config used to create this child
226 * time of last use in seconds (inbound)
231 * time of last use in seconds (outbound)
233 time_t other_usetime
;
236 * last number of inbound bytes
238 uint64_t my_usebytes
;
241 * last number of outbound bytes
243 uint64_t other_usebytes
;
246 * last number of inbound packets
248 uint64_t my_usepackets
;
251 * last number of outbound bytes
253 uint64_t other_usepackets
;
257 * Convert an IKEv2 specific protocol identifier to the IP protocol identifier
259 static inline uint8_t proto_ike2ip(protocol_id_t protocol
)
273 * Returns the mark to use on the inbound SA
275 static inline mark_t
mark_in_sa(private_child_sa_t
*this)
277 if (this->config
->has_option(this->config
, OPT_MARK_IN_SA
))
279 return this->mark_in
;
284 METHOD(child_sa_t
, get_name
, char*,
285 private_child_sa_t
*this)
287 return this->config
->get_name(this->config
);
290 METHOD(child_sa_t
, get_reqid
, uint32_t,
291 private_child_sa_t
*this)
296 METHOD(child_sa_t
, get_unique_id
, uint32_t,
297 private_child_sa_t
*this)
299 return this->unique_id
;
302 METHOD(child_sa_t
, get_config
, child_cfg_t
*,
303 private_child_sa_t
*this)
308 METHOD(child_sa_t
, set_state
, void,
309 private_child_sa_t
*this, child_sa_state_t state
)
311 if (this->state
!= state
)
313 DBG2(DBG_CHD
, "CHILD_SA %s{%d} state change: %N => %N",
314 get_name(this), this->unique_id
,
315 child_sa_state_names
, this->state
,
316 child_sa_state_names
, state
);
317 charon
->bus
->child_state_change(charon
->bus
, &this->public, state
);
322 METHOD(child_sa_t
, get_state
, child_sa_state_t
,
323 private_child_sa_t
*this)
328 METHOD(child_sa_t
, get_outbound_state
, child_sa_outbound_state_t
,
329 private_child_sa_t
*this)
331 return this->outbound_state
;
334 METHOD(child_sa_t
, get_spi
, uint32_t,
335 private_child_sa_t
*this, bool inbound
)
337 return inbound
? this->my_spi
: this->other_spi
;
340 METHOD(child_sa_t
, get_cpi
, uint16_t,
341 private_child_sa_t
*this, bool inbound
)
343 return inbound
? this->my_cpi
: this->other_cpi
;
346 METHOD(child_sa_t
, get_protocol
, protocol_id_t
,
347 private_child_sa_t
*this)
349 return this->protocol
;
352 METHOD(child_sa_t
, set_protocol
, void,
353 private_child_sa_t
*this, protocol_id_t protocol
)
355 this->protocol
= protocol
;
358 METHOD(child_sa_t
, get_mode
, ipsec_mode_t
,
359 private_child_sa_t
*this)
364 METHOD(child_sa_t
, set_mode
, void,
365 private_child_sa_t
*this, ipsec_mode_t mode
)
370 METHOD(child_sa_t
, has_encap
, bool,
371 private_child_sa_t
*this)
376 METHOD(child_sa_t
, get_ipcomp
, ipcomp_transform_t
,
377 private_child_sa_t
*this)
382 METHOD(child_sa_t
, set_ipcomp
, void,
383 private_child_sa_t
*this, ipcomp_transform_t ipcomp
)
385 this->ipcomp
= ipcomp
;
388 METHOD(child_sa_t
, set_close_action
, void,
389 private_child_sa_t
*this, action_t action
)
391 this->close_action
= action
;
394 METHOD(child_sa_t
, get_close_action
, action_t
,
395 private_child_sa_t
*this)
397 return this->close_action
;
400 METHOD(child_sa_t
, set_dpd_action
, void,
401 private_child_sa_t
*this, action_t action
)
403 this->dpd_action
= action
;
406 METHOD(child_sa_t
, get_dpd_action
, action_t
,
407 private_child_sa_t
*this)
409 return this->dpd_action
;
412 METHOD(child_sa_t
, get_proposal
, proposal_t
*,
413 private_child_sa_t
*this)
415 return this->proposal
;
418 METHOD(child_sa_t
, set_proposal
, void,
419 private_child_sa_t
*this, proposal_t
*proposal
)
421 this->proposal
= proposal
->clone(proposal
);
424 METHOD(child_sa_t
, create_ts_enumerator
, enumerator_t
*,
425 private_child_sa_t
*this, bool local
)
429 return array_create_enumerator(this->my_ts
);
431 return array_create_enumerator(this->other_ts
);
434 typedef struct policy_enumerator_t policy_enumerator_t
;
437 * Private policy enumerator
439 struct policy_enumerator_t
{
440 /** implements enumerator_t */
442 /** enumerator over own TS */
444 /** enumerator over others TS */
446 /** array of others TS, to recreate enumerator */
448 /** currently enumerating TS for "me" side */
449 traffic_selector_t
*ts
;
452 METHOD(enumerator_t
, policy_enumerate
, bool,
453 policy_enumerator_t
*this, va_list args
)
455 traffic_selector_t
*other_ts
, **my_out
, **other_out
;
457 VA_ARGS_VGET(args
, my_out
, other_out
);
459 while (this->ts
|| this->mine
->enumerate(this->mine
, &this->ts
))
461 if (!this->other
->enumerate(this->other
, &other_ts
))
462 { /* end of others list, restart with new of mine */
463 this->other
->destroy(this->other
);
464 this->other
= array_create_enumerator(this->array
);
468 if (this->ts
->get_type(this->ts
) != other_ts
->get_type(other_ts
))
469 { /* family mismatch */
472 if (this->ts
->get_protocol(this->ts
) &&
473 other_ts
->get_protocol(other_ts
) &&
474 this->ts
->get_protocol(this->ts
) != other_ts
->get_protocol(other_ts
))
475 { /* protocol mismatch */
484 *other_out
= other_ts
;
491 METHOD(enumerator_t
, policy_destroy
, void,
492 policy_enumerator_t
*this)
494 this->mine
->destroy(this->mine
);
495 this->other
->destroy(this->other
);
499 METHOD(child_sa_t
, create_policy_enumerator
, enumerator_t
*,
500 private_child_sa_t
*this)
502 policy_enumerator_t
*e
;
506 .enumerate
= enumerator_enumerate_default
,
507 .venumerate
= _policy_enumerate
,
508 .destroy
= _policy_destroy
,
510 .mine
= array_create_enumerator(this->my_ts
),
511 .other
= array_create_enumerator(this->other_ts
),
512 .array
= this->other_ts
,
520 * update the cached usebytes
521 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
522 * are available, and NOT_SUPPORTED if the kernel interface does not support
523 * querying the usebytes.
525 static status_t
update_usebytes(private_child_sa_t
*this, bool inbound
)
527 status_t status
= FAILED
;
528 uint64_t bytes
, packets
;
535 kernel_ipsec_sa_id_t id
= {
536 .src
= this->other_addr
,
537 .dst
= this->my_addr
,
539 .proto
= proto_ike2ip(this->protocol
),
540 .mark
= mark_in_sa(this),
542 kernel_ipsec_query_sa_t query
= {};
544 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
545 &bytes
, &packets
, &time
);
546 if (status
== SUCCESS
)
548 if (bytes
> this->my_usebytes
)
550 this->my_usebytes
= bytes
;
551 this->my_usepackets
= packets
;
554 this->my_usetime
= time
;
566 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
568 kernel_ipsec_sa_id_t id
= {
569 .src
= this->my_addr
,
570 .dst
= this->other_addr
,
571 .spi
= this->other_spi
,
572 .proto
= proto_ike2ip(this->protocol
),
573 .mark
= this->mark_out
,
575 kernel_ipsec_query_sa_t query
= {};
577 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
578 &bytes
, &packets
, &time
);
579 if (status
== SUCCESS
)
581 if (bytes
> this->other_usebytes
)
583 this->other_usebytes
= bytes
;
584 this->other_usepackets
= packets
;
587 this->other_usetime
= time
;
601 * updates the cached usetime
603 static bool update_usetime(private_child_sa_t
*this, bool inbound
)
605 enumerator_t
*enumerator
;
606 traffic_selector_t
*my_ts
, *other_ts
;
609 enumerator
= create_policy_enumerator(this);
610 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
616 kernel_ipsec_policy_id_t id
= {
620 .mark
= this->mark_in
,
622 kernel_ipsec_query_policy_t query
= {};
624 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
627 last_use
= max(last_use
, in
);
629 if (this->mode
!= MODE_TRANSPORT
)
632 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
635 last_use
= max(last_use
, fwd
);
641 kernel_ipsec_policy_id_t id
= {
645 .mark
= this->mark_out
,
646 .interface
= this->config
->get_interface(this->config
),
648 kernel_ipsec_query_policy_t query
= {};
650 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
653 last_use
= max(last_use
, out
);
657 enumerator
->destroy(enumerator
);
665 this->my_usetime
= last_use
;
669 this->other_usetime
= last_use
;
674 METHOD(child_sa_t
, get_usestats
, void,
675 private_child_sa_t
*this, bool inbound
,
676 time_t *time
, uint64_t *bytes
, uint64_t *packets
)
678 if ((!bytes
&& !packets
) || update_usebytes(this, inbound
) != FAILED
)
680 /* there was traffic since last update or the kernel interface
681 * does not support querying the number of usebytes.
685 if (!update_usetime(this, inbound
) && !bytes
&& !packets
)
687 /* if policy query did not yield a usetime, query SAs instead */
688 update_usebytes(this, inbound
);
694 *time
= inbound
? this->my_usetime
: this->other_usetime
;
698 *bytes
= inbound
? this->my_usebytes
: this->other_usebytes
;
702 *packets
= inbound
? this->my_usepackets
: this->other_usepackets
;
706 METHOD(child_sa_t
, get_mark
, mark_t
,
707 private_child_sa_t
*this, bool inbound
)
711 return this->mark_in
;
713 return this->mark_out
;
716 METHOD(child_sa_t
, get_lifetime
, time_t,
717 private_child_sa_t
*this, bool hard
)
719 return hard
? this->expire_time
: this->rekey_time
;
722 METHOD(child_sa_t
, get_installtime
, time_t,
723 private_child_sa_t
*this)
725 return this->install_time
;
728 METHOD(child_sa_t
, alloc_spi
, uint32_t,
729 private_child_sa_t
*this, protocol_id_t protocol
)
731 if (charon
->kernel
->get_spi(charon
->kernel
, this->other_addr
, this->my_addr
,
732 proto_ike2ip(protocol
), &this->my_spi
) == SUCCESS
)
734 /* if we allocate a SPI, but then are unable to establish the SA, we
735 * need to know the protocol family to delete the partial SA */
736 this->protocol
= protocol
;
742 METHOD(child_sa_t
, alloc_cpi
, uint16_t,
743 private_child_sa_t
*this)
745 if (charon
->kernel
->get_cpi(charon
->kernel
, this->other_addr
, this->my_addr
,
746 &this->my_cpi
) == SUCCESS
)
754 * Install the given SA in the kernel
756 static status_t
install_internal(private_child_sa_t
*this, chunk_t encr
,
757 chunk_t integ
, uint32_t spi
, uint16_t cpi
, bool initiator
, bool inbound
,
760 uint16_t enc_alg
= ENCR_UNDEFINED
, int_alg
= AUTH_UNDEFINED
, size
;
761 uint16_t esn
= NO_EXT_SEQ_NUMBERS
;
762 linked_list_t
*my_ts
, *other_ts
, *src_ts
, *dst_ts
;
764 kernel_ipsec_sa_id_t id
;
765 kernel_ipsec_add_sa_t sa
;
766 lifetime_cfg_t
*lifetime
;
772 /* BEET requires the bound address from the traffic selectors */
773 my_ts
= linked_list_create_from_enumerator(
774 array_create_enumerator(this->my_ts
));
775 other_ts
= linked_list_create_from_enumerator(
776 array_create_enumerator(this->other_ts
));
778 /* now we have to decide which spi to use. Use self allocated, if "in",
779 * or the one in the proposal, if not "in" (others). Additionally,
780 * source and dest host switch depending on the role */
784 src
= this->other_addr
;
785 if (this->my_spi
== spi
)
786 { /* alloc_spi has been called, do an SA update */
797 dst
= this->other_addr
;
798 this->other_spi
= spi
;
799 this->other_cpi
= cpi
;
805 tfc
= this->config
->get_tfc(this->config
);
807 this->outbound_state
|= CHILD_OUTBOUND_SA
;
810 DBG2(DBG_CHD
, "adding %s %N SA", inbound
? "inbound" : "outbound",
811 protocol_id_names
, this->protocol
);
813 /* send SA down to the kernel */
814 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), src
, dst
);
816 this->proposal
->get_algorithm(this->proposal
, ENCRYPTION_ALGORITHM
,
818 this->proposal
->get_algorithm(this->proposal
, INTEGRITY_ALGORITHM
,
820 this->proposal
->get_algorithm(this->proposal
, EXTENDED_SEQUENCE_NUMBERS
,
823 if (int_alg
== AUTH_HMAC_SHA2_256_128
&&
824 this->config
->has_option(this->config
, OPT_SHA256_96
))
826 DBG2(DBG_CHD
, " using %N with 96-bit truncation",
827 integrity_algorithm_names
, int_alg
);
828 int_alg
= AUTH_HMAC_SHA2_256_96
;
831 if (!this->reqid_allocated
&& !this->static_reqid
)
833 status
= charon
->kernel
->alloc_reqid(charon
->kernel
, my_ts
, other_ts
,
834 this->mark_in
, this->mark_out
, &this->reqid
);
835 if (status
!= SUCCESS
)
837 my_ts
->destroy(my_ts
);
838 other_ts
->destroy(other_ts
);
841 this->reqid_allocated
= TRUE
;
844 lifetime
= this->config
->get_lifetime(this->config
, TRUE
);
846 now
= time_monotonic(NULL
);
847 if (lifetime
->time
.rekey
)
849 if (this->rekey_time
)
851 this->rekey_time
= min(this->rekey_time
, now
+ lifetime
->time
.rekey
);
855 this->rekey_time
= now
+ lifetime
->time
.rekey
;
858 if (lifetime
->time
.life
)
860 this->expire_time
= now
+ lifetime
->time
.life
;
863 if (!lifetime
->time
.jitter
&& !inbound
)
864 { /* avoid triggering multiple rekey events */
865 lifetime
->time
.rekey
= 0;
868 id
= (kernel_ipsec_sa_id_t
){
872 .proto
= proto_ike2ip(this->protocol
),
873 .mark
= inbound
? mark_in_sa(this) : this->mark_out
,
875 sa
= (kernel_ipsec_add_sa_t
){
876 .reqid
= this->reqid
,
880 .interface
= inbound
? NULL
: this->config
->get_interface(this->config
),
881 .lifetime
= lifetime
,
886 .replay_window
= this->config
->get_replay_window(this->config
),
888 .ipcomp
= this->ipcomp
,
890 .encap
= this->encap
,
891 .hw_offload
= this->config
->has_option(this->config
, OPT_HW_OFFLOAD
),
893 .initiator
= initiator
,
898 status
= charon
->kernel
->add_sa(charon
->kernel
, &id
, &sa
);
900 my_ts
->destroy(my_ts
);
901 other_ts
->destroy(other_ts
);
907 METHOD(child_sa_t
, install
, status_t
,
908 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
909 uint16_t cpi
, bool initiator
, bool inbound
, bool tfcv3
)
911 return install_internal(this, encr
, integ
, spi
, cpi
, initiator
, inbound
,
916 * Check kernel interface if policy updates are required
918 static bool require_policy_update()
922 f
= charon
->kernel
->get_features(charon
->kernel
);
923 return !(f
& KERNEL_NO_POLICY_UPDATES
);
927 * Prepare SA config to install/delete policies
929 static void prepare_sa_cfg(private_child_sa_t
*this, ipsec_sa_cfg_t
*my_sa
,
930 ipsec_sa_cfg_t
*other_sa
)
932 enumerator_t
*enumerator
;
934 *my_sa
= (ipsec_sa_cfg_t
){
936 .reqid
= this->reqid
,
938 .transform
= this->ipcomp
,
943 my_sa
->ipcomp
.cpi
= this->my_cpi
;
944 other_sa
->ipcomp
.cpi
= this->other_cpi
;
946 if (this->protocol
== PROTO_ESP
)
948 my_sa
->esp
.use
= TRUE
;
949 my_sa
->esp
.spi
= this->my_spi
;
950 other_sa
->esp
.use
= TRUE
;
951 other_sa
->esp
.spi
= this->other_spi
;
955 my_sa
->ah
.use
= TRUE
;
956 my_sa
->ah
.spi
= this->my_spi
;
957 other_sa
->ah
.use
= TRUE
;
958 other_sa
->ah
.spi
= this->other_spi
;
961 enumerator
= create_policy_enumerator(this);
962 while (enumerator
->enumerate(enumerator
, NULL
, NULL
))
964 my_sa
->policy_count
++;
965 other_sa
->policy_count
++;
967 enumerator
->destroy(enumerator
);
971 * Install inbound policie(s): in, fwd
973 static status_t
install_policies_inbound(private_child_sa_t
*this,
974 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
975 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
976 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
977 policy_priority_t priority
, uint32_t manual_prio
)
979 kernel_ipsec_policy_id_t in_id
= {
983 .mark
= this->mark_in
,
985 kernel_ipsec_manage_policy_t in_policy
= {
988 .manual_prio
= manual_prio
,
993 status_t status
= SUCCESS
;
995 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
996 if (this->mode
!= MODE_TRANSPORT
)
998 in_id
.dir
= POLICY_FWD
;
999 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
1005 * Install outbound policie(s): out, [fwd]
1007 static status_t
install_policies_outbound(private_child_sa_t
*this,
1008 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1009 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1010 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1011 policy_priority_t priority
, uint32_t manual_prio
)
1013 kernel_ipsec_policy_id_t out_id
= {
1017 .mark
= this->mark_out
,
1018 .interface
= this->config
->get_interface(this->config
),
1020 kernel_ipsec_manage_policy_t out_policy
= {
1023 .manual_prio
= manual_prio
,
1028 status_t status
= SUCCESS
;
1030 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
, &out_policy
);
1032 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1034 /* install an "outbound" FWD policy in case there is a drop policy
1035 * matching outbound forwarded traffic, to allow another tunnel to use
1036 * the reversed subnets and do the same we don't set a reqid (this also
1037 * allows the kernel backend to distinguish between the two types of
1038 * FWD policies). To avoid problems with symmetrically overlapping
1039 * policies of two SAs we install them with reduced priority. As they
1040 * basically act as bypass policies for drop policies we use a higher
1041 * priority than is used for them. */
1042 out_id
.dir
= POLICY_FWD
;
1043 other_sa
->reqid
= 0;
1044 if (priority
== POLICY_PRIORITY_DEFAULT
)
1046 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1048 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
,
1050 /* reset the reqid for any other further policies */
1051 other_sa
->reqid
= this->reqid
;
1057 * Install all policies
1059 static status_t
install_policies_internal(private_child_sa_t
*this,
1060 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1061 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1062 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1063 policy_priority_t priority
, uint32_t manual_prio
)
1065 status_t status
= SUCCESS
;
1067 status
|= install_policies_inbound(this, my_addr
, other_addr
, my_ts
,
1068 other_ts
, my_sa
, other_sa
, type
,
1069 priority
, manual_prio
);
1070 status
|= install_policies_outbound(this, my_addr
, other_addr
, my_ts
,
1071 other_ts
, my_sa
, other_sa
, type
,
1072 priority
, manual_prio
);
1077 * Delete inbound policies: in, fwd
1079 static void del_policies_inbound(private_child_sa_t
*this,
1080 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1081 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1082 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1083 policy_priority_t priority
, uint32_t manual_prio
)
1085 kernel_ipsec_policy_id_t in_id
= {
1089 .mark
= this->mark_in
,
1091 kernel_ipsec_manage_policy_t in_policy
= {
1094 .manual_prio
= manual_prio
,
1100 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1102 if (this->mode
!= MODE_TRANSPORT
)
1104 in_id
.dir
= POLICY_FWD
;
1105 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1110 * Delete outbound policies: out, [fwd]
1112 static void del_policies_outbound(private_child_sa_t
*this,
1113 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1114 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1115 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1116 policy_priority_t priority
, uint32_t manual_prio
)
1118 kernel_ipsec_policy_id_t out_id
= {
1122 .mark
= this->mark_out
,
1123 .interface
= this->config
->get_interface(this->config
),
1125 kernel_ipsec_manage_policy_t out_policy
= {
1128 .manual_prio
= manual_prio
,
1134 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1136 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1138 out_id
.dir
= POLICY_FWD
;
1139 other_sa
->reqid
= 0;
1140 if (priority
== POLICY_PRIORITY_DEFAULT
)
1142 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1144 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1145 other_sa
->reqid
= this->reqid
;
1150 * Delete in- and outbound policies
1152 static void del_policies_internal(private_child_sa_t
*this,
1153 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1154 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1155 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1156 policy_priority_t priority
, uint32_t manual_prio
)
1158 del_policies_outbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1159 other_sa
, type
, priority
, manual_prio
);
1160 del_policies_inbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1161 other_sa
, type
, priority
, manual_prio
);
1164 METHOD(child_sa_t
, set_policies
, void,
1165 private_child_sa_t
*this, linked_list_t
*my_ts_list
,
1166 linked_list_t
*other_ts_list
)
1168 enumerator_t
*enumerator
;
1169 traffic_selector_t
*my_ts
, *other_ts
;
1171 if (array_count(this->my_ts
))
1173 array_destroy_offset(this->my_ts
,
1174 offsetof(traffic_selector_t
, destroy
));
1175 this->my_ts
= array_create(0, 0);
1177 enumerator
= my_ts_list
->create_enumerator(my_ts_list
);
1178 while (enumerator
->enumerate(enumerator
, &my_ts
))
1180 array_insert(this->my_ts
, ARRAY_TAIL
, my_ts
->clone(my_ts
));
1182 enumerator
->destroy(enumerator
);
1183 array_sort(this->my_ts
, (void*)traffic_selector_cmp
, NULL
);
1185 if (array_count(this->other_ts
))
1187 array_destroy_offset(this->other_ts
,
1188 offsetof(traffic_selector_t
, destroy
));
1189 this->other_ts
= array_create(0, 0);
1191 enumerator
= other_ts_list
->create_enumerator(other_ts_list
);
1192 while (enumerator
->enumerate(enumerator
, &other_ts
))
1194 array_insert(this->other_ts
, ARRAY_TAIL
, other_ts
->clone(other_ts
));
1196 enumerator
->destroy(enumerator
);
1197 array_sort(this->other_ts
, (void*)traffic_selector_cmp
, NULL
);
1200 METHOD(child_sa_t
, install_policies
, status_t
,
1201 private_child_sa_t
*this)
1203 enumerator_t
*enumerator
;
1204 linked_list_t
*my_ts_list
, *other_ts_list
;
1205 traffic_selector_t
*my_ts
, *other_ts
;
1206 status_t status
= SUCCESS
;
1207 bool install_outbound
= FALSE
;
1209 if (!this->reqid_allocated
&& !this->static_reqid
)
1211 my_ts_list
= linked_list_create_from_enumerator(
1212 array_create_enumerator(this->my_ts
));
1213 other_ts_list
= linked_list_create_from_enumerator(
1214 array_create_enumerator(this->other_ts
));
1215 status
= charon
->kernel
->alloc_reqid(
1216 charon
->kernel
, my_ts_list
, other_ts_list
,
1217 this->mark_in
, this->mark_out
, &this->reqid
);
1218 my_ts_list
->destroy(my_ts_list
);
1219 other_ts_list
->destroy(other_ts_list
);
1220 if (status
!= SUCCESS
)
1224 this->reqid_allocated
= TRUE
;
1227 if (!(this->outbound_state
& CHILD_OUTBOUND_REGISTERED
))
1229 install_outbound
= TRUE
;
1230 this->outbound_state
|= CHILD_OUTBOUND_POLICIES
;
1233 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1235 policy_priority_t priority
;
1236 ipsec_sa_cfg_t my_sa
, other_sa
;
1237 uint32_t manual_prio
;
1239 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1240 manual_prio
= this->config
->get_manual_prio(this->config
);
1242 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1243 * entry) we install a trap policy */
1244 this->trap
= this->state
== CHILD_CREATED
;
1245 priority
= this->trap
? POLICY_PRIORITY_ROUTED
1246 : POLICY_PRIORITY_DEFAULT
;
1248 /* enumerate pairs of traffic selectors */
1249 enumerator
= create_policy_enumerator(this);
1250 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1252 status
|= install_policies_inbound(this, this->my_addr
,
1253 this->other_addr
, my_ts
, other_ts
,
1254 &my_sa
, &other_sa
, POLICY_IPSEC
,
1255 priority
, manual_prio
);
1257 if (install_outbound
)
1259 status
|= install_policies_outbound(this, this->my_addr
,
1260 this->other_addr
, my_ts
, other_ts
,
1261 &my_sa
, &other_sa
, POLICY_IPSEC
,
1262 priority
, manual_prio
);
1264 if (status
!= SUCCESS
)
1269 enumerator
->destroy(enumerator
);
1272 if (status
== SUCCESS
&& this->trap
)
1274 set_state(this, CHILD_ROUTED
);
1279 METHOD(child_sa_t
, register_outbound
, status_t
,
1280 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
1281 uint16_t cpi
, bool tfcv3
)
1285 /* if the kernel supports installing SPIs with policies we install the
1286 * SA immediately as it will only be used once we update the policies */
1287 if (charon
->kernel
->get_features(charon
->kernel
) & KERNEL_POLICY_SPI
)
1289 status
= install_internal(this, encr
, integ
, spi
, cpi
, FALSE
, FALSE
,
1294 DBG2(DBG_CHD
, "registering outbound %N SA", protocol_id_names
,
1296 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), this->my_addr
,
1299 this->other_spi
= spi
;
1300 this->other_cpi
= cpi
;
1301 this->encr_r
= chunk_clone(encr
);
1302 this->integ_r
= chunk_clone(integ
);
1303 this->tfcv3
= tfcv3
;
1306 this->outbound_state
|= CHILD_OUTBOUND_REGISTERED
;
1310 METHOD(child_sa_t
, install_outbound
, status_t
,
1311 private_child_sa_t
*this)
1313 enumerator_t
*enumerator
;
1314 traffic_selector_t
*my_ts
, *other_ts
;
1315 status_t status
= SUCCESS
;
1317 if (!(this->outbound_state
& CHILD_OUTBOUND_SA
))
1319 status
= install_internal(this, this->encr_r
, this->integ_r
,
1320 this->other_spi
, this->other_cpi
, FALSE
,
1321 FALSE
, this->tfcv3
);
1322 chunk_clear(&this->encr_r
);
1323 chunk_clear(&this->integ_r
);
1325 this->outbound_state
&= ~CHILD_OUTBOUND_REGISTERED
;
1326 if (status
!= SUCCESS
)
1330 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1331 !(this->outbound_state
& CHILD_OUTBOUND_POLICIES
))
1333 ipsec_sa_cfg_t my_sa
, other_sa
;
1334 uint32_t manual_prio
;
1336 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1337 manual_prio
= this->config
->get_manual_prio(this->config
);
1339 enumerator
= create_policy_enumerator(this);
1340 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1342 status
|= install_policies_outbound(this, this->my_addr
,
1343 this->other_addr
, my_ts
, other_ts
,
1344 &my_sa
, &other_sa
, POLICY_IPSEC
,
1345 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1346 if (status
!= SUCCESS
)
1351 enumerator
->destroy(enumerator
);
1353 this->outbound_state
|= CHILD_OUTBOUND_POLICIES
;
1357 METHOD(child_sa_t
, remove_outbound
, void,
1358 private_child_sa_t
*this)
1360 enumerator_t
*enumerator
;
1361 traffic_selector_t
*my_ts
, *other_ts
;
1363 if (!(this->outbound_state
& CHILD_OUTBOUND_SA
))
1365 if (this->outbound_state
& CHILD_OUTBOUND_REGISTERED
)
1367 chunk_clear(&this->encr_r
);
1368 chunk_clear(&this->integ_r
);
1369 this->outbound_state
= CHILD_OUTBOUND_NONE
;
1374 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1375 (this->outbound_state
& CHILD_OUTBOUND_POLICIES
))
1377 ipsec_sa_cfg_t my_sa
, other_sa
;
1378 uint32_t manual_prio
;
1380 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1381 manual_prio
= this->config
->get_manual_prio(this->config
);
1383 enumerator
= create_policy_enumerator(this);
1384 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1386 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1387 my_ts
, other_ts
, &my_sa
, &other_sa
,
1388 POLICY_IPSEC
, POLICY_PRIORITY_DEFAULT
,
1391 enumerator
->destroy(enumerator
);
1394 kernel_ipsec_sa_id_t id
= {
1395 .src
= this->my_addr
,
1396 .dst
= this->other_addr
,
1397 .spi
= this->other_spi
,
1398 .proto
= proto_ike2ip(this->protocol
),
1399 .mark
= this->mark_out
,
1401 kernel_ipsec_del_sa_t sa
= {
1402 .cpi
= this->other_cpi
,
1404 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1405 this->outbound_state
= CHILD_OUTBOUND_NONE
;
1408 METHOD(child_sa_t
, set_rekey_spi
, void,
1409 private_child_sa_t
*this, uint32_t spi
)
1411 this->rekey_spi
= spi
;
1414 METHOD(child_sa_t
, get_rekey_spi
, uint32_t,
1415 private_child_sa_t
*this)
1417 return this->rekey_spi
;
1420 CALLBACK(reinstall_vip
, void,
1421 host_t
*vip
, va_list args
)
1426 VA_ARGS_VGET(args
, me
);
1427 if (charon
->kernel
->get_interface(charon
->kernel
, me
, &iface
))
1429 charon
->kernel
->del_ip(charon
->kernel
, vip
, -1, TRUE
);
1430 charon
->kernel
->add_ip(charon
->kernel
, vip
, -1, iface
);
1436 * Update addresses and encap state of IPsec SAs in the kernel
1438 static status_t
update_sas(private_child_sa_t
*this, host_t
*me
, host_t
*other
,
1441 /* update our (initiator) SA */
1444 kernel_ipsec_sa_id_t id
= {
1445 .src
= this->other_addr
,
1446 .dst
= this->my_addr
,
1447 .spi
= this->my_spi
,
1448 .proto
= proto_ike2ip(this->protocol
),
1449 .mark
= mark_in_sa(this),
1451 kernel_ipsec_update_sa_t sa
= {
1452 .cpi
= this->ipcomp
!= IPCOMP_NONE
? this->my_cpi
: 0,
1455 .encap
= this->encap
,
1458 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1459 &sa
) == NOT_SUPPORTED
)
1461 return NOT_SUPPORTED
;
1465 /* update his (responder) SA */
1466 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
1468 kernel_ipsec_sa_id_t id
= {
1469 .src
= this->my_addr
,
1470 .dst
= this->other_addr
,
1471 .spi
= this->other_spi
,
1472 .proto
= proto_ike2ip(this->protocol
),
1473 .mark
= this->mark_out
,
1475 kernel_ipsec_update_sa_t sa
= {
1476 .cpi
= this->ipcomp
!= IPCOMP_NONE
? this->other_cpi
: 0,
1479 .encap
= this->encap
,
1482 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1483 &sa
) == NOT_SUPPORTED
)
1485 return NOT_SUPPORTED
;
1488 /* we currently ignore the actual return values above */
1492 METHOD(child_sa_t
, update
, status_t
,
1493 private_child_sa_t
*this, host_t
*me
, host_t
*other
, linked_list_t
*vips
,
1496 child_sa_state_t old
;
1497 bool transport_proxy_mode
;
1499 /* anything changed at all? */
1500 if (me
->equals(me
, this->my_addr
) &&
1501 other
->equals(other
, this->other_addr
) && this->encap
== encap
)
1507 set_state(this, CHILD_UPDATING
);
1508 transport_proxy_mode
= this->mode
== MODE_TRANSPORT
&&
1509 this->config
->has_option(this->config
,
1512 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1513 require_policy_update())
1515 ipsec_sa_cfg_t my_sa
, other_sa
;
1516 enumerator_t
*enumerator
;
1517 traffic_selector_t
*my_ts
, *other_ts
;
1518 uint32_t manual_prio
;
1521 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1522 manual_prio
= this->config
->get_manual_prio(this->config
);
1524 enumerator
= create_policy_enumerator(this);
1525 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1527 /* install drop policy to avoid traffic leaks, acquires etc. */
1528 install_policies_outbound(this, this->my_addr
, this->other_addr
,
1529 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_DROP
,
1530 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1532 /* remove old policies */
1533 del_policies_internal(this, this->my_addr
, this->other_addr
,
1534 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
,
1535 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1537 enumerator
->destroy(enumerator
);
1539 /* update the IPsec SAs */
1540 state
= update_sas(this, me
, other
, encap
);
1542 enumerator
= create_policy_enumerator(this);
1543 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1545 traffic_selector_t
*old_my_ts
= NULL
, *old_other_ts
= NULL
;
1547 /* reinstall the previous policies if we can't update the SAs */
1548 if (state
== NOT_SUPPORTED
)
1550 install_policies_internal(this, this->my_addr
, this->other_addr
,
1551 my_ts
, other_ts
, &my_sa
, &other_sa
,
1552 POLICY_IPSEC
, POLICY_PRIORITY_DEFAULT
, manual_prio
);
1556 /* check if we have to update a "dynamic" traffic selector */
1557 if (!me
->ip_equals(me
, this->my_addr
) &&
1558 my_ts
->is_host(my_ts
, this->my_addr
))
1560 old_my_ts
= my_ts
->clone(my_ts
);
1561 my_ts
->set_address(my_ts
, me
);
1563 if (!other
->ip_equals(other
, this->other_addr
) &&
1564 other_ts
->is_host(other_ts
, this->other_addr
))
1566 old_other_ts
= other_ts
->clone(other_ts
);
1567 other_ts
->set_address(other_ts
, other
);
1570 /* we reinstall the virtual IP to handle interface roaming
1572 vips
->invoke_function(vips
, reinstall_vip
, me
);
1574 /* reinstall updated policies */
1575 install_policies_internal(this, me
, other
, my_ts
, other_ts
,
1576 &my_sa
, &other_sa
, POLICY_IPSEC
,
1577 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1579 /* remove the drop policy */
1580 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1582 old_other_ts
?: other_ts
,
1583 &my_sa
, &other_sa
, POLICY_DROP
,
1584 POLICY_PRIORITY_DEFAULT
, 0);
1586 DESTROY_IF(old_my_ts
);
1587 DESTROY_IF(old_other_ts
);
1589 enumerator
->destroy(enumerator
);
1591 if (state
== NOT_SUPPORTED
)
1593 set_state(this, old
);
1594 return NOT_SUPPORTED
;
1598 else if (!transport_proxy_mode
)
1600 if (update_sas(this, me
, other
, encap
) == NOT_SUPPORTED
)
1602 set_state(this, old
);
1603 return NOT_SUPPORTED
;
1607 if (!transport_proxy_mode
)
1610 if (!me
->equals(me
, this->my_addr
))
1612 this->my_addr
->destroy(this->my_addr
);
1613 this->my_addr
= me
->clone(me
);
1615 if (!other
->equals(other
, this->other_addr
))
1617 this->other_addr
->destroy(this->other_addr
);
1618 this->other_addr
= other
->clone(other
);
1622 this->encap
= encap
;
1623 set_state(this, old
);
1628 METHOD(child_sa_t
, destroy
, void,
1629 private_child_sa_t
*this)
1631 enumerator_t
*enumerator
;
1632 traffic_selector_t
*my_ts
, *other_ts
;
1633 policy_priority_t priority
;
1635 priority
= this->trap
? POLICY_PRIORITY_ROUTED
: POLICY_PRIORITY_DEFAULT
;
1637 set_state(this, CHILD_DESTROYING
);
1639 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1641 ipsec_sa_cfg_t my_sa
, other_sa
;
1642 uint32_t manual_prio
;
1645 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1646 manual_prio
= this->config
->get_manual_prio(this->config
);
1647 del_outbound
= (this->outbound_state
& CHILD_OUTBOUND_POLICIES
) ||
1650 /* delete all policies in the kernel */
1651 enumerator
= create_policy_enumerator(this);
1652 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1656 del_policies_outbound(this, this->my_addr
,
1657 this->other_addr
, my_ts
, other_ts
,
1658 &my_sa
, &other_sa
, POLICY_IPSEC
,
1659 priority
, manual_prio
);
1661 del_policies_inbound(this, this->my_addr
, this->other_addr
,
1662 my_ts
, other_ts
, &my_sa
, &other_sa
,
1663 POLICY_IPSEC
, priority
, manual_prio
);
1665 enumerator
->destroy(enumerator
);
1668 /* delete SAs in the kernel, if they are set up */
1671 kernel_ipsec_sa_id_t id
= {
1672 .src
= this->other_addr
,
1673 .dst
= this->my_addr
,
1674 .spi
= this->my_spi
,
1675 .proto
= proto_ike2ip(this->protocol
),
1676 .mark
= mark_in_sa(this),
1678 kernel_ipsec_del_sa_t sa
= {
1679 .cpi
= this->my_cpi
,
1681 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1683 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
1685 kernel_ipsec_sa_id_t id
= {
1686 .src
= this->my_addr
,
1687 .dst
= this->other_addr
,
1688 .spi
= this->other_spi
,
1689 .proto
= proto_ike2ip(this->protocol
),
1690 .mark
= this->mark_out
,
1692 kernel_ipsec_del_sa_t sa
= {
1693 .cpi
= this->other_cpi
,
1695 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1698 if (this->reqid_allocated
)
1700 if (charon
->kernel
->release_reqid(charon
->kernel
,
1701 this->reqid
, this->mark_in
, this->mark_out
) != SUCCESS
)
1703 DBG1(DBG_CHD
, "releasing reqid %u failed", this->reqid
);
1707 array_destroy_offset(this->my_ts
, offsetof(traffic_selector_t
, destroy
));
1708 array_destroy_offset(this->other_ts
, offsetof(traffic_selector_t
, destroy
));
1709 this->my_addr
->destroy(this->my_addr
);
1710 this->other_addr
->destroy(this->other_addr
);
1711 DESTROY_IF(this->proposal
);
1712 this->config
->destroy(this->config
);
1713 chunk_clear(&this->encr_r
);
1714 chunk_clear(&this->integ_r
);
1719 * Get proxy address for one side, if any
1721 static host_t
* get_proxy_addr(child_cfg_t
*config
, host_t
*ike
, bool local
)
1723 host_t
*host
= NULL
;
1725 enumerator_t
*enumerator
;
1726 linked_list_t
*ts_list
, *list
;
1727 traffic_selector_t
*ts
;
1729 list
= linked_list_create_with_items(ike
, NULL
);
1730 ts_list
= config
->get_traffic_selectors(config
, local
, NULL
, list
);
1731 list
->destroy(list
);
1733 enumerator
= ts_list
->create_enumerator(ts_list
);
1734 while (enumerator
->enumerate(enumerator
, &ts
))
1736 if (ts
->is_host(ts
, NULL
) && ts
->to_subnet(ts
, &host
, &mask
))
1738 DBG1(DBG_CHD
, "%s address: %H is a transport mode proxy for %H",
1739 local
? "my" : "other", ike
, host
);
1743 enumerator
->destroy(enumerator
);
1744 ts_list
->destroy_offset(ts_list
, offsetof(traffic_selector_t
, destroy
));
1748 host
= ike
->clone(ike
);
1754 * Described in header.
1756 child_sa_t
* child_sa_create(host_t
*me
, host_t
* other
,
1757 child_cfg_t
*config
, uint32_t reqid
, bool encap
,
1758 u_int mark_in
, u_int mark_out
)
1760 private_child_sa_t
*this;
1761 static refcount_t unique_id
= 0, unique_mark
= 0;
1762 refcount_t mark
= 0;
1766 .get_name
= _get_name
,
1767 .get_reqid
= _get_reqid
,
1768 .get_unique_id
= _get_unique_id
,
1769 .get_config
= _get_config
,
1770 .get_state
= _get_state
,
1771 .set_state
= _set_state
,
1772 .get_outbound_state
= _get_outbound_state
,
1773 .get_spi
= _get_spi
,
1774 .get_cpi
= _get_cpi
,
1775 .get_protocol
= _get_protocol
,
1776 .set_protocol
= _set_protocol
,
1777 .get_mode
= _get_mode
,
1778 .set_mode
= _set_mode
,
1779 .get_proposal
= _get_proposal
,
1780 .set_proposal
= _set_proposal
,
1781 .get_lifetime
= _get_lifetime
,
1782 .get_installtime
= _get_installtime
,
1783 .get_usestats
= _get_usestats
,
1784 .get_mark
= _get_mark
,
1785 .has_encap
= _has_encap
,
1786 .get_ipcomp
= _get_ipcomp
,
1787 .set_ipcomp
= _set_ipcomp
,
1788 .get_close_action
= _get_close_action
,
1789 .set_close_action
= _set_close_action
,
1790 .get_dpd_action
= _get_dpd_action
,
1791 .set_dpd_action
= _set_dpd_action
,
1792 .alloc_spi
= _alloc_spi
,
1793 .alloc_cpi
= _alloc_cpi
,
1794 .install
= _install
,
1795 .register_outbound
= _register_outbound
,
1796 .install_outbound
= _install_outbound
,
1797 .remove_outbound
= _remove_outbound
,
1798 .set_rekey_spi
= _set_rekey_spi
,
1799 .get_rekey_spi
= _get_rekey_spi
,
1801 .set_policies
= _set_policies
,
1802 .install_policies
= _install_policies
,
1803 .create_ts_enumerator
= _create_ts_enumerator
,
1804 .create_policy_enumerator
= _create_policy_enumerator
,
1805 .destroy
= _destroy
,
1808 .ipcomp
= IPCOMP_NONE
,
1809 .state
= CHILD_CREATED
,
1810 .my_ts
= array_create(0, 0),
1811 .other_ts
= array_create(0, 0),
1812 .protocol
= PROTO_NONE
,
1813 .mode
= MODE_TUNNEL
,
1814 .close_action
= config
->get_close_action(config
),
1815 .dpd_action
= config
->get_dpd_action(config
),
1816 .reqid
= config
->get_reqid(config
),
1817 .unique_id
= ref_get(&unique_id
),
1818 .mark_in
= config
->get_mark(config
, TRUE
),
1819 .mark_out
= config
->get_mark(config
, FALSE
),
1820 .install_time
= time_monotonic(NULL
),
1821 .policies_fwd_out
= config
->has_option(config
, OPT_FWD_OUT_POLICIES
),
1824 this->config
= config
;
1825 config
->get_ref(config
);
1829 this->mark_in
.value
= mark_in
;
1833 this->mark_out
.value
= mark_out
;
1836 if (MARK_IS_UNIQUE(this->mark_in
.value
) ||
1837 MARK_IS_UNIQUE(this->mark_out
.value
))
1841 unique_dir
= this->mark_in
.value
== MARK_UNIQUE_DIR
||
1842 this->mark_out
.value
== MARK_UNIQUE_DIR
;
1846 mark
= ref_get(&unique_mark
);
1848 if (MARK_IS_UNIQUE(this->mark_in
.value
))
1852 mark
= ref_get(&unique_mark
);
1854 this->mark_in
.value
= mark
;
1856 if (MARK_IS_UNIQUE(this->mark_out
.value
))
1860 mark
= ref_get(&unique_mark
);
1862 this->mark_out
.value
= mark
;
1868 /* reuse old reqid if we are rekeying an existing CHILD_SA and when
1869 * initiating a trap policy. While the reqid cache would find the same
1870 * reqid for our selectors, this does not work in a special case: If an
1871 * SA is triggered by a trap policy, but the negotiated TS get
1872 * narrowed, we still must reuse the same reqid to successfully
1873 * replace the temporary SA on the kernel level. Rekeying such an SA
1874 * requires an explicit reqid, as the cache currently knows the original
1875 * selectors only for that reqid. */
1876 this->reqid
= reqid
;
1880 this->static_reqid
= TRUE
;
1883 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1884 if (config
->get_mode(config
) == MODE_TRANSPORT
&&
1885 config
->has_option(config
, OPT_PROXY_MODE
))
1887 this->mode
= MODE_TRANSPORT
;
1889 this->my_addr
= get_proxy_addr(config
, me
, TRUE
);
1890 this->other_addr
= get_proxy_addr(config
, other
, FALSE
);
1894 this->my_addr
= me
->clone(me
);
1895 this->other_addr
= other
->clone(other
);
1897 return &this->public;