2 * Copyright (C) 2006-2016 Tobias Brunner
3 * Copyright (C) 2005-2008 Martin Willi
4 * Copyright (C) 2006 Daniel Roethlisberger
5 * Copyright (C) 2005 Jan Hutter
6 * HSR Hochschule fuer Technik Rapperswil
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
27 #include <collections/array.h>
29 ENUM(child_sa_state_names
, CHILD_CREATED
, CHILD_DESTROYING
,
42 typedef struct private_child_sa_t private_child_sa_t
;
45 * Private data of a child_sa_t object.
47 struct private_child_sa_t
{
49 * Public interface of child_sa_t.
64 * our actually used SPI, 0 if unused
69 * others used SPI, 0 if unused
74 * our Compression Parameter Index (CPI) used, 0 if unused
79 * others Compression Parameter Index (CPI) used, 0 if unused
84 * Array for local traffic selectors
89 * Array for remote traffic selectors
94 * Protocol used to protect this SA, ESP|AH
96 protocol_id_t protocol
;
99 * reqid used for this child_sa
104 * Did we allocate/confirm and must release the reqid?
106 bool reqid_allocated
;
109 * Is the reqid statically configured
114 * Unique CHILD_SA identifier
119 * inbound mark used for this child_sa
124 * outbound mark used for this child_sa
129 * absolute time when rekeying is scheduled
134 * absolute time when the SA expires
139 * absolute time when SA has been installed
144 * state of the CHILD_SA
146 child_sa_state_t state
;
149 * TRUE if this CHILD_SA is used to install trap policies
154 * Specifies if UDP encapsulation is enabled (NAT traversal)
159 * Specifies the IPComp transform used (IPCOMP_NONE if disabled)
161 ipcomp_transform_t ipcomp
;
164 * mode this SA uses, tunnel/transport
169 * Action to enforce if peer closes the CHILD_SA
171 action_t close_action
;
174 * Action to enforce if peer is considered dead
181 proposal_t
*proposal
;
184 * config used to create this child
189 * time of last use in seconds (inbound)
194 * time of last use in seconds (outbound)
196 time_t other_usetime
;
199 * last number of inbound bytes
201 uint64_t my_usebytes
;
204 * last number of outbound bytes
206 uint64_t other_usebytes
;
209 * last number of inbound packets
211 uint64_t my_usepackets
;
214 * last number of outbound bytes
216 uint64_t other_usepackets
;
220 * convert an IKEv2 specific protocol identifier to the IP protocol identifier.
222 static inline uint8_t proto_ike2ip(protocol_id_t protocol
)
235 METHOD(child_sa_t
, get_name
, char*,
236 private_child_sa_t
*this)
238 return this->config
->get_name(this->config
);
241 METHOD(child_sa_t
, get_reqid
, uint32_t,
242 private_child_sa_t
*this)
247 METHOD(child_sa_t
, get_unique_id
, uint32_t,
248 private_child_sa_t
*this)
250 return this->unique_id
;
253 METHOD(child_sa_t
, get_config
, child_cfg_t
*,
254 private_child_sa_t
*this)
259 METHOD(child_sa_t
, set_state
, void,
260 private_child_sa_t
*this, child_sa_state_t state
)
262 charon
->bus
->child_state_change(charon
->bus
, &this->public, state
);
266 METHOD(child_sa_t
, get_state
, child_sa_state_t
,
267 private_child_sa_t
*this)
272 METHOD(child_sa_t
, get_spi
, uint32_t,
273 private_child_sa_t
*this, bool inbound
)
275 return inbound ?
this->my_spi
: this->other_spi
;
278 METHOD(child_sa_t
, get_cpi
, uint16_t,
279 private_child_sa_t
*this, bool inbound
)
281 return inbound ?
this->my_cpi
: this->other_cpi
;
284 METHOD(child_sa_t
, get_protocol
, protocol_id_t
,
285 private_child_sa_t
*this)
287 return this->protocol
;
290 METHOD(child_sa_t
, set_protocol
, void,
291 private_child_sa_t
*this, protocol_id_t protocol
)
293 this->protocol
= protocol
;
296 METHOD(child_sa_t
, get_mode
, ipsec_mode_t
,
297 private_child_sa_t
*this)
302 METHOD(child_sa_t
, set_mode
, void,
303 private_child_sa_t
*this, ipsec_mode_t mode
)
308 METHOD(child_sa_t
, has_encap
, bool,
309 private_child_sa_t
*this)
314 METHOD(child_sa_t
, get_ipcomp
, ipcomp_transform_t
,
315 private_child_sa_t
*this)
320 METHOD(child_sa_t
, set_ipcomp
, void,
321 private_child_sa_t
*this, ipcomp_transform_t ipcomp
)
323 this->ipcomp
= ipcomp
;
326 METHOD(child_sa_t
, set_close_action
, void,
327 private_child_sa_t
*this, action_t action
)
329 this->close_action
= action
;
332 METHOD(child_sa_t
, get_close_action
, action_t
,
333 private_child_sa_t
*this)
335 return this->close_action
;
338 METHOD(child_sa_t
, set_dpd_action
, void,
339 private_child_sa_t
*this, action_t action
)
341 this->dpd_action
= action
;
344 METHOD(child_sa_t
, get_dpd_action
, action_t
,
345 private_child_sa_t
*this)
347 return this->dpd_action
;
350 METHOD(child_sa_t
, get_proposal
, proposal_t
*,
351 private_child_sa_t
*this)
353 return this->proposal
;
356 METHOD(child_sa_t
, set_proposal
, void,
357 private_child_sa_t
*this, proposal_t
*proposal
)
359 this->proposal
= proposal
->clone(proposal
);
362 METHOD(child_sa_t
, create_ts_enumerator
, enumerator_t
*,
363 private_child_sa_t
*this, bool local
)
367 return array_create_enumerator(this->my_ts
);
369 return array_create_enumerator(this->other_ts
);
372 typedef struct policy_enumerator_t policy_enumerator_t
;
375 * Private policy enumerator
377 struct policy_enumerator_t
{
378 /** implements enumerator_t */
380 /** enumerator over own TS */
382 /** enumerator over others TS */
384 /** array of others TS, to recreate enumerator */
386 /** currently enumerating TS for "me" side */
387 traffic_selector_t
*ts
;
390 METHOD(enumerator_t
, policy_enumerate
, bool,
391 policy_enumerator_t
*this, traffic_selector_t
**my_out
,
392 traffic_selector_t
**other_out
)
394 traffic_selector_t
*other_ts
;
396 while (this->ts
|| this->mine
->enumerate(this->mine
, &this->ts
))
398 if (!this->other
->enumerate(this->other
, &other_ts
))
399 { /* end of others list, restart with new of mine */
400 this->other
->destroy(this->other
);
401 this->other
= array_create_enumerator(this->array
);
405 if (this->ts
->get_type(this->ts
) != other_ts
->get_type(other_ts
))
406 { /* family mismatch */
409 if (this->ts
->get_protocol(this->ts
) &&
410 other_ts
->get_protocol(other_ts
) &&
411 this->ts
->get_protocol(this->ts
) != other_ts
->get_protocol(other_ts
))
412 { /* protocol mismatch */
421 *other_out
= other_ts
;
428 METHOD(enumerator_t
, policy_destroy
, void,
429 policy_enumerator_t
*this)
431 this->mine
->destroy(this->mine
);
432 this->other
->destroy(this->other
);
436 METHOD(child_sa_t
, create_policy_enumerator
, enumerator_t
*,
437 private_child_sa_t
*this)
439 policy_enumerator_t
*e
;
443 .enumerate
= (void*)_policy_enumerate
,
444 .destroy
= _policy_destroy
,
446 .mine
= array_create_enumerator(this->my_ts
),
447 .other
= array_create_enumerator(this->other_ts
),
448 .array
= this->other_ts
,
456 * update the cached usebytes
457 * returns SUCCESS if the usebytes have changed, FAILED if not or no SPIs
458 * are available, and NOT_SUPPORTED if the kernel interface does not support
459 * querying the usebytes.
461 static status_t
update_usebytes(private_child_sa_t
*this, bool inbound
)
463 status_t status
= FAILED
;
464 uint64_t bytes
, packets
;
471 kernel_ipsec_sa_id_t id
= {
472 .src
= this->other_addr
,
473 .dst
= this->my_addr
,
475 .proto
= proto_ike2ip(this->protocol
),
476 .mark
= this->mark_in
,
478 kernel_ipsec_query_sa_t query
= {};
480 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
481 &bytes
, &packets
, &time
);
482 if (status
== SUCCESS
)
484 if (bytes
> this->my_usebytes
)
486 this->my_usebytes
= bytes
;
487 this->my_usepackets
= packets
;
490 this->my_usetime
= time
;
502 kernel_ipsec_sa_id_t id
= {
503 .src
= this->my_addr
,
504 .dst
= this->other_addr
,
505 .spi
= this->other_spi
,
506 .proto
= proto_ike2ip(this->protocol
),
507 .mark
= this->mark_out
,
509 kernel_ipsec_query_sa_t query
= {};
511 status
= charon
->kernel
->query_sa(charon
->kernel
, &id
, &query
,
512 &bytes
, &packets
, &time
);
513 if (status
== SUCCESS
)
515 if (bytes
> this->other_usebytes
)
517 this->other_usebytes
= bytes
;
518 this->other_usepackets
= packets
;
521 this->other_usetime
= time
;
533 * updates the cached usetime
535 static bool update_usetime(private_child_sa_t
*this, bool inbound
)
537 enumerator_t
*enumerator
;
538 traffic_selector_t
*my_ts
, *other_ts
;
541 enumerator
= create_policy_enumerator(this);
542 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
548 kernel_ipsec_policy_id_t id
= {
552 .mark
= this->mark_in
,
554 kernel_ipsec_query_policy_t query
= {};
556 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
559 last_use
= max(last_use
, in
);
561 if (this->mode
!= MODE_TRANSPORT
)
564 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
567 last_use
= max(last_use
, fwd
);
573 kernel_ipsec_policy_id_t id
= {
577 .mark
= this->mark_out
,
579 kernel_ipsec_query_policy_t query
= {};
581 if (charon
->kernel
->query_policy(charon
->kernel
, &id
, &query
,
584 last_use
= max(last_use
, out
);
588 enumerator
->destroy(enumerator
);
596 this->my_usetime
= last_use
;
600 this->other_usetime
= last_use
;
605 METHOD(child_sa_t
, get_usestats
, void,
606 private_child_sa_t
*this, bool inbound
,
607 time_t *time
, uint64_t *bytes
, uint64_t *packets
)
609 if ((!bytes
&& !packets
) || update_usebytes(this, inbound
) != FAILED
)
611 /* there was traffic since last update or the kernel interface
612 * does not support querying the number of usebytes.
616 if (!update_usetime(this, inbound
) && !bytes
&& !packets
)
618 /* if policy query did not yield a usetime, query SAs instead */
619 update_usebytes(this, inbound
);
625 *time
= inbound ?
this->my_usetime
: this->other_usetime
;
629 *bytes
= inbound ?
this->my_usebytes
: this->other_usebytes
;
633 *packets
= inbound ?
this->my_usepackets
: this->other_usepackets
;
637 METHOD(child_sa_t
, get_mark
, mark_t
,
638 private_child_sa_t
*this, bool inbound
)
642 return this->mark_in
;
644 return this->mark_out
;
647 METHOD(child_sa_t
, get_lifetime
, time_t,
648 private_child_sa_t
*this, bool hard
)
650 return hard ?
this->expire_time
: this->rekey_time
;
653 METHOD(child_sa_t
, get_installtime
, time_t,
654 private_child_sa_t
*this)
656 return this->install_time
;
659 METHOD(child_sa_t
, alloc_spi
, uint32_t,
660 private_child_sa_t
*this, protocol_id_t protocol
)
662 if (charon
->kernel
->get_spi(charon
->kernel
, this->other_addr
, this->my_addr
,
663 proto_ike2ip(protocol
), &this->my_spi
) == SUCCESS
)
665 /* if we allocate a SPI, but then are unable to establish the SA, we
666 * need to know the protocol family to delete the partial SA */
667 this->protocol
= protocol
;
673 METHOD(child_sa_t
, alloc_cpi
, uint16_t,
674 private_child_sa_t
*this)
676 if (charon
->kernel
->get_cpi(charon
->kernel
, this->other_addr
, this->my_addr
,
677 &this->my_cpi
) == SUCCESS
)
684 METHOD(child_sa_t
, install
, status_t
,
685 private_child_sa_t
*this, chunk_t encr
, chunk_t integ
, uint32_t spi
,
686 uint16_t cpi
, bool initiator
, bool inbound
, bool tfcv3
,
687 linked_list_t
*my_ts
, linked_list_t
*other_ts
)
689 uint16_t enc_alg
= ENCR_UNDEFINED
, int_alg
= AUTH_UNDEFINED
, size
;
690 uint16_t esn
= NO_EXT_SEQ_NUMBERS
;
691 linked_list_t
*src_ts
= NULL
, *dst_ts
= NULL
;
693 kernel_ipsec_sa_id_t id
;
694 kernel_ipsec_add_sa_t sa
;
695 lifetime_cfg_t
*lifetime
;
701 /* now we have to decide which spi to use. Use self allocated, if "in",
702 * or the one in the proposal, if not "in" (others). Additionally,
703 * source and dest host switch depending on the role */
707 src
= this->other_addr
;
708 if (this->my_spi
== spi
)
709 { /* alloc_spi has been called, do an SA update */
718 dst
= this->other_addr
;
719 this->other_spi
= spi
;
720 this->other_cpi
= cpi
;
724 tfc
= this->config
->get_tfc(this->config
);
728 DBG2(DBG_CHD
, "adding %s %N SA", inbound ?
"inbound" : "outbound",
729 protocol_id_names
, this->protocol
);
731 /* send SA down to the kernel */
732 DBG2(DBG_CHD
, " SPI 0x%.8x, src %H dst %H", ntohl(spi
), src
, dst
);
734 this->proposal
->get_algorithm(this->proposal
, ENCRYPTION_ALGORITHM
,
736 this->proposal
->get_algorithm(this->proposal
, INTEGRITY_ALGORITHM
,
738 this->proposal
->get_algorithm(this->proposal
, EXTENDED_SEQUENCE_NUMBERS
,
741 if (!this->reqid_allocated
&& !this->static_reqid
)
743 status
= charon
->kernel
->alloc_reqid(charon
->kernel
, my_ts
, other_ts
,
744 this->mark_in
, this->mark_out
, &this->reqid
);
745 if (status
!= SUCCESS
)
749 this->reqid_allocated
= TRUE
;
752 lifetime
= this->config
->get_lifetime(this->config
);
754 now
= time_monotonic(NULL
);
755 if (lifetime
->time
.rekey
)
757 if (this->rekey_time
)
759 this->rekey_time
= min(this->rekey_time
, now
+ lifetime
->time
.rekey
);
763 this->rekey_time
= now
+ lifetime
->time
.rekey
;
766 if (lifetime
->time
.life
)
768 this->expire_time
= now
+ lifetime
->time
.life
;
771 if (!lifetime
->time
.jitter
&& !inbound
)
772 { /* avoid triggering multiple rekey events */
773 lifetime
->time
.rekey
= 0;
776 /* BEET requires the bound address from the traffic selectors */
788 id
= (kernel_ipsec_sa_id_t
){
792 .proto
= proto_ike2ip(this->protocol
),
793 .mark
= inbound ?
this->mark_in
: this->mark_out
,
795 sa
= (kernel_ipsec_add_sa_t
){
796 .reqid
= this->reqid
,
800 .lifetime
= lifetime
,
805 .replay_window
= this->config
->get_replay_window(this->config
),
807 .ipcomp
= this->ipcomp
,
809 .encap
= this->encap
,
811 .initiator
= initiator
,
816 status
= charon
->kernel
->add_sa(charon
->kernel
, &id
, &sa
);
824 * Check kernel interface if policy updates are required
826 static bool require_policy_update()
830 f
= charon
->kernel
->get_features(charon
->kernel
);
831 return !(f
& KERNEL_NO_POLICY_UPDATES
);
835 * Prepare SA config to install/delete policies
837 static void prepare_sa_cfg(private_child_sa_t
*this, ipsec_sa_cfg_t
*my_sa
,
838 ipsec_sa_cfg_t
*other_sa
)
840 enumerator_t
*enumerator
;
842 *my_sa
= (ipsec_sa_cfg_t
){
844 .reqid
= this->reqid
,
846 .transform
= this->ipcomp
,
851 my_sa
->ipcomp
.cpi
= this->my_cpi
;
852 other_sa
->ipcomp
.cpi
= this->other_cpi
;
854 if (this->protocol
== PROTO_ESP
)
856 my_sa
->esp
.use
= TRUE
;
857 my_sa
->esp
.spi
= this->my_spi
;
858 other_sa
->esp
.use
= TRUE
;
859 other_sa
->esp
.spi
= this->other_spi
;
863 my_sa
->ah
.use
= TRUE
;
864 my_sa
->ah
.spi
= this->my_spi
;
865 other_sa
->ah
.use
= TRUE
;
866 other_sa
->ah
.spi
= this->other_spi
;
869 enumerator
= create_policy_enumerator(this);
870 while (enumerator
->enumerate(enumerator
, NULL
, NULL
))
872 my_sa
->policy_count
++;
873 other_sa
->policy_count
++;
875 enumerator
->destroy(enumerator
);
879 * Install 3 policies: out, in and forward
881 static status_t
install_policies_internal(private_child_sa_t
*this,
882 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
883 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
884 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
, policy_priority_t priority
)
886 kernel_ipsec_policy_id_t out_id
= {
890 .mark
= this->mark_out
,
895 .mark
= this->mark_in
,
897 kernel_ipsec_manage_policy_t out_policy
= {
910 status_t status
= SUCCESS
;
912 status
|= charon
->kernel
->add_policy(charon
->kernel
, &out_id
, &out_policy
);
913 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
914 if (this->mode
!= MODE_TRANSPORT
)
916 in_id
.dir
= POLICY_FWD
;
917 status
|= charon
->kernel
->add_policy(charon
->kernel
, &in_id
, &in_policy
);
923 * Delete 3 policies: out, in and forward
925 static void del_policies_internal(private_child_sa_t
*this,
926 host_t
*my_addr
, host_t
*other_addr
, traffic_selector_t
*my_ts
,
927 traffic_selector_t
*other_ts
, ipsec_sa_cfg_t
*my_sa
,
928 ipsec_sa_cfg_t
*other_sa
, policy_type_t type
, policy_priority_t priority
)
930 kernel_ipsec_policy_id_t out_id
= {
934 .mark
= this->mark_out
,
939 .mark
= this->mark_in
,
941 kernel_ipsec_manage_policy_t out_policy
= {
955 charon
->kernel
->del_policy(charon
->kernel
, &out_id
, &out_policy
);
956 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
957 if (this->mode
!= MODE_TRANSPORT
)
959 in_id
.dir
= POLICY_FWD
;
960 charon
->kernel
->del_policy(charon
->kernel
, &in_id
, &in_policy
);
964 METHOD(child_sa_t
, add_policies
, status_t
,
965 private_child_sa_t
*this, linked_list_t
*my_ts_list
,
966 linked_list_t
*other_ts_list
)
968 enumerator_t
*enumerator
;
969 traffic_selector_t
*my_ts
, *other_ts
;
970 status_t status
= SUCCESS
;
972 if (!this->reqid_allocated
&& !this->static_reqid
)
974 /* trap policy, get or confirm reqid */
975 status
= charon
->kernel
->alloc_reqid(
976 charon
->kernel
, my_ts_list
, other_ts_list
,
977 this->mark_in
, this->mark_out
, &this->reqid
);
978 if (status
!= SUCCESS
)
982 this->reqid_allocated
= TRUE
;
985 /* apply traffic selectors */
986 enumerator
= my_ts_list
->create_enumerator(my_ts_list
);
987 while (enumerator
->enumerate(enumerator
, &my_ts
))
989 array_insert(this->my_ts
, ARRAY_TAIL
, my_ts
->clone(my_ts
));
991 enumerator
->destroy(enumerator
);
992 array_sort(this->my_ts
, (void*)traffic_selector_cmp
, NULL
);
994 enumerator
= other_ts_list
->create_enumerator(other_ts_list
);
995 while (enumerator
->enumerate(enumerator
, &other_ts
))
997 array_insert(this->other_ts
, ARRAY_TAIL
, other_ts
->clone(other_ts
));
999 enumerator
->destroy(enumerator
);
1000 array_sort(this->other_ts
, (void*)traffic_selector_cmp
, NULL
);
1002 if (this->config
->install_policy(this->config
))
1004 policy_priority_t priority
;
1005 ipsec_sa_cfg_t my_sa
, other_sa
;
1007 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1009 /* if we're not in state CHILD_INSTALLING (i.e. if there is no SAD
1010 * entry) we install a trap policy */
1011 this->trap
= this->state
== CHILD_CREATED
;
1012 priority
= this->trap ? POLICY_PRIORITY_ROUTED
1013 : POLICY_PRIORITY_DEFAULT
;
1015 /* enumerate pairs of traffic selectors */
1016 enumerator
= create_policy_enumerator(this);
1017 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1019 /* install outbound drop policy to avoid packets leaving unencrypted
1020 * when updating policies */
1021 if (priority
== POLICY_PRIORITY_DEFAULT
&& require_policy_update())
1023 status
|= install_policies_internal(this, this->my_addr
,
1024 this->other_addr
, my_ts
, other_ts
,
1025 &my_sa
, &other_sa
, POLICY_DROP
,
1026 POLICY_PRIORITY_FALLBACK
);
1029 /* install policies */
1030 status
|= install_policies_internal(this, this->my_addr
,
1031 this->other_addr
, my_ts
, other_ts
,
1032 &my_sa
, &other_sa
, POLICY_IPSEC
, priority
);
1034 if (status
!= SUCCESS
)
1039 enumerator
->destroy(enumerator
);
1042 if (status
== SUCCESS
&& this->trap
)
1044 set_state(this, CHILD_ROUTED
);
1050 * Callback to reinstall a virtual IP
1052 static void reinstall_vip(host_t
*vip
, host_t
*me
)
1056 if (charon
->kernel
->get_interface(charon
->kernel
, me
, &iface
))
1058 charon
->kernel
->del_ip(charon
->kernel
, vip
, -1, TRUE
);
1059 charon
->kernel
->add_ip(charon
->kernel
, vip
, -1, iface
);
1064 METHOD(child_sa_t
, update
, status_t
,
1065 private_child_sa_t
*this, host_t
*me
, host_t
*other
, linked_list_t
*vips
,
1068 child_sa_state_t old
;
1069 bool transport_proxy_mode
;
1071 /* anything changed at all? */
1072 if (me
->equals(me
, this->my_addr
) &&
1073 other
->equals(other
, this->other_addr
) && this->encap
== encap
)
1079 set_state(this, CHILD_UPDATING
);
1080 transport_proxy_mode
= this->config
->use_proxy_mode(this->config
) &&
1081 this->mode
== MODE_TRANSPORT
;
1083 if (!transport_proxy_mode
)
1085 /* update our (initiator) SA */
1088 kernel_ipsec_sa_id_t id
= {
1089 .src
= this->other_addr
,
1090 .dst
= this->my_addr
,
1091 .spi
= this->my_spi
,
1092 .proto
= proto_ike2ip(this->protocol
),
1093 .mark
= this->mark_in
,
1095 kernel_ipsec_update_sa_t sa
= {
1096 .cpi
= this->ipcomp
!= IPCOMP_NONE ?
this->my_cpi
: 0,
1099 .encap
= this->encap
,
1102 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1103 &sa
) == NOT_SUPPORTED
)
1105 set_state(this, old
);
1106 return NOT_SUPPORTED
;
1110 /* update his (responder) SA */
1111 if (this->other_spi
)
1113 kernel_ipsec_sa_id_t id
= {
1114 .src
= this->my_addr
,
1115 .dst
= this->other_addr
,
1116 .spi
= this->other_spi
,
1117 .proto
= proto_ike2ip(this->protocol
),
1118 .mark
= this->mark_out
,
1120 kernel_ipsec_update_sa_t sa
= {
1121 .cpi
= this->ipcomp
!= IPCOMP_NONE ?
this->other_cpi
: 0,
1124 .encap
= this->encap
,
1127 if (charon
->kernel
->update_sa(charon
->kernel
, &id
,
1128 &sa
) == NOT_SUPPORTED
)
1130 set_state(this, old
);
1131 return NOT_SUPPORTED
;
1136 if (this->config
->install_policy(this->config
) && require_policy_update())
1138 if (!me
->ip_equals(me
, this->my_addr
) ||
1139 !other
->ip_equals(other
, this->other_addr
))
1141 ipsec_sa_cfg_t my_sa
, other_sa
;
1142 enumerator_t
*enumerator
;
1143 traffic_selector_t
*my_ts
, *other_ts
;
1145 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1147 /* always use high priorities, as hosts getting updated are INSTALLED */
1148 enumerator
= create_policy_enumerator(this);
1149 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1151 traffic_selector_t
*old_my_ts
= NULL
, *old_other_ts
= NULL
;
1152 /* remove old policies first */
1153 del_policies_internal(this, this->my_addr
, this->other_addr
,
1154 my_ts
, other_ts
, &my_sa
, &other_sa
,
1155 POLICY_IPSEC
, POLICY_PRIORITY_DEFAULT
);
1157 /* check if we have to update a "dynamic" traffic selector */
1158 if (!me
->ip_equals(me
, this->my_addr
) &&
1159 my_ts
->is_host(my_ts
, this->my_addr
))
1161 old_my_ts
= my_ts
->clone(my_ts
);
1162 my_ts
->set_address(my_ts
, me
);
1164 if (!other
->ip_equals(other
, this->other_addr
) &&
1165 other_ts
->is_host(other_ts
, this->other_addr
))
1167 old_other_ts
= other_ts
->clone(other_ts
);
1168 other_ts
->set_address(other_ts
, other
);
1171 /* we reinstall the virtual IP to handle interface roaming
1173 vips
->invoke_function(vips
, (void*)reinstall_vip
, me
);
1175 /* reinstall updated policies */
1176 install_policies_internal(this, me
, other
, my_ts
, other_ts
,
1177 &my_sa
, &other_sa
, POLICY_IPSEC
,
1178 POLICY_PRIORITY_DEFAULT
);
1180 /* update fallback policies after the new policy is in place */
1181 del_policies_internal(this, this->my_addr
, this->other_addr
,
1183 old_other_ts ?
: other_ts
,
1184 &my_sa
, &other_sa
, POLICY_DROP
,
1185 POLICY_PRIORITY_FALLBACK
);
1186 install_policies_internal(this, me
, other
, my_ts
, other_ts
,
1187 &my_sa
, &other_sa
, POLICY_DROP
,
1188 POLICY_PRIORITY_FALLBACK
);
1189 DESTROY_IF(old_my_ts
);
1190 DESTROY_IF(old_other_ts
);
1192 enumerator
->destroy(enumerator
);
1196 if (!transport_proxy_mode
)
1199 if (!me
->equals(me
, this->my_addr
))
1201 this->my_addr
->destroy(this->my_addr
);
1202 this->my_addr
= me
->clone(me
);
1204 if (!other
->equals(other
, this->other_addr
))
1206 this->other_addr
->destroy(this->other_addr
);
1207 this->other_addr
= other
->clone(other
);
1211 this->encap
= encap
;
1212 set_state(this, old
);
1217 METHOD(child_sa_t
, destroy
, void,
1218 private_child_sa_t
*this)
1220 enumerator_t
*enumerator
;
1221 traffic_selector_t
*my_ts
, *other_ts
;
1222 policy_priority_t priority
;
1224 priority
= this->trap ? POLICY_PRIORITY_ROUTED
: POLICY_PRIORITY_DEFAULT
;
1226 set_state(this, CHILD_DESTROYING
);
1228 if (this->config
->install_policy(this->config
))
1230 ipsec_sa_cfg_t my_sa
, other_sa
;
1232 prepare_sa_cfg(this, &my_sa
, &other_sa
);
1234 /* delete all policies in the kernel */
1235 enumerator
= create_policy_enumerator(this);
1236 while (enumerator
->enumerate(enumerator
, &my_ts
, &other_ts
))
1238 del_policies_internal(this, this->my_addr
, this->other_addr
,
1239 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_IPSEC
, priority
);
1240 if (priority
== POLICY_PRIORITY_DEFAULT
&& require_policy_update())
1242 del_policies_internal(this, this->my_addr
, this->other_addr
,
1243 my_ts
, other_ts
, &my_sa
, &other_sa
, POLICY_DROP
,
1244 POLICY_PRIORITY_FALLBACK
);
1247 enumerator
->destroy(enumerator
);
1250 /* delete SAs in the kernel, if they are set up */
1253 kernel_ipsec_sa_id_t id
= {
1254 .src
= this->other_addr
,
1255 .dst
= this->my_addr
,
1256 .spi
= this->my_spi
,
1257 .proto
= proto_ike2ip(this->protocol
),
1258 .mark
= this->mark_in
,
1260 kernel_ipsec_del_sa_t sa
= {
1261 .cpi
= this->my_cpi
,
1263 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1265 if (this->other_spi
)
1267 kernel_ipsec_sa_id_t id
= {
1268 .src
= this->my_addr
,
1269 .dst
= this->other_addr
,
1270 .spi
= this->other_spi
,
1271 .proto
= proto_ike2ip(this->protocol
),
1272 .mark
= this->mark_out
,
1274 kernel_ipsec_del_sa_t sa
= {
1275 .cpi
= this->other_cpi
,
1277 charon
->kernel
->del_sa(charon
->kernel
, &id
, &sa
);
1280 if (this->reqid_allocated
)
1282 if (charon
->kernel
->release_reqid(charon
->kernel
,
1283 this->reqid
, this->mark_in
, this->mark_out
) != SUCCESS
)
1285 DBG1(DBG_CHD
, "releasing reqid %u failed", this->reqid
);
1289 array_destroy_offset(this->my_ts
, offsetof(traffic_selector_t
, destroy
));
1290 array_destroy_offset(this->other_ts
, offsetof(traffic_selector_t
, destroy
));
1291 this->my_addr
->destroy(this->my_addr
);
1292 this->other_addr
->destroy(this->other_addr
);
1293 DESTROY_IF(this->proposal
);
1294 this->config
->destroy(this->config
);
1299 * Get proxy address for one side, if any
1301 static host_t
* get_proxy_addr(child_cfg_t
*config
, host_t
*ike
, bool local
)
1303 host_t
*host
= NULL
;
1305 enumerator_t
*enumerator
;
1306 linked_list_t
*ts_list
, *list
;
1307 traffic_selector_t
*ts
;
1309 list
= linked_list_create_with_items(ike
, NULL
);
1310 ts_list
= config
->get_traffic_selectors(config
, local
, NULL
, list
);
1311 list
->destroy(list
);
1313 enumerator
= ts_list
->create_enumerator(ts_list
);
1314 while (enumerator
->enumerate(enumerator
, &ts
))
1316 if (ts
->is_host(ts
, NULL
) && ts
->to_subnet(ts
, &host
, &mask
))
1318 DBG1(DBG_CHD
, "%s address: %H is a transport mode proxy for %H",
1319 local ?
"my" : "other", ike
, host
);
1323 enumerator
->destroy(enumerator
);
1324 ts_list
->destroy_offset(ts_list
, offsetof(traffic_selector_t
, destroy
));
1328 host
= ike
->clone(ike
);
1334 * Described in header.
1336 child_sa_t
* child_sa_create(host_t
*me
, host_t
* other
,
1337 child_cfg_t
*config
, uint32_t rekey
, bool encap
,
1338 u_int mark_in
, u_int mark_out
)
1340 private_child_sa_t
*this;
1341 static refcount_t unique_id
= 0, unique_mark
= 0, mark
;
1345 .get_name
= _get_name
,
1346 .get_reqid
= _get_reqid
,
1347 .get_unique_id
= _get_unique_id
,
1348 .get_config
= _get_config
,
1349 .get_state
= _get_state
,
1350 .set_state
= _set_state
,
1351 .get_spi
= _get_spi
,
1352 .get_cpi
= _get_cpi
,
1353 .get_protocol
= _get_protocol
,
1354 .set_protocol
= _set_protocol
,
1355 .get_mode
= _get_mode
,
1356 .set_mode
= _set_mode
,
1357 .get_proposal
= _get_proposal
,
1358 .set_proposal
= _set_proposal
,
1359 .get_lifetime
= _get_lifetime
,
1360 .get_installtime
= _get_installtime
,
1361 .get_usestats
= _get_usestats
,
1362 .get_mark
= _get_mark
,
1363 .has_encap
= _has_encap
,
1364 .get_ipcomp
= _get_ipcomp
,
1365 .set_ipcomp
= _set_ipcomp
,
1366 .get_close_action
= _get_close_action
,
1367 .set_close_action
= _set_close_action
,
1368 .get_dpd_action
= _get_dpd_action
,
1369 .set_dpd_action
= _set_dpd_action
,
1370 .alloc_spi
= _alloc_spi
,
1371 .alloc_cpi
= _alloc_cpi
,
1372 .install
= _install
,
1374 .add_policies
= _add_policies
,
1375 .create_ts_enumerator
= _create_ts_enumerator
,
1376 .create_policy_enumerator
= _create_policy_enumerator
,
1377 .destroy
= _destroy
,
1380 .ipcomp
= IPCOMP_NONE
,
1381 .state
= CHILD_CREATED
,
1382 .my_ts
= array_create(0, 0),
1383 .other_ts
= array_create(0, 0),
1384 .protocol
= PROTO_NONE
,
1385 .mode
= MODE_TUNNEL
,
1386 .close_action
= config
->get_close_action(config
),
1387 .dpd_action
= config
->get_dpd_action(config
),
1388 .reqid
= config
->get_reqid(config
),
1389 .unique_id
= ref_get(&unique_id
),
1390 .mark_in
= config
->get_mark(config
, TRUE
),
1391 .mark_out
= config
->get_mark(config
, FALSE
),
1392 .install_time
= time_monotonic(NULL
),
1395 this->config
= config
;
1396 config
->get_ref(config
);
1400 this->mark_in
.value
= mark_in
;
1404 this->mark_out
.value
= mark_out
;
1406 if (this->mark_in
.value
== MARK_UNIQUE
||
1407 this->mark_out
.value
== MARK_UNIQUE
)
1409 mark
= ref_get(&unique_mark
);
1410 if (this->mark_in
.value
== MARK_UNIQUE
)
1412 this->mark_in
.value
= mark
;
1414 if (this->mark_out
.value
== MARK_UNIQUE
)
1416 this->mark_out
.value
= mark
;
1422 /* reuse old reqid if we are rekeying an existing CHILD_SA. While the
1423 * reqid cache would find the same reqid for our selectors, this does
1424 * not work in a special case: If an SA is triggered by a trap policy,
1425 * but the negotiated SA gets narrowed, we still must reuse the same
1426 * reqid to successfully "trigger" the SA on the kernel level. Rekeying
1427 * such an SA requires an explicit reqid, as the cache currently knows
1428 * the original selectors only for that reqid. */
1431 this->reqid
= rekey
;
1435 this->reqid
= charon
->traps
->find_reqid(charon
->traps
, config
);
1440 this->static_reqid
= TRUE
;
1443 /* MIPv6 proxy transport mode sets SA endpoints to TS hosts */
1444 if (config
->get_mode(config
) == MODE_TRANSPORT
&&
1445 config
->use_proxy_mode(config
))
1447 this->mode
= MODE_TRANSPORT
;
1449 this->my_addr
= get_proxy_addr(config
, me
, TRUE
);
1450 this->other_addr
= get_proxy_addr(config
, other
, FALSE
);
1454 this->my_addr
= me
->clone(me
);
1455 this->other_addr
= other
->clone(other
);
1457 return &this->public;