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
8 * Copyright (C) secunet Security Networks AG
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
15 * This program is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
29 #include <collections/array.h>
31 ENUM(child_sa_state_names
, CHILD_CREATED
, CHILD_DESTROYING
,
45 ENUM_FLAGS(child_sa_outbound_state_names
, CHILD_OUTBOUND_REGISTERED
, CHILD_OUTBOUND_POLICIES
,
52 typedef struct private_child_sa_t private_child_sa_t
;
55 * Private data of a child_sa_t object.
57 struct private_child_sa_t
{
59 * Public interface of child_sa_t.
74 * our actually used SPI, 0 if unused
79 * others used SPI, 0 if unused
84 * our Compression Parameter Index (CPI) used, 0 if unused
89 * others Compression Parameter Index (CPI) used, 0 if unused
94 * Array for local traffic selectors
99 * Array for remote traffic selectors
104 * Outbound encryption key cached during a rekeying
109 * Outbound integrity key cached during a rekeying
114 * Whether the outbound SA has only been registered yet during a rekeying
116 child_sa_outbound_state_t outbound_state
;
119 * Whether the inbound SA has been installed
121 bool inbound_installed
;
124 * Whether the peer supports TFCv3
129 * The outbound SPI of the CHILD_SA that replaced this one during a rekeying
134 * Protocol used to protect this SA, ESP|AH
136 protocol_id_t protocol
;
139 * reqid used for this child_sa
144 * Did we allocate/confirm and must release the reqid?
146 bool reqid_allocated
;
149 * Is the reqid statically configured
154 * Unique CHILD_SA identifier
159 * Whether FWD policies in the outbound direction should be installed
161 bool policies_fwd_out
;
164 * Inbound interface ID
169 * Outbound interface ID
174 * inbound mark used for this child_sa
179 * outbound mark used for this child_sa
189 * absolute time when rekeying is scheduled
194 * absolute time when the SA expires
199 * absolute time when SA has been installed
204 * state of the CHILD_SA
206 child_sa_state_t state
;
209 * TRUE if this CHILD_SA is used to install trap policies
214 * Specifies if UDP encapsulation is enabled (NAT traversal)
219 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
221 ipcomp_transform_t ipcomp
;
224 * mode this SA uses, tunnel/transport
229 * Action to enforce if peer closes the CHILD_SA
231 action_t close_action
;
234 * Action to enforce if peer is considered dead
241 proposal_t
*proposal
;
244 * config used to create this child
249 * time of last use in seconds (inbound)
254 * time of last use in seconds (outbound)
256 time_t other_usetime
;
259 * last number of inbound bytes
261 uint64_t my_usebytes
;
264 * last number of outbound bytes
266 uint64_t other_usebytes
;
269 * last number of inbound packets
271 uint64_t my_usepackets
;
274 * last number of outbound bytes
276 uint64_t other_usepackets
;
280 * Convert an IKEv2 specific protocol identifier to the IP protocol identifier
282 static inline uint8_t proto_ike2ip(protocol_id_t protocol
)
296 * Returns the mark to use on the inbound SA
298 static inline mark_t
mark_in_sa(private_child_sa_t
*this)
300 if (this->config
->has_option(this->config
, OPT_MARK_IN_SA
))
302 return this->mark_in
;
308 * Possible uses for security labels
317 * Returns the security label for either policies, SAs or reqids.
319 static inline sec_label_t
*label_for(private_child_sa_t
*this, label_use_t use
)
321 /* For SELinux we use the configured label for policies and reqid but the
322 * negotiated one for the SAs. That's because the label on the policies is
323 * usually a generic one that matches specific labels on flows, which will
324 * trigger an acquire if no matching SA with that label exists yet.
325 * When that SA is later installed, we want to avoid having to install
326 * policies in the kernel that will never get used, so we use the configured
328 * Note that while the labels don't have to be equal, they are both either
331 if (this->config
->get_label_mode(this->config
) == SEC_LABEL_MODE_SELINUX
)
335 case LABEL_USE_REQID
:
336 case LABEL_USE_POLICY
:
337 return this->config
->get_label(this->config
);
342 /* for the simple label mode we don't pass labels to the kernel, so we don't
343 * use it to acquire unique reqids either */
347 METHOD(child_sa_t
, get_name
, char*,
348 private_child_sa_t
*this)
350 return this->config
->get_name(this->config
);
353 METHOD(child_sa_t
, get_reqid
, uint32_t,
354 private_child_sa_t
*this)
359 METHOD(child_sa_t
, get_unique_id
, uint32_t,
360 private_child_sa_t
*this)
362 return this->unique_id
;
365 METHOD(child_sa_t
, get_config
, child_cfg_t
*,
366 private_child_sa_t
*this)
371 METHOD(child_sa_t
, set_state
, void,
372 private_child_sa_t
*this, child_sa_state_t state
)
374 if (this->state
!= state
)
376 DBG2(DBG_CHD
, "CHILD_SA %s{%d} state change: %N => %N",
377 get_name(this), this->unique_id
,
378 child_sa_state_names
, this->state
,
379 child_sa_state_names
, state
);
380 charon
->bus
->child_state_change(charon
->bus
, &this->public, state
);
385 METHOD(child_sa_t
, get_state
, child_sa_state_t
,
386 private_child_sa_t
*this)
391 METHOD(child_sa_t
, get_outbound_state
, child_sa_outbound_state_t
,
392 private_child_sa_t
*this)
394 return this->outbound_state
;
397 METHOD(child_sa_t
, get_spi
, uint32_t,
398 private_child_sa_t
*this, bool inbound
)
400 return inbound
? this->my_spi
: this->other_spi
;
403 METHOD(child_sa_t
, get_cpi
, uint16_t,
404 private_child_sa_t
*this, bool inbound
)
406 return inbound
? this->my_cpi
: this->other_cpi
;
409 METHOD(child_sa_t
, get_protocol
, protocol_id_t
,
410 private_child_sa_t
*this)
412 return this->protocol
;
415 METHOD(child_sa_t
, set_protocol
, void,
416 private_child_sa_t
*this, protocol_id_t protocol
)
418 this->protocol
= protocol
;
421 METHOD(child_sa_t
, get_mode
, ipsec_mode_t
,
422 private_child_sa_t
*this)
427 METHOD(child_sa_t
, set_mode
, void,
428 private_child_sa_t
*this, ipsec_mode_t mode
)
433 METHOD(child_sa_t
, has_encap
, bool,
434 private_child_sa_t
*this)
439 METHOD(child_sa_t
, get_ipcomp
, ipcomp_transform_t
,
440 private_child_sa_t
*this)
445 METHOD(child_sa_t
, set_ipcomp
, void,
446 private_child_sa_t
*this, ipcomp_transform_t ipcomp
)
448 this->ipcomp
= ipcomp
;
451 METHOD(child_sa_t
, set_close_action
, void,
452 private_child_sa_t
*this, action_t action
)
454 this->close_action
= action
;
457 METHOD(child_sa_t
, get_close_action
, action_t
,
458 private_child_sa_t
*this)
460 return this->close_action
;
463 METHOD(child_sa_t
, set_dpd_action
, void,
464 private_child_sa_t
*this, action_t action
)
466 this->dpd_action
= action
;
469 METHOD(child_sa_t
, get_dpd_action
, action_t
,
470 private_child_sa_t
*this)
472 return this->dpd_action
;
475 METHOD(child_sa_t
, get_proposal
, proposal_t
*,
476 private_child_sa_t
*this)
478 return this->proposal
;
481 METHOD(child_sa_t
, set_proposal
, void,
482 private_child_sa_t
*this, proposal_t
*proposal
)
484 this->proposal
= proposal
->clone(proposal
, 0);
487 METHOD(child_sa_t
, create_ts_enumerator
, enumerator_t
*,
488 private_child_sa_t
*this, bool local
)
492 return array_create_enumerator(this->my_ts
);
494 return array_create_enumerator(this->other_ts
);
497 typedef struct policy_enumerator_t policy_enumerator_t
;
500 * Private policy enumerator
502 struct policy_enumerator_t
{
503 /** implements enumerator_t */
505 /** enumerator over own TS */
507 /** enumerator over others TS */
509 /** array of others TS, to recreate enumerator */
511 /** currently enumerating TS for "me" side */
512 traffic_selector_t
*ts
;
515 METHOD(enumerator_t
, policy_enumerate
, bool,
516 policy_enumerator_t
*this, va_list args
)
518 traffic_selector_t
*other_ts
, **my_out
, **other_out
;
520 VA_ARGS_VGET(args
, my_out
, other_out
);
522 while (this->ts
|| this->mine
->enumerate(this->mine
, &this->ts
))
524 if (!this->other
->enumerate(this->other
, &other_ts
))
525 { /* end of others list, restart with new of mine */
526 this->other
->destroy(this->other
);
527 this->other
= array_create_enumerator(this->array
);
531 if (this->ts
->get_type(this->ts
) != other_ts
->get_type(other_ts
))
532 { /* family mismatch */
535 if (this->ts
->get_protocol(this->ts
) &&
536 other_ts
->get_protocol(other_ts
) &&
537 this->ts
->get_protocol(this->ts
) != other_ts
->get_protocol(other_ts
))
538 { /* protocol mismatch */
547 *other_out
= other_ts
;
554 METHOD(enumerator_t
, policy_destroy
, void,
555 policy_enumerator_t
*this)
557 this->mine
->destroy(this->mine
);
558 this->other
->destroy(this->other
);
563 * Create an enumerator over two lists of traffic selectors, returning all the
564 * pairs of traffic selectors from the first and second list.
566 static enumerator_t
*create_policy_enumerator_internal(array_t
*my_ts
,
569 policy_enumerator_t
*e
;
573 .enumerate
= enumerator_enumerate_default
,
574 .venumerate
= _policy_enumerate
,
575 .destroy
= _policy_destroy
,
577 .mine
= array_create_enumerator(my_ts
),
578 .other
= array_create_enumerator(other_ts
),
586 METHOD(child_sa_t
, create_policy_enumerator
, enumerator_t
*,
587 private_child_sa_t
*this)
589 return create_policy_enumerator_internal(this->my_ts
, this->other_ts
);
593 * update the cached usebytes
594 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
595 * are available, and NOT_SUPPORTED if the kernel interface does not support
596 * querying the usebytes.
598 static status_t
update_usebytes(private_child_sa_t
*this, bool inbound
)
600 status_t status
= FAILED
;
601 uint64_t bytes
, packets
;
606 if (this->my_spi
&& this->inbound_installed
)
608 kernel_ipsec_sa_id_t id
= {
609 .src
= this->other_addr
,
610 .dst
= this->my_addr
,
612 .proto
= proto_ike2ip(this->protocol
),
613 .mark
= mark_in_sa(this),
614 .if_id
= this->if_id_in
,
616 kernel_ipsec_query_sa_t query
= {};
618 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
619 &bytes
, &packets
, &time
);
620 if (status
== SUCCESS
)
622 if (bytes
> this->my_usebytes
)
624 this->my_usebytes
= bytes
;
625 this->my_usepackets
= packets
;
628 this->my_usetime
= time
;
640 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
642 kernel_ipsec_sa_id_t id
= {
643 .src
= this->my_addr
,
644 .dst
= this->other_addr
,
645 .spi
= this->other_spi
,
646 .proto
= proto_ike2ip(this->protocol
),
647 .mark
= this->mark_out
,
648 .if_id
= this->if_id_out
,
650 kernel_ipsec_query_sa_t query
= {};
652 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
653 &bytes
, &packets
, &time
);
654 if (status
== SUCCESS
)
656 if (bytes
> this->other_usebytes
)
658 this->other_usebytes
= bytes
;
659 this->other_usepackets
= packets
;
662 this->other_usetime
= time
;
676 * updates the cached usetime
678 static bool update_usetime(private_child_sa_t
*this, bool inbound
)
680 enumerator_t
*enumerator
;
681 traffic_selector_t
*my_ts
, *other_ts
;
684 enumerator
= create_policy_enumerator(this);
685 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
691 kernel_ipsec_policy_id_t id
= {
695 .mark
= this->mark_in
,
696 .if_id
= this->if_id_in
,
697 .label
= label_for(this, LABEL_USE_POLICY
),
699 kernel_ipsec_query_policy_t query
= {};
701 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
704 last_use
= max(last_use
, in
);
706 if (this->mode
!= MODE_TRANSPORT
)
709 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
712 last_use
= max(last_use
, fwd
);
718 kernel_ipsec_policy_id_t id
= {
722 .mark
= this->mark_out
,
723 .if_id
= this->if_id_out
,
724 .interface
= this->config
->get_interface(this->config
),
725 .label
= label_for(this, LABEL_USE_POLICY
),
727 kernel_ipsec_query_policy_t query
= {};
729 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
732 last_use
= max(last_use
, out
);
736 enumerator
->destroy(enumerator
);
744 this->my_usetime
= last_use
;
748 this->other_usetime
= last_use
;
753 METHOD(child_sa_t
, get_usestats
, void,
754 private_child_sa_t
*this, bool inbound
,
755 time_t *time
, uint64_t *bytes
, uint64_t *packets
)
757 if ((!bytes
&& !packets
) || update_usebytes(this, inbound
) != FAILED
)
759 /* there was traffic since last update or the kernel interface
760 * does not support querying the number of usebytes.
764 if (!update_usetime(this, inbound
) && !bytes
&& !packets
)
766 /* if policy query did not yield a usetime, query SAs instead */
767 update_usebytes(this, inbound
);
773 *time
= inbound
? this->my_usetime
: this->other_usetime
;
777 *bytes
= inbound
? this->my_usebytes
: this->other_usebytes
;
781 *packets
= inbound
? this->my_usepackets
: this->other_usepackets
;
785 METHOD(child_sa_t
, get_mark
, mark_t
,
786 private_child_sa_t
*this, bool inbound
)
788 return inbound
? this->mark_in
: this->mark_out
;
791 METHOD(child_sa_t
, get_if_id
, uint32_t,
792 private_child_sa_t
*this, bool inbound
)
794 return inbound
? this->if_id_in
: this->if_id_out
;
797 METHOD(child_sa_t
, get_label
, sec_label_t
*,
798 private_child_sa_t
*this)
800 return this->label
?: this->config
->get_label(this->config
);
803 METHOD(child_sa_t
, get_lifetime
, time_t,
804 private_child_sa_t
*this, bool hard
)
806 return hard
? this->expire_time
: this->rekey_time
;
809 METHOD(child_sa_t
, get_installtime
, time_t,
810 private_child_sa_t
*this)
812 return this->install_time
;
815 METHOD(child_sa_t
, alloc_spi
, uint32_t,
816 private_child_sa_t
*this, protocol_id_t protocol
)
818 if (charon
->kernel
->get_spi(charon
->kernel
, this->other_addr
, this->my_addr
,
819 proto_ike2ip(protocol
), &this->my_spi
) == SUCCESS
)
821 /* if we allocate a SPI, but then are unable to establish the SA, we
822 * need to know the protocol family to delete the partial SA */
823 this->protocol
= protocol
;
829 METHOD(child_sa_t
, alloc_cpi
, uint16_t,
830 private_child_sa_t
*this)
832 if (charon
->kernel
->get_cpi(charon
->kernel
, this->other_addr
, this->my_addr
,
833 &this->my_cpi
) == SUCCESS
)
841 * Install the given SA in the kernel
843 static status_t
install_internal(private_child_sa_t
*this, chunk_t encr
,
844 chunk_t integ
, uint32_t spi
, uint16_t cpi
, bool initiator
, bool inbound
,
847 uint16_t enc_alg
= ENCR_UNDEFINED
, int_alg
= AUTH_UNDEFINED
, size
;
848 uint16_t esn
= NO_EXT_SEQ_NUMBERS
;
849 linked_list_t
*my_ts
, *other_ts
, *src_ts
, *dst_ts
;
851 kernel_ipsec_sa_id_t id
;
852 kernel_ipsec_add_sa_t sa
;
853 lifetime_cfg_t
*lifetime
;
859 /* BEET requires the bound address from the traffic selectors */
860 my_ts
= linked_list_create_from_enumerator(
861 array_create_enumerator(this->my_ts
));
862 other_ts
= linked_list_create_from_enumerator(
863 array_create_enumerator(this->other_ts
));
865 /* now we have to decide which spi to use. Use self allocated, if "in",
866 * or the one in the proposal, if not "in" (others). Additionally,
867 * source and dest host switch depending on the role */
871 src
= this->other_addr
;
872 if (this->my_spi
== spi
)
873 { /* alloc_spi has been called, do an SA update */
880 this->inbound_installed
= TRUE
;
885 dst
= this->other_addr
;
886 this->other_spi
= spi
;
887 this->other_cpi
= cpi
;
893 tfc
= this->config
->get_tfc(this->config
);
895 this->outbound_state
|= CHILD_OUTBOUND_SA
;
898 DBG2(DBG_CHD
, "adding %s %N SA", inbound
? "inbound" : "outbound",
899 protocol_id_names
, this->protocol
);
901 /* send SA down to the kernel */
902 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), src
, dst
);
904 this->proposal
->get_algorithm(this->proposal
, ENCRYPTION_ALGORITHM
,
906 this->proposal
->get_algorithm(this->proposal
, INTEGRITY_ALGORITHM
,
908 this->proposal
->get_algorithm(this->proposal
, EXTENDED_SEQUENCE_NUMBERS
,
911 if (int_alg
== AUTH_HMAC_SHA2_256_128
&&
912 this->config
->has_option(this->config
, OPT_SHA256_96
))
914 DBG2(DBG_CHD
, " using %N with 96-bit truncation",
915 integrity_algorithm_names
, int_alg
);
916 int_alg
= AUTH_HMAC_SHA2_256_96
;
919 if (!this->reqid_allocated
&& !this->static_reqid
)
921 status
= charon
->kernel
->alloc_reqid(charon
->kernel
, my_ts
, other_ts
,
922 this->mark_in
, this->mark_out
, this->if_id_in
,
923 this->if_id_out
, label_for(this, LABEL_USE_REQID
),
925 if (status
!= SUCCESS
)
927 my_ts
->destroy(my_ts
);
928 other_ts
->destroy(other_ts
);
931 this->reqid_allocated
= TRUE
;
934 lifetime
= this->config
->get_lifetime(this->config
, TRUE
);
936 now
= time_monotonic(NULL
);
937 if (lifetime
->time
.rekey
)
939 if (this->rekey_time
)
941 this->rekey_time
= min(this->rekey_time
, now
+ lifetime
->time
.rekey
);
945 this->rekey_time
= now
+ lifetime
->time
.rekey
;
948 if (lifetime
->time
.life
)
950 this->expire_time
= now
+ lifetime
->time
.life
;
953 if (!lifetime
->time
.jitter
&& !inbound
)
954 { /* avoid triggering multiple rekey events */
955 lifetime
->time
.rekey
= 0;
958 id
= (kernel_ipsec_sa_id_t
){
962 .proto
= proto_ike2ip(this->protocol
),
963 .mark
= inbound
? mark_in_sa(this) : this->mark_out
,
964 .if_id
= inbound
? this->if_id_in
: this->if_id_out
,
966 sa
= (kernel_ipsec_add_sa_t
){
967 .reqid
= this->reqid
,
971 .interface
= inbound
? NULL
: this->config
->get_interface(this->config
),
972 .lifetime
= lifetime
,
977 .replay_window
= this->config
->get_replay_window(this->config
),
979 .ipcomp
= this->ipcomp
,
981 .encap
= this->encap
,
982 .hw_offload
= this->config
->get_hw_offload(this->config
),
983 .mark
= this->config
->get_set_mark(this->config
, inbound
),
985 .copy_df
= !this->config
->has_option(this->config
, OPT_NO_COPY_DF
),
986 .copy_ecn
= !this->config
->has_option(this->config
, OPT_NO_COPY_ECN
),
987 .copy_dscp
= this->config
->get_copy_dscp(this->config
),
988 .label
= label_for(this, LABEL_USE_SA
),
989 .initiator
= initiator
,
994 if (sa
.mark
.value
== MARK_SAME
)
996 sa
.mark
.value
= inbound
? this->mark_in
.value
: this->mark_out
.value
;
999 status
= charon
->kernel
->add_sa(charon
->kernel
, &id
, &sa
);
1001 my_ts
->destroy(my_ts
);
1002 other_ts
->destroy(other_ts
);
1008 METHOD(child_sa_t
, install
, status_t
,
1009 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
1010 uint16_t cpi
, bool initiator
, bool inbound
, bool tfcv3
)
1012 return install_internal(this, encr
, integ
, spi
, cpi
, initiator
, inbound
,
1017 * Check kernel interface if policy updates are required
1019 static bool require_policy_update()
1023 f
= charon
->kernel
->get_features(charon
->kernel
);
1024 return !(f
& KERNEL_NO_POLICY_UPDATES
);
1028 * Prepare SA config to install/delete policies
1030 static void prepare_sa_cfg(private_child_sa_t
*this, ipsec_sa_cfg_t
*my_sa
,
1031 ipsec_sa_cfg_t
*other_sa
)
1033 enumerator_t
*enumerator
;
1035 *my_sa
= (ipsec_sa_cfg_t
){
1037 .reqid
= this->reqid
,
1039 .transform
= this->ipcomp
,
1044 my_sa
->ipcomp
.cpi
= this->my_cpi
;
1045 other_sa
->ipcomp
.cpi
= this->other_cpi
;
1047 if (this->protocol
== PROTO_ESP
)
1049 my_sa
->esp
.use
= TRUE
;
1050 my_sa
->esp
.spi
= this->my_spi
;
1051 other_sa
->esp
.use
= TRUE
;
1052 other_sa
->esp
.spi
= this->other_spi
;
1056 my_sa
->ah
.use
= TRUE
;
1057 my_sa
->ah
.spi
= this->my_spi
;
1058 other_sa
->ah
.use
= TRUE
;
1059 other_sa
->ah
.spi
= this->other_spi
;
1062 enumerator
= create_policy_enumerator(this);
1063 while (enumerator
->enumerate(enumerator
, NULL
, NULL
))
1065 my_sa
->policy_count
++;
1066 other_sa
->policy_count
++;
1068 enumerator
->destroy(enumerator
);
1072 * Install inbound policies: in, fwd
1074 static status_t
install_policies_inbound(private_child_sa_t
*this,
1075 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1076 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1077 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1078 policy_priority_t priority
, uint32_t manual_prio
)
1080 kernel_ipsec_policy_id_t in_id
= {
1084 .mark
= this->mark_in
,
1085 .if_id
= this->if_id_in
,
1086 .label
= label_for(this, LABEL_USE_POLICY
),
1088 kernel_ipsec_manage_policy_t in_policy
= {
1091 .manual_prio
= manual_prio
,
1096 status_t status
= SUCCESS
;
1098 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
1099 if (this->mode
!= MODE_TRANSPORT
)
1101 in_id
.dir
= POLICY_FWD
;
1102 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
1108 * Install outbound policies: out, [fwd]
1110 static status_t
install_policies_outbound(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 out_id
= {
1120 .mark
= this->mark_out
,
1121 .if_id
= this->if_id_out
,
1122 .interface
= this->config
->get_interface(this->config
),
1123 .label
= label_for(this, LABEL_USE_POLICY
),
1125 kernel_ipsec_manage_policy_t out_policy
= {
1128 .manual_prio
= manual_prio
,
1133 uint32_t reqid
= other_sa
->reqid
;
1134 status_t status
= SUCCESS
;
1136 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
, &out_policy
);
1138 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1140 /* install an "outbound" FWD policy in case there is a drop policy
1141 * matching outbound forwarded traffic, to allow another tunnel to use
1142 * the reversed subnets and do the same we don't set a reqid (this also
1143 * allows the kernel backend to distinguish between the two types of
1144 * FWD policies). To avoid problems with symmetrically overlapping
1145 * policies of two SAs we install them with reduced priority. As they
1146 * basically act as bypass policies for drop policies we use a higher
1147 * priority than is used for them. */
1148 out_id
.dir
= POLICY_FWD
;
1149 other_sa
->reqid
= 0;
1150 if (priority
== POLICY_PRIORITY_DEFAULT
)
1152 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1154 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
,
1156 /* reset the reqid for any other further policies */
1157 other_sa
->reqid
= reqid
;
1163 * Install all policies
1165 static status_t
install_policies_internal(private_child_sa_t
*this,
1166 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1167 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1168 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1169 policy_priority_t priority
, uint32_t manual_prio
, bool outbound
)
1171 status_t status
= SUCCESS
;
1173 status
|= install_policies_inbound(this, my_addr
, other_addr
, my_ts
,
1174 other_ts
, my_sa
, other_sa
, type
, priority
, manual_prio
);
1177 status
|= install_policies_outbound(this, my_addr
, other_addr
, my_ts
,
1178 other_ts
, my_sa
, other_sa
, type
, priority
, manual_prio
);
1184 * Delete inbound policies: in, fwd
1186 static void del_policies_inbound(private_child_sa_t
*this,
1187 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1188 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1189 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1190 policy_priority_t priority
, uint32_t manual_prio
)
1192 kernel_ipsec_policy_id_t in_id
= {
1196 .mark
= this->mark_in
,
1197 .if_id
= this->if_id_in
,
1198 .label
= label_for(this, LABEL_USE_POLICY
),
1200 kernel_ipsec_manage_policy_t in_policy
= {
1203 .manual_prio
= manual_prio
,
1209 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1211 if (this->mode
!= MODE_TRANSPORT
)
1213 in_id
.dir
= POLICY_FWD
;
1214 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
1219 * Delete outbound policies: out, [fwd]
1221 static void del_policies_outbound(private_child_sa_t
*this,
1222 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1223 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1224 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1225 policy_priority_t priority
, uint32_t manual_prio
)
1227 kernel_ipsec_policy_id_t out_id
= {
1231 .mark
= this->mark_out
,
1232 .if_id
= this->if_id_out
,
1233 .interface
= this->config
->get_interface(this->config
),
1234 .label
= label_for(this, LABEL_USE_POLICY
),
1236 kernel_ipsec_manage_policy_t out_policy
= {
1239 .manual_prio
= manual_prio
,
1244 uint32_t reqid
= other_sa
->reqid
;
1246 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1248 if (this->mode
!= MODE_TRANSPORT
&& this->policies_fwd_out
)
1250 out_id
.dir
= POLICY_FWD
;
1251 other_sa
->reqid
= 0;
1252 if (priority
== POLICY_PRIORITY_DEFAULT
)
1254 out_policy
.prio
= POLICY_PRIORITY_ROUTED
;
1256 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
1257 other_sa
->reqid
= reqid
;
1262 * Delete in- and outbound policies
1264 static void del_policies_internal(private_child_sa_t
*this,
1265 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
1266 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
1267 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
,
1268 policy_priority_t priority
, uint32_t manual_prio
, bool outbound
)
1272 del_policies_outbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1273 other_sa
, type
, priority
, manual_prio
);
1275 del_policies_inbound(this, my_addr
, other_addr
, my_ts
, other_ts
, my_sa
,
1276 other_sa
, type
, priority
, manual_prio
);
1279 METHOD(child_sa_t
, set_policies
, void,
1280 private_child_sa_t
*this, linked_list_t
*my_ts_list
,
1281 linked_list_t
*other_ts_list
)
1283 enumerator_t
*enumerator
;
1284 traffic_selector_t
*my_ts
, *other_ts
;
1286 if (array_count(this->my_ts
))
1288 array_destroy_offset(this->my_ts
,
1289 offsetof(traffic_selector_t
, destroy
));
1290 this->my_ts
= array_create(0, 0);
1292 enumerator
= my_ts_list
->create_enumerator(my_ts_list
);
1293 while (enumerator
->enumerate(enumerator
, &my_ts
))
1295 array_insert(this->my_ts
, ARRAY_TAIL
, my_ts
->clone(my_ts
));
1297 enumerator
->destroy(enumerator
);
1298 array_sort(this->my_ts
, (void*)traffic_selector_cmp
, NULL
);
1300 if (array_count(this->other_ts
))
1302 array_destroy_offset(this->other_ts
,
1303 offsetof(traffic_selector_t
, destroy
));
1304 this->other_ts
= array_create(0, 0);
1306 enumerator
= other_ts_list
->create_enumerator(other_ts_list
);
1307 while (enumerator
->enumerate(enumerator
, &other_ts
))
1309 array_insert(this->other_ts
, ARRAY_TAIL
, other_ts
->clone(other_ts
));
1311 enumerator
->destroy(enumerator
);
1312 array_sort(this->other_ts
, (void*)traffic_selector_cmp
, NULL
);
1316 * Allocate a reqid for the given local and remote traffic selectors.
1318 static status_t
alloc_reqid(private_child_sa_t
*this, array_t
*my_ts
,
1319 array_t
*other_ts
, uint32_t *reqid
)
1321 linked_list_t
*my_ts_list
, *other_ts_list
;
1324 my_ts_list
= linked_list_create_from_enumerator(array_create_enumerator(my_ts
));
1325 other_ts_list
= linked_list_create_from_enumerator(array_create_enumerator(other_ts
));
1326 status
= charon
->kernel
->alloc_reqid(
1327 charon
->kernel
, my_ts_list
, other_ts_list
,
1328 this->mark_in
, this->mark_out
, this->if_id_in
,
1329 this->if_id_out
, label_for(this, LABEL_USE_REQID
),
1331 my_ts_list
->destroy(my_ts_list
);
1332 other_ts_list
->destroy(other_ts_list
);
1336 METHOD(child_sa_t
, install_policies
, status_t
,
1337 private_child_sa_t
*this)
1339 enumerator_t
*enumerator
;
1340 traffic_selector_t
*my_ts
, *other_ts
;
1341 status_t status
= SUCCESS
;
1342 bool install_outbound
= FALSE
;
1344 if (!this->reqid_allocated
&& !this->static_reqid
)
1346 status
= alloc_reqid(this, this->my_ts
, this->other_ts
, &this->reqid
);
1347 if (status
!= SUCCESS
)
1351 this->reqid_allocated
= TRUE
;
1354 if (!(this->outbound_state
& CHILD_OUTBOUND_REGISTERED
))
1356 install_outbound
= TRUE
;
1357 this->outbound_state
|= CHILD_OUTBOUND_POLICIES
;
1360 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1362 policy_priority_t priority
;
1363 ipsec_sa_cfg_t my_sa
, other_sa
;
1364 uint32_t manual_prio
;
1366 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1367 manual_prio
= this->config
->get_manual_prio(this->config
);
1369 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1370 * entry) we install a trap policy */
1371 this->trap
= this->state
== CHILD_CREATED
;
1372 priority
= this->trap
? POLICY_PRIORITY_ROUTED
1373 : POLICY_PRIORITY_DEFAULT
;
1375 /* enumerate pairs of traffic selectors */
1376 enumerator
= create_policy_enumerator(this);
1377 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1379 status
|= install_policies_internal(this, this->my_addr
,
1380 this->other_addr
, my_ts
, other_ts
,
1381 &my_sa
, &other_sa
, POLICY_IPSEC
, priority
,
1382 manual_prio
, install_outbound
);
1383 if (status
!= SUCCESS
)
1388 enumerator
->destroy(enumerator
);
1391 if (status
== SUCCESS
&& this->trap
)
1393 set_state(this, CHILD_ROUTED
);
1399 * Check if we can install the outbound SA immediately.
1401 * If the kernel supports installing SPIs with policies, we can do so as it
1402 * will only be used once we update the policies.
1404 * However, if we use labels with SELinux, we can't as we don't set SPIs
1405 * on the policy in order to match SAs with other labels that match the generic
1406 * label that's used on the policies.
1408 static bool install_outbound_immediately(private_child_sa_t
*this)
1410 if (charon
->kernel
->get_features(charon
->kernel
) & KERNEL_POLICY_SPI
)
1412 if (this->config
->get_label_mode(this->config
) == SEC_LABEL_MODE_SELINUX
)
1414 return !this->label
;
1421 METHOD(child_sa_t
, register_outbound
, status_t
,
1422 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
1423 uint16_t cpi
, bool tfcv3
)
1427 if (install_outbound_immediately(this))
1429 status
= install_internal(this, encr
, integ
, spi
, cpi
, FALSE
, FALSE
,
1434 DBG2(DBG_CHD
, "registering outbound %N SA", protocol_id_names
,
1436 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), this->my_addr
,
1439 this->other_spi
= spi
;
1440 this->other_cpi
= cpi
;
1441 this->encr_r
= chunk_clone(encr
);
1442 this->integ_r
= chunk_clone(integ
);
1443 this->tfcv3
= tfcv3
;
1446 this->outbound_state
|= CHILD_OUTBOUND_REGISTERED
;
1450 METHOD(child_sa_t
, install_outbound
, status_t
,
1451 private_child_sa_t
*this)
1453 enumerator_t
*enumerator
;
1454 traffic_selector_t
*my_ts
, *other_ts
;
1455 status_t status
= SUCCESS
;
1457 if (!(this->outbound_state
& CHILD_OUTBOUND_SA
))
1459 status
= install_internal(this, this->encr_r
, this->integ_r
,
1460 this->other_spi
, this->other_cpi
, FALSE
,
1461 FALSE
, this->tfcv3
);
1462 chunk_clear(&this->encr_r
);
1463 chunk_clear(&this->integ_r
);
1465 this->outbound_state
&= ~CHILD_OUTBOUND_REGISTERED
;
1466 if (status
!= SUCCESS
)
1470 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1471 !(this->outbound_state
& CHILD_OUTBOUND_POLICIES
))
1473 ipsec_sa_cfg_t my_sa
, other_sa
;
1474 uint32_t manual_prio
;
1476 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1477 manual_prio
= this->config
->get_manual_prio(this->config
);
1479 enumerator
= create_policy_enumerator(this);
1480 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1482 status
|= install_policies_outbound(this, this->my_addr
,
1483 this->other_addr
, my_ts
, other_ts
,
1484 &my_sa
, &other_sa
, POLICY_IPSEC
,
1485 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1486 if (status
!= SUCCESS
)
1491 enumerator
->destroy(enumerator
);
1493 this->outbound_state
|= CHILD_OUTBOUND_POLICIES
;
1497 METHOD(child_sa_t
, remove_outbound
, void,
1498 private_child_sa_t
*this)
1500 enumerator_t
*enumerator
;
1501 traffic_selector_t
*my_ts
, *other_ts
;
1503 if (!(this->outbound_state
& CHILD_OUTBOUND_SA
))
1505 if (this->outbound_state
& CHILD_OUTBOUND_REGISTERED
)
1507 chunk_clear(&this->encr_r
);
1508 chunk_clear(&this->integ_r
);
1509 this->outbound_state
= CHILD_OUTBOUND_NONE
;
1514 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1515 (this->outbound_state
& CHILD_OUTBOUND_POLICIES
))
1517 ipsec_sa_cfg_t my_sa
, other_sa
;
1518 uint32_t manual_prio
;
1520 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1521 manual_prio
= this->config
->get_manual_prio(this->config
);
1523 enumerator
= create_policy_enumerator(this);
1524 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1526 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1527 my_ts
, other_ts
, &my_sa
, &other_sa
,
1528 POLICY_IPSEC
, POLICY_PRIORITY_DEFAULT
,
1531 enumerator
->destroy(enumerator
);
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
,
1540 .if_id
= this->if_id_out
,
1542 kernel_ipsec_del_sa_t sa
= {
1543 .cpi
= this->other_cpi
,
1545 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1546 this->outbound_state
= CHILD_OUTBOUND_NONE
;
1549 METHOD(child_sa_t
, set_rekey_spi
, void,
1550 private_child_sa_t
*this, uint32_t spi
)
1552 this->rekey_spi
= spi
;
1555 METHOD(child_sa_t
, get_rekey_spi
, uint32_t,
1556 private_child_sa_t
*this)
1558 return this->rekey_spi
;
1561 CALLBACK(reinstall_vip
, void,
1562 host_t
*vip
, va_list args
)
1567 VA_ARGS_VGET(args
, me
);
1568 if (charon
->kernel
->get_interface(charon
->kernel
, me
, &iface
))
1570 charon
->kernel
->del_ip(charon
->kernel
, vip
, -1, TRUE
);
1571 charon
->kernel
->add_ip(charon
->kernel
, vip
, -1, iface
);
1577 * Update addresses and encap state of IPsec SAs in the kernel
1579 static status_t
update_sas(private_child_sa_t
*this, host_t
*me
, host_t
*other
,
1580 bool encap
, uint32_t reqid
)
1582 /* update our (initiator) SA */
1583 if (this->my_spi
&& this->inbound_installed
)
1585 kernel_ipsec_sa_id_t id
= {
1586 .src
= this->other_addr
,
1587 .dst
= this->my_addr
,
1588 .spi
= this->my_spi
,
1589 .proto
= proto_ike2ip(this->protocol
),
1590 .mark
= mark_in_sa(this),
1591 .if_id
= this->if_id_in
,
1593 kernel_ipsec_update_sa_t sa
= {
1594 .cpi
= this->ipcomp
!= IPCOMP_NONE
? this->my_cpi
: 0,
1597 .encap
= this->encap
,
1601 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1602 &sa
) == NOT_SUPPORTED
)
1604 return NOT_SUPPORTED
;
1608 /* update his (responder) SA */
1609 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
1611 kernel_ipsec_sa_id_t id
= {
1612 .src
= this->my_addr
,
1613 .dst
= this->other_addr
,
1614 .spi
= this->other_spi
,
1615 .proto
= proto_ike2ip(this->protocol
),
1616 .mark
= this->mark_out
,
1617 .if_id
= this->if_id_out
,
1619 kernel_ipsec_update_sa_t sa
= {
1620 .cpi
= this->ipcomp
!= IPCOMP_NONE
? this->other_cpi
: 0,
1623 .encap
= this->encap
,
1627 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1628 &sa
) == NOT_SUPPORTED
)
1630 return NOT_SUPPORTED
;
1633 /* we currently ignore the actual return values above */
1638 * Fill the second list with copies of the given traffic selectors updating
1639 * dynamic traffic selectors based on the given addresses.
1641 static void update_ts(host_t
*old_host
, host_t
*new_host
, array_t
*old_list
,
1644 enumerator_t
*enumerator
;
1645 traffic_selector_t
*old_ts
, *new_ts
;
1647 enumerator
= array_create_enumerator(old_list
);
1648 while (enumerator
->enumerate(enumerator
, &old_ts
))
1650 new_ts
= old_ts
->clone(old_ts
);
1651 if (new_ts
->is_host(new_ts
, old_host
))
1653 new_ts
->set_address(new_ts
, new_host
);
1655 array_insert(new_list
, ARRAY_TAIL
, new_ts
);
1657 enumerator
->destroy(enumerator
);
1658 array_sort(new_list
, (void*)traffic_selector_cmp
, NULL
);
1661 METHOD(child_sa_t
, update
, status_t
,
1662 private_child_sa_t
*this, host_t
*me
, host_t
*other
, linked_list_t
*vips
,
1665 child_sa_state_t old
;
1666 bool transport_proxy_mode
;
1668 /* anything changed at all? */
1669 if (me
->equals(me
, this->my_addr
) &&
1670 other
->equals(other
, this->other_addr
) && this->encap
== encap
)
1676 set_state(this, CHILD_UPDATING
);
1677 transport_proxy_mode
= this->mode
== MODE_TRANSPORT
&&
1678 this->config
->has_option(this->config
,
1681 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
) &&
1682 require_policy_update() && array_count(this->my_ts
) &&
1683 array_count(this->other_ts
))
1685 ipsec_sa_cfg_t my_sa
, other_sa
;
1686 enumerator_t
*enumerator
;
1687 traffic_selector_t
*my_ts
, *other_ts
;
1688 array_t
*new_my_ts
= NULL
, *new_other_ts
= NULL
;
1689 policy_priority_t priority
;
1690 uint32_t manual_prio
, new_reqid
= 0;
1694 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1695 manual_prio
= this->config
->get_manual_prio(this->config
);
1696 priority
= this->trap
? POLICY_PRIORITY_ROUTED
1697 : POLICY_PRIORITY_DEFAULT
;
1698 outbound
= (this->outbound_state
& CHILD_OUTBOUND_POLICIES
) || this->trap
;
1700 enumerator
= create_policy_enumerator(this);
1701 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1703 if (!new_my_ts
&& !me
->ip_equals(me
, this->my_addr
) &&
1704 my_ts
->is_host(my_ts
, this->my_addr
))
1706 new_my_ts
= array_create(0, 0);
1708 if (!new_other_ts
&& !other
->ip_equals(other
, this->other_addr
) &&
1709 other_ts
->is_host(other_ts
, this->other_addr
))
1711 new_other_ts
= array_create(0, 0);
1713 /* install drop policy to avoid traffic leaks, acquires etc. */
1716 install_policies_outbound(this, this->my_addr
, this->other_addr
,
1717 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_DROP
,
1718 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1720 /* remove old policies */
1721 del_policies_internal(this, this->my_addr
, this->other_addr
,
1722 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
,
1723 priority
, manual_prio
, outbound
);
1725 enumerator
->destroy(enumerator
);
1729 update_ts(this->my_addr
, me
, this->my_ts
, new_my_ts
);
1733 update_ts(this->other_addr
, other
, this->other_ts
, new_other_ts
);
1735 if (this->reqid_allocated
&& (new_my_ts
|| new_other_ts
))
1737 /* if we allocated a reqid with the previous TS, we have to get a
1738 * new one that matches the updated TS */
1739 if (alloc_reqid(this, new_my_ts
?: this->my_ts
,
1740 new_other_ts
?: this->other_ts
, &new_reqid
) != SUCCESS
)
1742 DBG1(DBG_CHD
, "allocating new reqid for updated SA failed");
1746 /* update the IPsec SAs */
1747 state
= update_sas(this, me
, other
, encap
, new_reqid
);
1749 /* install new/updated policies only if we were able to update the
1750 * SAs, otherwise we reinstall the old policies further below */
1751 if (state
!= NOT_SUPPORTED
)
1753 /* we reinstall the virtual IP to handle interface roaming
1757 vips
->invoke_function(vips
, reinstall_vip
, me
);
1761 my_sa
.reqid
= other_sa
.reqid
= new_reqid
;
1763 enumerator
= create_policy_enumerator_internal(
1764 new_my_ts
?: this->my_ts
,
1765 new_other_ts
?: this->other_ts
);
1766 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1768 install_policies_internal(this, me
, other
, my_ts
, other_ts
,
1769 &my_sa
, &other_sa
, POLICY_IPSEC
,
1770 priority
, manual_prio
, outbound
);
1772 enumerator
->destroy(enumerator
);
1775 my_sa
.reqid
= other_sa
.reqid
= this->reqid
;
1779 enumerator
= create_policy_enumerator(this);
1780 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1782 /* reinstall the previous policies if we can't update the SAs */
1783 if (state
== NOT_SUPPORTED
)
1785 install_policies_internal(this, this->my_addr
, this->other_addr
,
1786 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
,
1787 priority
, manual_prio
, outbound
);
1789 /* remove the drop policy */
1792 del_policies_outbound(this, this->my_addr
, this->other_addr
,
1793 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_DROP
,
1794 POLICY_PRIORITY_DEFAULT
, manual_prio
);
1797 enumerator
->destroy(enumerator
);
1799 if (state
== NOT_SUPPORTED
)
1802 charon
->kernel
->release_reqid(charon
->kernel
,
1803 new_reqid
, this->mark_in
, this->mark_out
,
1804 this->if_id_in
, this->if_id_out
,
1805 label_for(this, LABEL_USE_REQID
)) != SUCCESS
)
1807 DBG1(DBG_CHD
, "releasing reqid %u failed", new_reqid
);
1809 array_destroy_offset(new_my_ts
,
1810 offsetof(traffic_selector_t
, destroy
));
1811 array_destroy_offset(new_other_ts
,
1812 offsetof(traffic_selector_t
, destroy
));
1813 set_state(this, old
);
1814 return NOT_SUPPORTED
;
1819 if (charon
->kernel
->release_reqid(charon
->kernel
,
1820 this->reqid
, this->mark_in
, this->mark_out
,
1821 this->if_id_in
, this->if_id_out
,
1822 label_for(this, LABEL_USE_REQID
)) != SUCCESS
)
1824 DBG1(DBG_CHD
, "releasing reqid %u failed", this->reqid
);
1826 DBG1(DBG_CHD
, "replaced reqid %u with reqid %u for updated "
1827 "CHILD_SA %s{%d}", this->reqid
, new_reqid
, get_name(this),
1829 this->reqid
= new_reqid
;
1833 array_destroy_offset(this->my_ts
,
1834 offsetof(traffic_selector_t
, destroy
));
1835 this->my_ts
= new_my_ts
;
1839 array_destroy_offset(this->other_ts
,
1840 offsetof(traffic_selector_t
, destroy
));
1841 this->other_ts
= new_other_ts
;
1844 else if (!transport_proxy_mode
)
1846 if (update_sas(this, me
, other
, encap
, 0) == NOT_SUPPORTED
)
1848 set_state(this, old
);
1849 return NOT_SUPPORTED
;
1853 if (!transport_proxy_mode
)
1856 if (!me
->equals(me
, this->my_addr
))
1858 this->my_addr
->destroy(this->my_addr
);
1859 this->my_addr
= me
->clone(me
);
1861 if (!other
->equals(other
, this->other_addr
))
1863 this->other_addr
->destroy(this->other_addr
);
1864 this->other_addr
= other
->clone(other
);
1868 this->encap
= encap
;
1869 set_state(this, old
);
1874 METHOD(child_sa_t
, destroy
, void,
1875 private_child_sa_t
*this)
1877 enumerator_t
*enumerator
;
1878 traffic_selector_t
*my_ts
, *other_ts
;
1879 policy_priority_t priority
;
1881 priority
= this->trap
? POLICY_PRIORITY_ROUTED
: POLICY_PRIORITY_DEFAULT
;
1883 set_state(this, CHILD_DESTROYING
);
1885 if (!this->config
->has_option(this->config
, OPT_NO_POLICIES
))
1887 ipsec_sa_cfg_t my_sa
, other_sa
;
1888 uint32_t manual_prio
;
1891 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1892 manual_prio
= this->config
->get_manual_prio(this->config
);
1893 del_outbound
= (this->outbound_state
& CHILD_OUTBOUND_POLICIES
) ||
1896 /* delete all policies in the kernel */
1897 enumerator
= create_policy_enumerator(this);
1898 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1900 del_policies_internal(this, this->my_addr
,
1901 this->other_addr
, my_ts
, other_ts
, &my_sa
, &other_sa
,
1902 POLICY_IPSEC
, priority
, manual_prio
, del_outbound
);
1904 enumerator
->destroy(enumerator
);
1907 /* delete SAs in the kernel, if they are set up, inbound is always deleted
1908 * to remove allocated SPIs */
1911 kernel_ipsec_sa_id_t id
= {
1912 .src
= this->other_addr
,
1913 .dst
= this->my_addr
,
1914 .spi
= this->my_spi
,
1915 .proto
= proto_ike2ip(this->protocol
),
1916 .mark
= mark_in_sa(this),
1917 .if_id
= this->if_id_in
,
1919 kernel_ipsec_del_sa_t sa
= {
1920 .cpi
= this->my_cpi
,
1922 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1924 if (this->other_spi
&& (this->outbound_state
& CHILD_OUTBOUND_SA
))
1926 kernel_ipsec_sa_id_t id
= {
1927 .src
= this->my_addr
,
1928 .dst
= this->other_addr
,
1929 .spi
= this->other_spi
,
1930 .proto
= proto_ike2ip(this->protocol
),
1931 .mark
= this->mark_out
,
1932 .if_id
= this->if_id_out
,
1934 kernel_ipsec_del_sa_t sa
= {
1935 .cpi
= this->other_cpi
,
1937 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1940 if (this->reqid_allocated
)
1942 if (charon
->kernel
->release_reqid(charon
->kernel
,
1943 this->reqid
, this->mark_in
, this->mark_out
,
1944 this->if_id_in
, this->if_id_out
,
1945 label_for(this, LABEL_USE_REQID
)) != SUCCESS
)
1947 DBG1(DBG_CHD
, "releasing reqid %u failed", this->reqid
);
1951 array_destroy_offset(this->my_ts
, offsetof(traffic_selector_t
, destroy
));
1952 array_destroy_offset(this->other_ts
, offsetof(traffic_selector_t
, destroy
));
1953 this->my_addr
->destroy(this->my_addr
);
1954 this->other_addr
->destroy(this->other_addr
);
1955 DESTROY_IF(this->proposal
);
1956 DESTROY_IF(this->label
);
1957 this->config
->destroy(this->config
);
1958 chunk_clear(&this->encr_r
);
1959 chunk_clear(&this->integ_r
);
1964 * Get proxy address for one side, if any
1966 static host_t
* get_proxy_addr(child_cfg_t
*config
, host_t
*ike
, bool local
)
1968 host_t
*host
= NULL
;
1970 enumerator_t
*enumerator
;
1971 linked_list_t
*ts_list
, *list
;
1972 traffic_selector_t
*ts
;
1974 list
= linked_list_create_with_items(ike
, NULL
);
1975 ts_list
= config
->get_traffic_selectors(config
, local
, NULL
, list
, FALSE
);
1976 list
->destroy(list
);
1978 enumerator
= ts_list
->create_enumerator(ts_list
);
1979 while (enumerator
->enumerate(enumerator
, &ts
))
1981 if (ts
->is_host(ts
, NULL
) && ts
->to_subnet(ts
, &host
, &mask
))
1983 DBG1(DBG_CHD
, "%s address: %H is a transport mode proxy for %H",
1984 local
? "my" : "other", ike
, host
);
1988 enumerator
->destroy(enumerator
);
1989 ts_list
->destroy_offset(ts_list
, offsetof(traffic_selector_t
, destroy
));
1993 host
= ike
->clone(ike
);
1999 * Described in header
2001 child_sa_t
*child_sa_create(host_t
*me
, host_t
*other
, child_cfg_t
*config
,
2002 child_sa_create_t
*data
)
2004 private_child_sa_t
*this;
2005 static refcount_t unique_id
= 0, unique_mark
= 0;
2009 .get_name
= _get_name
,
2010 .get_reqid
= _get_reqid
,
2011 .get_unique_id
= _get_unique_id
,
2012 .get_config
= _get_config
,
2013 .get_state
= _get_state
,
2014 .set_state
= _set_state
,
2015 .get_outbound_state
= _get_outbound_state
,
2016 .get_spi
= _get_spi
,
2017 .get_cpi
= _get_cpi
,
2018 .get_protocol
= _get_protocol
,
2019 .set_protocol
= _set_protocol
,
2020 .get_mode
= _get_mode
,
2021 .set_mode
= _set_mode
,
2022 .get_proposal
= _get_proposal
,
2023 .set_proposal
= _set_proposal
,
2024 .get_lifetime
= _get_lifetime
,
2025 .get_installtime
= _get_installtime
,
2026 .get_usestats
= _get_usestats
,
2027 .get_mark
= _get_mark
,
2028 .get_if_id
= _get_if_id
,
2029 .get_label
= _get_label
,
2030 .has_encap
= _has_encap
,
2031 .get_ipcomp
= _get_ipcomp
,
2032 .set_ipcomp
= _set_ipcomp
,
2033 .get_close_action
= _get_close_action
,
2034 .set_close_action
= _set_close_action
,
2035 .get_dpd_action
= _get_dpd_action
,
2036 .set_dpd_action
= _set_dpd_action
,
2037 .alloc_spi
= _alloc_spi
,
2038 .alloc_cpi
= _alloc_cpi
,
2039 .install
= _install
,
2040 .register_outbound
= _register_outbound
,
2041 .install_outbound
= _install_outbound
,
2042 .remove_outbound
= _remove_outbound
,
2043 .set_rekey_spi
= _set_rekey_spi
,
2044 .get_rekey_spi
= _get_rekey_spi
,
2046 .set_policies
= _set_policies
,
2047 .install_policies
= _install_policies
,
2048 .create_ts_enumerator
= _create_ts_enumerator
,
2049 .create_policy_enumerator
= _create_policy_enumerator
,
2050 .destroy
= _destroy
,
2052 .encap
= data
->encap
,
2053 .ipcomp
= IPCOMP_NONE
,
2054 .state
= CHILD_CREATED
,
2055 .my_ts
= array_create(0, 0),
2056 .other_ts
= array_create(0, 0),
2057 .protocol
= PROTO_NONE
,
2058 .mode
= MODE_TUNNEL
,
2059 .close_action
= config
->get_close_action(config
),
2060 .dpd_action
= config
->get_dpd_action(config
),
2061 .reqid
= config
->get_reqid(config
),
2062 .unique_id
= ref_get(&unique_id
),
2063 .mark_in
= config
->get_mark(config
, TRUE
),
2064 .mark_out
= config
->get_mark(config
, FALSE
),
2065 .if_id_in
= config
->get_if_id(config
, TRUE
) ?: data
->if_id_in_def
,
2066 .if_id_out
= config
->get_if_id(config
, FALSE
) ?: data
->if_id_out_def
,
2067 .label
= data
->label
? data
->label
->clone(data
->label
) : NULL
,
2068 .install_time
= time_monotonic(NULL
),
2069 .policies_fwd_out
= config
->has_option(config
, OPT_FWD_OUT_POLICIES
),
2072 this->config
= config
;
2073 config
->get_ref(config
);
2077 this->mark_in
.value
= data
->mark_in
;
2081 this->mark_out
.value
= data
->mark_out
;
2085 this->if_id_in
= data
->if_id_in
;
2087 if (data
->if_id_out
)
2089 this->if_id_out
= data
->if_id_out
;
2092 allocate_unique_if_ids(&this->if_id_in
, &this->if_id_out
);
2094 if (MARK_IS_UNIQUE(this->mark_in
.value
) ||
2095 MARK_IS_UNIQUE(this->mark_out
.value
))
2097 refcount_t mark
= 0;
2098 bool unique_dir
= this->mark_in
.value
== MARK_UNIQUE_DIR
||
2099 this->mark_out
.value
== MARK_UNIQUE_DIR
;
2103 mark
= ref_get(&unique_mark
);
2105 if (MARK_IS_UNIQUE(this->mark_in
.value
))
2107 this->mark_in
.value
= unique_dir
? ref_get(&unique_mark
) : mark
;
2109 if (MARK_IS_UNIQUE(this->mark_out
.value
))
2111 this->mark_out
.value
= unique_dir
? ref_get(&unique_mark
) : mark
;
2117 /* reuse old reqid if we are rekeying an existing CHILD_SA and when
2118 * initiating a trap policy. While the reqid cache would find the same
2119 * reqid for our selectors, this does not work in a special case: If an
2120 * SA is triggered by a trap policy, but the negotiated TS get
2121 * narrowed, we still must reuse the same reqid to successfully
2122 * replace the temporary SA on the kernel level. Rekeying such an SA
2123 * requires an explicit reqid, as the cache currently knows the original
2124 * selectors only for that reqid. */
2125 this->reqid
= data
->reqid
;
2129 this->static_reqid
= TRUE
;
2132 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
2133 if (config
->get_mode(config
) == MODE_TRANSPORT
&&
2134 config
->has_option(config
, OPT_PROXY_MODE
))
2136 this->mode
= MODE_TRANSPORT
;
2138 this->my_addr
= get_proxy_addr(config
, me
, TRUE
);
2139 this->other_addr
= get_proxy_addr(config
, other
, FALSE
);
2143 this->my_addr
= me
->clone(me
);
2144 this->other_addr
= other
->clone(other
);
2146 return &this->public;