support of xfrm marks for IKEv2
This commit is contained in:
parent
02571374c4
commit
ee26c537d7
|
@ -114,10 +114,19 @@ struct private_child_cfg_t {
|
|||
u_int32_t inactivity;
|
||||
|
||||
/**
|
||||
* Reqid to install CHIL_SA with
|
||||
* Reqid to install CHILD_SA with
|
||||
*/
|
||||
u_int32_t reqid;
|
||||
|
||||
/**
|
||||
* Optional mark to install inbound CHILD_SA with
|
||||
*/
|
||||
mark_t mark_in;
|
||||
|
||||
/**
|
||||
* Optional mark to install outbound CHILD_SA with
|
||||
*/
|
||||
mark_t mark_out;
|
||||
/**
|
||||
* set up IPsec transport SA in MIPv6 proxy mode
|
||||
*/
|
||||
|
@ -460,6 +469,14 @@ static u_int32_t get_reqid(private_child_cfg_t *this)
|
|||
return this->reqid;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_cfg_t.get_mark.
|
||||
*/
|
||||
static mark_t get_mark(private_child_cfg_t *this, bool inbound)
|
||||
{
|
||||
return inbound ? this->mark_in : this->mark_out;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of child_cfg_t.set_mipv6_options.
|
||||
*/
|
||||
|
@ -521,7 +538,8 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
|
|||
char *updown, bool hostaccess,
|
||||
ipsec_mode_t mode, action_t dpd_action,
|
||||
action_t close_action, bool ipcomp,
|
||||
u_int32_t inactivity, u_int32_t reqid)
|
||||
u_int32_t inactivity, u_int32_t reqid,
|
||||
mark_t *mark)
|
||||
{
|
||||
private_child_cfg_t *this = malloc_thing(private_child_cfg_t);
|
||||
|
||||
|
@ -542,6 +560,7 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
|
|||
this->public.use_ipcomp = (bool (*) (child_cfg_t *))use_ipcomp;
|
||||
this->public.get_inactivity = (u_int32_t (*) (child_cfg_t *))get_inactivity;
|
||||
this->public.get_reqid = (u_int32_t (*) (child_cfg_t *))get_reqid;
|
||||
this->public.get_mark = (mark_t (*) (child_cfg_t *,bool))get_mark;
|
||||
this->public.use_proxy_mode = (bool (*) (child_cfg_t *))use_proxy_mode;
|
||||
this->public.install_policy = (bool (*) (child_cfg_t *))install_policy;
|
||||
this->public.get_ref = (child_cfg_t* (*) (child_cfg_t*))get_ref;
|
||||
|
@ -556,6 +575,21 @@ child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
|
|||
this->use_ipcomp = ipcomp;
|
||||
this->inactivity = inactivity;
|
||||
this->reqid = reqid;
|
||||
|
||||
/* TODO configure separate inbound and outbound marks */
|
||||
if (mark)
|
||||
{
|
||||
this->mark_in = *mark;
|
||||
this->mark_out = *mark;
|
||||
}
|
||||
else
|
||||
{
|
||||
this->mark_in.value = 0;
|
||||
this->mark_in.mask = 0;
|
||||
this->mark_out.value = 0;
|
||||
this->mark_out.mask = 0;
|
||||
}
|
||||
|
||||
this->proxy_mode = FALSE;
|
||||
this->install_policy = TRUE;
|
||||
this->refcount = 1;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
typedef enum action_t action_t;
|
||||
typedef enum ipcomp_transform_t ipcomp_transform_t;
|
||||
typedef struct lifetime_cfg_t lifetime_cfg_t;
|
||||
typedef struct mark_t mark_t;
|
||||
typedef struct child_cfg_t child_cfg_t;
|
||||
|
||||
#include <library.h>
|
||||
|
@ -82,6 +83,16 @@ struct lifetime_cfg_t {
|
|||
} time, bytes, packets;
|
||||
};
|
||||
|
||||
/**
|
||||
* A mark_t defines an optional mark in a CHILD_SA.
|
||||
*/
|
||||
struct mark_t {
|
||||
/** Mark value */
|
||||
u_int32_t value;
|
||||
/** Mark mask */
|
||||
u_int32_t mask;
|
||||
};
|
||||
|
||||
/**
|
||||
* A child_cfg_t defines the config template for a CHILD_SA.
|
||||
*
|
||||
|
@ -245,6 +256,14 @@ struct child_cfg_t {
|
|||
*/
|
||||
u_int32_t (*get_reqid)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Optional mark for CHILD_SA
|
||||
*
|
||||
* @param inbound TRUE for inbound, FALSE for outbound
|
||||
* @return mark
|
||||
*/
|
||||
mark_t (*get_mark)(child_cfg_t *this, bool inbound);
|
||||
|
||||
/**
|
||||
* Sets two options needed for Mobile IPv6 interoperability
|
||||
*
|
||||
|
@ -307,12 +326,14 @@ struct child_cfg_t {
|
|||
* @param ipcomp use IPComp, if peer supports it
|
||||
* @param inactivity inactivity timeout in s before closing a CHILD_SA
|
||||
* @param reqid specific reqid to use for CHILD_SA, 0 for auto assign
|
||||
* @param mark optional mark (can be NULL)
|
||||
* @return child_cfg_t object
|
||||
*/
|
||||
child_cfg_t *child_cfg_create(char *name, lifetime_cfg_t *lifetime,
|
||||
char *updown, bool hostaccess,
|
||||
ipsec_mode_t mode, action_t dpd_action,
|
||||
action_t close_action, bool ipcomp,
|
||||
u_int32_t inactivity, u_int32_t reqid);
|
||||
u_int32_t inactivity, u_int32_t reqid,
|
||||
mark_t *mark);
|
||||
|
||||
#endif /** CHILD_CFG_H_ @}*/
|
||||
|
|
|
@ -67,8 +67,8 @@ METHOD(kernel_interface_t, get_cpi, status_t,
|
|||
METHOD(kernel_interface_t, add_sa, status_t,
|
||||
private_kernel_interface_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int32_t reqid,
|
||||
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
mark_t mark, lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool encap, bool inbound, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts)
|
||||
{
|
||||
|
@ -77,82 +77,84 @@ METHOD(kernel_interface_t, add_sa, status_t,
|
|||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->add_sa(this->ipsec, src, dst, spi, protocol, reqid,
|
||||
lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp, cpi,
|
||||
encap, inbound, src_ts, dst_ts);
|
||||
mark, lifetime, enc_alg, enc_key, int_alg, int_key, mode, ipcomp,
|
||||
cpi, encap, inbound, src_ts, dst_ts);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, update_sa, status_t,
|
||||
private_kernel_interface_t *this, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap)
|
||||
bool encap, bool new_encap, mark_t mark)
|
||||
{
|
||||
if (!this->ipsec)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->update_sa(this->ipsec, spi, protocol, cpi, src, dst,
|
||||
new_src, new_dst, encap, new_encap);
|
||||
new_src, new_dst, encap, new_encap, mark);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, query_sa, status_t,
|
||||
private_kernel_interface_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
|
||||
u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
|
||||
{
|
||||
if (!this->ipsec)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, bytes);
|
||||
return this->ipsec->query_sa(this->ipsec, src, dst, spi, protocol, mark, bytes);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, del_sa, status_t,
|
||||
private_kernel_interface_t *this, host_t *src, host_t *dst, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int16_t cpi)
|
||||
protocol_id_t protocol, u_int16_t cpi, mark_t mark)
|
||||
{
|
||||
if (!this->ipsec)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi);
|
||||
return this->ipsec->del_sa(this->ipsec, src, dst, spi, protocol, cpi, mark);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, add_policy, status_t,
|
||||
private_kernel_interface_t *this, host_t *src, host_t *dst,
|
||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
bool routed)
|
||||
u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool routed)
|
||||
{
|
||||
if (!this->ipsec)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->add_policy(this->ipsec, src, dst, src_ts, dst_ts,
|
||||
direction, spi, protocol, reqid, mode, ipcomp, cpi, routed);
|
||||
direction, spi, protocol, reqid, mark, mode, ipcomp, cpi, routed);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, query_policy, status_t,
|
||||
private_kernel_interface_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
u_int32_t *use_time)
|
||||
{
|
||||
if (!this->ipsec)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->query_policy(this->ipsec, src_ts, dst_ts,
|
||||
direction, use_time);
|
||||
direction, mark, use_time);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, del_policy, status_t,
|
||||
private_kernel_interface_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
bool unrouted)
|
||||
{
|
||||
if (!this->ipsec)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
return this->ipsec->del_policy(this->ipsec, src_ts, dst_ts,
|
||||
direction, unrouted);
|
||||
direction, mark, unrouted);
|
||||
}
|
||||
|
||||
METHOD(kernel_interface_t, get_source_addr, host_t*,
|
||||
|
|
|
@ -90,6 +90,7 @@ struct kernel_interface_t {
|
|||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param reqid unique ID for this SA
|
||||
* @param mark optional mark for this SA
|
||||
* @param lifetime lifetime_cfg_t for this SA
|
||||
* @param enc_alg Algorithm to use for encryption (ESP only)
|
||||
* @param enc_key key to use for encryption
|
||||
|
@ -106,7 +107,7 @@ struct kernel_interface_t {
|
|||
*/
|
||||
status_t (*add_sa) (kernel_interface_t *this,
|
||||
host_t *src, host_t *dst, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int32_t reqid,
|
||||
protocol_id_t protocol, u_int32_t reqid, mark_t mark,
|
||||
lifetime_cfg_t *lifetime,
|
||||
u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key,
|
||||
|
@ -131,6 +132,7 @@ struct kernel_interface_t {
|
|||
* @param new_dst new destination address
|
||||
* @param encap current use of UDP encapsulation
|
||||
* @param new_encap new use of UDP encapsulation
|
||||
* @param mark optional mark for this SA
|
||||
* @return SUCCESS if operation completed, NOT_SUPPORTED if
|
||||
* the kernel interface can't update the SA
|
||||
*/
|
||||
|
@ -138,7 +140,7 @@ struct kernel_interface_t {
|
|||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
|
||||
host_t *src, host_t *dst,
|
||||
host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap);
|
||||
bool encap, bool new_encap, mark_t mark);
|
||||
|
||||
/**
|
||||
* Query the number of bytes processed by an SA from the SAD.
|
||||
|
@ -147,11 +149,13 @@ struct kernel_interface_t {
|
|||
* @param dst destination address for this SA
|
||||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param mark optional mark for this SA
|
||||
* @param[out] bytes the number of bytes processed by SA
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*query_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes);
|
||||
u_int32_t spi, protocol_id_t protocol, mark_t mark,
|
||||
u_int64_t *bytes);
|
||||
|
||||
/**
|
||||
* Delete a previously installed SA from the SAD.
|
||||
|
@ -161,10 +165,12 @@ struct kernel_interface_t {
|
|||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param cpi CPI for IPComp or 0
|
||||
* @param mark optional mark for this SA
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*del_sa) (kernel_interface_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi);
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
|
||||
mark_t mark);
|
||||
|
||||
/**
|
||||
* Add a policy to the SPD.
|
||||
|
@ -180,6 +186,7 @@ struct kernel_interface_t {
|
|||
* @param spi SPI of SA
|
||||
* @param protocol protocol to use to protect traffic (AH/ESP)
|
||||
* @param reqid unique ID of an SA to use to enforce policy
|
||||
* @param mark mark for this policy
|
||||
* @param mode mode of SA (tunnel, transport)
|
||||
* @param ipcomp the IPComp transform used
|
||||
* @param cpi CPI for IPComp
|
||||
|
@ -192,8 +199,8 @@ struct kernel_interface_t {
|
|||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int32_t reqid,
|
||||
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
bool routed);
|
||||
mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool routed);
|
||||
|
||||
/**
|
||||
* Query the use time of a policy.
|
||||
|
@ -204,13 +211,15 @@ struct kernel_interface_t {
|
|||
* @param src_ts traffic selector to match traffic source
|
||||
* @param dst_ts traffic selector to match traffic dest
|
||||
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||
* @param mark optional mark
|
||||
* @param[out] use_time the time of this SA's last use
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*query_policy) (kernel_interface_t *this,
|
||||
traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t *use_time);
|
||||
policy_dir_t direction, mark_t mark,
|
||||
u_int32_t *use_time);
|
||||
|
||||
/**
|
||||
* Remove a policy from the SPD.
|
||||
|
@ -223,13 +232,14 @@ struct kernel_interface_t {
|
|||
* @param src_ts traffic selector to match traffic source
|
||||
* @param dst_ts traffic selector to match traffic dest
|
||||
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||
* @param mark optional mark
|
||||
* @param unrouted TRUE, if this policy is unrouted from the kernel
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*del_policy) (kernel_interface_t *this,
|
||||
traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction,
|
||||
policy_dir_t direction, mark_t mark,
|
||||
bool unrouted);
|
||||
|
||||
/**
|
||||
|
|
|
@ -121,6 +121,7 @@ struct kernel_ipsec_t {
|
|||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param reqid unique ID for this SA
|
||||
* @param mark mark for this SA
|
||||
* @param lifetime lifetime_cfg_t for this SA
|
||||
* @param enc_alg Algorithm to use for encryption (ESP only)
|
||||
* @param enc_key key to use for encryption
|
||||
|
@ -138,7 +139,7 @@ struct kernel_ipsec_t {
|
|||
status_t (*add_sa) (kernel_ipsec_t *this,
|
||||
host_t *src, host_t *dst, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int32_t reqid,
|
||||
lifetime_cfg_t *lifetime,
|
||||
mark_t mark, lifetime_cfg_t *lifetime,
|
||||
u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key,
|
||||
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
|
@ -162,6 +163,7 @@ struct kernel_ipsec_t {
|
|||
* @param new_dst new destination address
|
||||
* @param encap current use of UDP encapsulation
|
||||
* @param new_encap new use of UDP encapsulation
|
||||
* @param mark optional mark for this SA
|
||||
* @return SUCCESS if operation completed, NOT_SUPPORTED if
|
||||
* the kernel interface can't update the SA
|
||||
*/
|
||||
|
@ -169,7 +171,7 @@ struct kernel_ipsec_t {
|
|||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
|
||||
host_t *src, host_t *dst,
|
||||
host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap);
|
||||
bool encap, bool new_encap, mark_t mark);
|
||||
|
||||
/**
|
||||
* Query the number of bytes processed by an SA from the SAD.
|
||||
|
@ -178,11 +180,13 @@ struct kernel_ipsec_t {
|
|||
* @param dst destination address for this SA
|
||||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param mark optional mark for this SA
|
||||
* @param[out] bytes the number of bytes processed by SA
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*query_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes);
|
||||
u_int32_t spi, protocol_id_t protocol, mark_t mark,
|
||||
u_int64_t *bytes);
|
||||
|
||||
/**
|
||||
* Delete a previusly installed SA from the SAD.
|
||||
|
@ -192,10 +196,12 @@ struct kernel_ipsec_t {
|
|||
* @param spi SPI allocated by us or remote peer
|
||||
* @param protocol protocol for this SA (ESP/AH)
|
||||
* @param cpi CPI for IPComp or 0
|
||||
* @param mark optional mark for this SA
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*del_sa) (kernel_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi);
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi,
|
||||
mark_t mark);
|
||||
|
||||
/**
|
||||
* Add a policy to the SPD.
|
||||
|
@ -211,6 +217,7 @@ struct kernel_ipsec_t {
|
|||
* @param spi SPI of SA
|
||||
* @param protocol protocol to use to protect traffic (AH/ESP)
|
||||
* @param reqid unique ID of an SA to use to enforce policy
|
||||
* @param mark mark for this policy
|
||||
* @param mode mode of SA (tunnel, transport)
|
||||
* @param ipcomp the IPComp transform used
|
||||
* @param cpi CPI for IPComp
|
||||
|
@ -223,8 +230,8 @@ struct kernel_ipsec_t {
|
|||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int32_t reqid,
|
||||
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
bool routed);
|
||||
mark_t mark, ipsec_mode_t mode,
|
||||
u_int16_t ipcomp, u_int16_t cpi, bool routed);
|
||||
|
||||
/**
|
||||
* Query the use time of a policy.
|
||||
|
@ -236,13 +243,15 @@ struct kernel_ipsec_t {
|
|||
* @param src_ts traffic selector to match traffic source
|
||||
* @param dst_ts traffic selector to match traffic dest
|
||||
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||
* @param mark optional mark
|
||||
* @param[out] use_time the monotonic timestamp of this SA's last use
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*query_policy) (kernel_ipsec_t *this,
|
||||
traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t *use_time);
|
||||
policy_dir_t direction, mark_t mark,
|
||||
u_int32_t *use_time);
|
||||
|
||||
/**
|
||||
* Remove a policy from the SPD.
|
||||
|
@ -255,13 +264,14 @@ struct kernel_ipsec_t {
|
|||
* @param src_ts traffic selector to match traffic source
|
||||
* @param dst_ts traffic selector to match traffic dest
|
||||
* @param direction direction of traffic, POLICY_IN, POLICY_OUT, POLICY_FWD
|
||||
* @param mark optional mark
|
||||
* @param unrouted TRUE, if this policy is unrouted from the kernel
|
||||
* @return SUCCESS if operation completed
|
||||
*/
|
||||
status_t (*del_policy) (kernel_ipsec_t *this,
|
||||
traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction,
|
||||
policy_dir_t direction, mark_t mark,
|
||||
bool unrouted);
|
||||
|
||||
/**
|
||||
|
|
|
@ -291,7 +291,7 @@ static job_requeue_t initiate(private_android_service_t *this)
|
|||
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
|
||||
|
||||
child_cfg = child_cfg_create("android", &lifetime, NULL, TRUE, MODE_TUNNEL,
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
|
||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
||||
ts = traffic_selector_create_dynamic(0, 0, 65535);
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
|
||||
|
|
|
@ -233,8 +233,8 @@ static void setup_tunnel(private_ha_tunnel_t *this,
|
|||
identification_create_from_string(remote));
|
||||
peer_cfg->add_auth_cfg(peer_cfg, auth_cfg, FALSE);
|
||||
|
||||
child_cfg = child_cfg_create("ha", &lifetime, NULL, TRUE,
|
||||
MODE_TRANSPORT, ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
|
||||
child_cfg = child_cfg_create("ha", &lifetime, NULL, TRUE, MODE_TRANSPORT,
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
|
||||
ts = traffic_selector_create_dynamic(IPPROTO_UDP, HA_PORT, HA_PORT);
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
|
||||
ts = traffic_selector_create_dynamic(IPPROTO_ICMP, 0, 65535);
|
||||
|
|
|
@ -1690,10 +1690,11 @@ static status_t group_ipip_sa(private_kernel_klips_ipsec_t *this,
|
|||
|
||||
METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int32_t reqid, lifetime_cfg_t *lifetime,
|
||||
u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key,
|
||||
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool encap,
|
||||
bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
|
||||
protocol_id_t protocol, u_int32_t reqid, mark_t mark,
|
||||
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
|
||||
u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
|
||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1849,7 +1850,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
private_kernel_klips_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap)
|
||||
bool encap, bool new_encap, mark_t mark)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1920,14 +1921,14 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
|
||||
u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
|
||||
{
|
||||
return NOT_SUPPORTED; /* TODO */
|
||||
}
|
||||
|
||||
METHOD(kernel_ipsec_t, del_sa, status_t,
|
||||
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1992,8 +1993,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
private_kernel_klips_ipsec_t *this, host_t *src, host_t *dst,
|
||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
bool routed)
|
||||
u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool routed)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -2210,7 +2211,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, query_policy, status_t,
|
||||
private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
u_int32_t *use_time)
|
||||
{
|
||||
#define IDLE_PREFIX "idle="
|
||||
static const char *path_eroute = "/proc/net/ipsec_eroute";
|
||||
|
@ -2365,7 +2367,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, del_policy, status_t,
|
||||
private_kernel_klips_ipsec_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
bool unrouted)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg = (struct sadb_msg*)request, *out;
|
||||
|
@ -2574,7 +2577,7 @@ METHOD(kernel_ipsec_t, destroy, void,
|
|||
{
|
||||
close(this->socket);
|
||||
}
|
||||
if (this->socket_evnets > 0)
|
||||
if (this->socket_events > 0)
|
||||
{
|
||||
close(this->socket_events);
|
||||
}
|
||||
|
|
|
@ -280,6 +280,9 @@ struct policy_entry_t {
|
|||
/** parameters of installed policy */
|
||||
struct xfrm_selector sel;
|
||||
|
||||
/** optional mark */
|
||||
u_int32_t mark;
|
||||
|
||||
/** associated route installed for this policy */
|
||||
route_entry_t *route;
|
||||
|
||||
|
@ -292,7 +295,8 @@ struct policy_entry_t {
|
|||
*/
|
||||
static u_int policy_hash(policy_entry_t *key)
|
||||
{
|
||||
chunk_t chunk = chunk_create((void*)&key->sel, sizeof(struct xfrm_selector));
|
||||
chunk_t chunk = chunk_create((void*)&key->sel,
|
||||
sizeof(struct xfrm_selector) + sizeof(u_int32_t));
|
||||
return chunk_hash(chunk);
|
||||
}
|
||||
|
||||
|
@ -301,7 +305,8 @@ static u_int policy_hash(policy_entry_t *key)
|
|||
*/
|
||||
static bool policy_equals(policy_entry_t *key, policy_entry_t *other_key)
|
||||
{
|
||||
return memeq(&key->sel, &other_key->sel, sizeof(struct xfrm_selector)) &&
|
||||
return memeq(&key->sel, &other_key->sel,
|
||||
sizeof(struct xfrm_selector) + sizeof(u_int32_t)) &&
|
||||
key->direction == other_key->direction;
|
||||
}
|
||||
|
||||
|
@ -917,11 +922,11 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int32_t reqid,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int32_t reqid, mark_t mark,
|
||||
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool encap, bool inbound, traffic_selector_t* src_ts,
|
||||
traffic_selector_t* dst_ts)
|
||||
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool encap, bool inbound,
|
||||
traffic_selector_t* src_ts, traffic_selector_t* dst_ts)
|
||||
{
|
||||
netlink_buf_t request;
|
||||
char *alg_name;
|
||||
|
@ -934,8 +939,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
if (ipcomp != IPCOMP_NONE && cpi != 0)
|
||||
{
|
||||
lifetime_cfg_t lft = {{0,0,0},{0,0,0},{0,0,0}};
|
||||
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, &lft,
|
||||
ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
|
||||
add_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, reqid, mark,
|
||||
&lft, ENCR_UNDEFINED, chunk_empty, AUTH_UNDEFINED, chunk_empty,
|
||||
mode, ipcomp, 0, FALSE, inbound, NULL, NULL);
|
||||
ipcomp = IPCOMP_NONE;
|
||||
/* use transport mode ESP SA, IPComp uses tunnel mode */
|
||||
|
@ -944,9 +949,16 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
|
||||
ntohl(spi), reqid);
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u} "
|
||||
"(mark %u/0x%8x)", ntohl(spi), reqid, mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "adding SAD entry with SPI %.8x and reqid {%u}",
|
||||
ntohl(spi), reqid);
|
||||
}
|
||||
hdr = (struct nlmsghdr*)request;
|
||||
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
hdr->nlmsg_type = inbound ? XFRM_MSG_UPDSA : XFRM_MSG_NEWSA;
|
||||
|
@ -1151,6 +1163,8 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
|
||||
if (encap)
|
||||
{
|
||||
struct xfrm_encap_tmpl *tmpl;
|
||||
|
||||
rthdr->rta_type = XFRMA_ENCAP;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_encap_tmpl));
|
||||
|
||||
|
@ -1160,7 +1174,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
return FAILED;
|
||||
}
|
||||
|
||||
struct xfrm_encap_tmpl* tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
|
||||
tmpl = (struct xfrm_encap_tmpl*)RTA_DATA(rthdr);
|
||||
tmpl->encap_type = UDP_ENCAP_ESPINUDP;
|
||||
tmpl->encap_sport = htons(src->get_port(src));
|
||||
tmpl->encap_dport = htons(dst->get_port(dst));
|
||||
|
@ -1177,9 +1191,36 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
rthdr = XFRM_RTA_NEXT(rthdr);
|
||||
}
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
struct xfrm_mark *mrk;
|
||||
|
||||
rthdr->rta_type = XFRMA_MARK;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
|
||||
|
||||
hdr->nlmsg_len += rthdr->rta_len;
|
||||
if (hdr->nlmsg_len > sizeof(request))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
|
||||
mrk->v = mark.value;
|
||||
mrk->m = mark.mask;
|
||||
rthdr = XFRM_RTA_NEXT(rthdr);
|
||||
}
|
||||
|
||||
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
|
||||
if (mark.value)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x "
|
||||
"(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to add SAD entry with SPI %.8x", ntohl(spi));
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
return SUCCESS;
|
||||
|
@ -1275,7 +1316,7 @@ static status_t get_replay_state(private_kernel_netlink_ipsec_t *this,
|
|||
|
||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
|
||||
u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
|
||||
{
|
||||
netlink_buf_t request;
|
||||
struct nlmsghdr *out = NULL, *hdr;
|
||||
|
@ -1285,8 +1326,15 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
|||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "querying SAD entry with SPI %.8x (mark %u/0x%8x)",
|
||||
ntohl(spi), mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "querying SAD entry with SPI %.8x", ntohl(spi));
|
||||
}
|
||||
hdr = (struct nlmsghdr*)request;
|
||||
hdr->nlmsg_flags = NLM_F_REQUEST;
|
||||
hdr->nlmsg_type = XFRM_MSG_GETSA;
|
||||
|
@ -1298,6 +1346,24 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
|||
sa_id->proto = proto_ike2kernel(protocol);
|
||||
sa_id->family = dst->get_family(dst);
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
struct xfrm_mark *mrk;
|
||||
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id);
|
||||
|
||||
rthdr->rta_type = XFRMA_MARK;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
|
||||
hdr->nlmsg_len += rthdr->rta_len;
|
||||
if (hdr->nlmsg_len > sizeof(request))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
|
||||
mrk->v = mark.value;
|
||||
mrk->m = mark.mask;
|
||||
}
|
||||
|
||||
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
||||
{
|
||||
hdr = out;
|
||||
|
@ -1313,8 +1379,20 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
|||
case NLMSG_ERROR:
|
||||
{
|
||||
struct nlmsgerr *err = NLMSG_DATA(hdr);
|
||||
DBG1(DBG_KNL, "querying SAD entry with SPI %.8x failed: %s (%d)",
|
||||
ntohl(spi), strerror(-err->error), -err->error);
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
DBG1(DBG_KNL, "querying SAD entry with SPI %.8x "
|
||||
"(mark %u/0x%8x) failed: %s (%d)",
|
||||
ntohl(spi), mark.value, mark.mask,
|
||||
strerror(-err->error), -err->error);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_KNL, "querying SAD entry with SPI %.8x "
|
||||
"failed: %s (%d)", ntohl(spi),
|
||||
strerror(-err->error), -err->error);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -1341,7 +1419,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, del_sa, status_t,
|
||||
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
|
||||
{
|
||||
netlink_buf_t request;
|
||||
struct nlmsghdr *hdr;
|
||||
|
@ -1350,13 +1428,20 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
|
|||
/* if IPComp was used, we first delete the additional IPComp SA */
|
||||
if (cpi)
|
||||
{
|
||||
del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0);
|
||||
del_sa(this, src, dst, htonl(ntohs(cpi)), IPPROTO_COMP, 0, mark);
|
||||
}
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x (mark %u/0x%8x)",
|
||||
ntohl(spi), mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "deleting SAD entry with SPI %.8x", ntohl(spi));
|
||||
}
|
||||
hdr = (struct nlmsghdr*)request;
|
||||
hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK;
|
||||
hdr->nlmsg_type = XFRM_MSG_DELSA;
|
||||
|
@ -1368,19 +1453,53 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
|
|||
sa_id->proto = proto_ike2kernel(protocol);
|
||||
sa_id->family = dst->get_family(dst);
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
struct xfrm_mark *mrk;
|
||||
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_usersa_id);
|
||||
|
||||
rthdr->rta_type = XFRMA_MARK;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
|
||||
hdr->nlmsg_len += rthdr->rta_len;
|
||||
if (hdr->nlmsg_len > sizeof(request))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
|
||||
mrk->v = mark.value;
|
||||
mrk->m = mark.mask;
|
||||
}
|
||||
|
||||
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
|
||||
if (mark.value)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x "
|
||||
"(mark %u/0x%8x)", ntohl(spi), mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete SAD entry with SPI %.8x", ntohl(spi));
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x (mark %u/0x%8x)",
|
||||
ntohl(spi), mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "deleted SAD entry with SPI %.8x", ntohl(spi));
|
||||
}
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
private_kernel_netlink_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
|
||||
bool old_encap, bool new_encap)
|
||||
bool old_encap, bool new_encap, mark_t mark)
|
||||
{
|
||||
netlink_buf_t request;
|
||||
u_char *pos;
|
||||
|
@ -1398,7 +1517,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
|||
if (cpi)
|
||||
{
|
||||
update_sa(this, htonl(ntohs(cpi)), IPPROTO_COMP, 0,
|
||||
src, dst, new_src, new_dst, FALSE, FALSE);
|
||||
src, dst, new_src, new_dst, FALSE, FALSE, mark);
|
||||
}
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
@ -1459,7 +1578,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
|||
}
|
||||
|
||||
/* delete the old SA (without affecting the IPComp SA) */
|
||||
if (del_sa(this, src, dst, spi, protocol, 0) != SUCCESS)
|
||||
if (del_sa(this, src, dst, spi, protocol, 0, mark) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete old SAD entry with SPI %.8x", ntohl(spi));
|
||||
free(out);
|
||||
|
@ -1558,8 +1677,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
private_kernel_netlink_ipsec_t *this, host_t *src, host_t *dst,
|
||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
bool routed)
|
||||
u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool routed)
|
||||
{
|
||||
policy_entry_t *current, *policy;
|
||||
bool found = FALSE;
|
||||
|
@ -1571,6 +1690,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
policy = malloc_thing(policy_entry_t);
|
||||
memset(policy, 0, sizeof(policy_entry_t));
|
||||
policy->sel = ts2selector(src_ts, dst_ts);
|
||||
policy->mark = mark.value & mark.mask;
|
||||
policy->direction = direction;
|
||||
|
||||
/* find the policy, which matches EXACTLY */
|
||||
|
@ -1580,9 +1700,19 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
{
|
||||
/* use existing policy */
|
||||
current->refcount++;
|
||||
DBG2(DBG_KNL, "policy %R === %R %N already exists, increasing "
|
||||
"refcount", src_ts, dst_ts,
|
||||
policy_dir_names, direction);
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "policy %R === %R %N (mark %u/0x%8x) "
|
||||
"already exists, increasing refcount",
|
||||
src_ts, dst_ts, policy_dir_names, direction,
|
||||
mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "policy %R === %R %N "
|
||||
"already exists, increasing refcount",
|
||||
src_ts, dst_ts, policy_dir_names, direction);
|
||||
}
|
||||
free(policy);
|
||||
policy = current;
|
||||
found = TRUE;
|
||||
|
@ -1593,8 +1723,17 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
policy->refcount = 1;
|
||||
}
|
||||
|
||||
DBG2(DBG_KNL, "adding policy %R === %R %N", src_ts, dst_ts,
|
||||
policy_dir_names, direction);
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "adding policy %R === %R %N (mark %u/0x%8x)",
|
||||
src_ts, dst_ts, policy_dir_names, direction,
|
||||
mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "adding policy %R === %R %N",
|
||||
src_ts, dst_ts, policy_dir_names, direction);
|
||||
}
|
||||
|
||||
memset(&request, 0, sizeof(request));
|
||||
hdr = (struct nlmsghdr*)request;
|
||||
|
@ -1673,6 +1812,25 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
tmpl->aalgos = tmpl->ealgos = tmpl->calgos = ~0;
|
||||
tmpl->mode = mode2kernel(mode);
|
||||
tmpl->family = src->get_family(src);
|
||||
rthdr = XFRM_RTA_NEXT(rthdr);
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
struct xfrm_mark *mrk;
|
||||
|
||||
rthdr->rta_type = XFRMA_MARK;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
|
||||
|
||||
hdr->nlmsg_len += rthdr->rta_len;
|
||||
if (hdr->nlmsg_len > sizeof(request))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
|
||||
mrk->v = mark.value;
|
||||
mrk->m = mark.mask;
|
||||
}
|
||||
|
||||
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
|
||||
{
|
||||
|
@ -1741,7 +1899,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, query_policy, status_t,
|
||||
private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
u_int32_t *use_time)
|
||||
{
|
||||
netlink_buf_t request;
|
||||
struct nlmsghdr *out = NULL, *hdr;
|
||||
|
@ -1751,9 +1910,17 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
|||
|
||||
memset(&request, 0, sizeof(request));
|
||||
|
||||
DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
|
||||
policy_dir_names, direction);
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "querying policy %R === %R %N (mark %u/0x%8x)",
|
||||
src_ts, dst_ts, policy_dir_names, direction,
|
||||
mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "querying policy %R === %R %N", src_ts, dst_ts,
|
||||
policy_dir_names, direction);
|
||||
}
|
||||
hdr = (struct nlmsghdr*)request;
|
||||
hdr->nlmsg_flags = NLM_F_REQUEST;
|
||||
hdr->nlmsg_type = XFRM_MSG_GETPOLICY;
|
||||
|
@ -1763,6 +1930,25 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
|||
policy_id->sel = ts2selector(src_ts, dst_ts);
|
||||
policy_id->dir = direction;
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
struct xfrm_mark *mrk;
|
||||
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
|
||||
|
||||
rthdr->rta_type = XFRMA_MARK;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
|
||||
|
||||
hdr->nlmsg_len += rthdr->rta_len;
|
||||
if (hdr->nlmsg_len > sizeof(request))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
|
||||
mrk->v = mark.value;
|
||||
mrk->m = mark.mask;
|
||||
}
|
||||
|
||||
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
||||
{
|
||||
hdr = out;
|
||||
|
@ -1816,7 +2002,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, del_policy, status_t,
|
||||
private_kernel_netlink_ipsec_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
bool unrouted)
|
||||
{
|
||||
policy_entry_t *current, policy, *to_delete = NULL;
|
||||
route_entry_t *route;
|
||||
|
@ -1824,12 +2011,22 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
struct nlmsghdr *hdr;
|
||||
struct xfrm_userpolicy_id *policy_id;
|
||||
|
||||
DBG2(DBG_KNL, "deleting policy %R === %R %N", src_ts, dst_ts,
|
||||
policy_dir_names, direction);
|
||||
if (mark.value)
|
||||
{
|
||||
DBG2(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x)",
|
||||
src_ts, dst_ts, policy_dir_names, direction,
|
||||
mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG2(DBG_KNL, "deleting policy %R === %R %N",
|
||||
src_ts, dst_ts, policy_dir_names, direction);
|
||||
}
|
||||
|
||||
/* create a policy */
|
||||
memset(&policy, 0, sizeof(policy_entry_t));
|
||||
policy.sel = ts2selector(src_ts, dst_ts);
|
||||
policy.mark = mark.value & mark.mask;
|
||||
policy.direction = direction;
|
||||
|
||||
/* find the policy */
|
||||
|
@ -1851,8 +2048,17 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
this->mutex->unlock(this->mutex);
|
||||
if (!to_delete)
|
||||
{
|
||||
DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found", src_ts,
|
||||
dst_ts, policy_dir_names, direction);
|
||||
if (mark.value)
|
||||
{
|
||||
DBG1(DBG_KNL, "deleting policy %R === %R %N (mark %u/0x%8x) "
|
||||
"failed, not found", src_ts, dst_ts, policy_dir_names,
|
||||
direction, mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_KNL, "deleting policy %R === %R %N failed, not found",
|
||||
src_ts, dst_ts, policy_dir_names, direction);
|
||||
}
|
||||
return NOT_FOUND;
|
||||
}
|
||||
|
||||
|
@ -1867,13 +2073,40 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
|||
policy_id->sel = to_delete->sel;
|
||||
policy_id->dir = direction;
|
||||
|
||||
if (mark.value)
|
||||
{
|
||||
struct xfrm_mark *mrk;
|
||||
struct rtattr *rthdr = XFRM_RTA(hdr, struct xfrm_userpolicy_id);
|
||||
|
||||
rthdr->rta_type = XFRMA_MARK;
|
||||
rthdr->rta_len = RTA_LENGTH(sizeof(struct xfrm_mark));
|
||||
hdr->nlmsg_len += rthdr->rta_len;
|
||||
if (hdr->nlmsg_len > sizeof(request))
|
||||
{
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
mrk = (struct xfrm_mark*)RTA_DATA(rthdr);
|
||||
mrk->v = mark.value;
|
||||
mrk->m = mark.mask;
|
||||
}
|
||||
|
||||
route = to_delete->route;
|
||||
free(to_delete);
|
||||
|
||||
if (this->socket_xfrm->send_ack(this->socket_xfrm, hdr) != SUCCESS)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete policy %R === %R %N", src_ts, dst_ts,
|
||||
policy_dir_names, direction);
|
||||
if (mark.value)
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete policy %R === %R %N "
|
||||
"(mark %u/0x%8x)", src_ts, dst_ts, policy_dir_names,
|
||||
direction, mark.value, mark.mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_KNL, "unable to delete policy %R === %R %N",
|
||||
src_ts, dst_ts, policy_dir_names, direction);
|
||||
}
|
||||
return FAILED;
|
||||
}
|
||||
|
||||
|
|
|
@ -1245,10 +1245,11 @@ METHOD(kernel_ipsec_t, get_cpi, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst, u_int32_t spi,
|
||||
protocol_id_t protocol, u_int32_t reqid, lifetime_cfg_t *lifetime,
|
||||
u_int16_t enc_alg, chunk_t enc_key, u_int16_t int_alg, chunk_t int_key,
|
||||
ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi, bool encap,
|
||||
bool inbound, traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
|
||||
protocol_id_t protocol, u_int32_t reqid, mark_t mark,
|
||||
lifetime_cfg_t *lifetime, u_int16_t enc_alg, chunk_t enc_key,
|
||||
u_int16_t int_alg, chunk_t int_key, ipsec_mode_t mode,
|
||||
u_int16_t ipcomp, u_int16_t cpi, bool encap, bool inbound,
|
||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1392,7 +1393,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
|||
METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||
private_kernel_pfkey_ipsec_t *this, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int16_t cpi, host_t *src, host_t *dst, host_t *new_src, host_t *new_dst,
|
||||
bool encap, bool new_encap)
|
||||
bool encap, bool new_encap, mark_t mark)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1525,7 +1526,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int64_t *bytes)
|
||||
u_int32_t spi, protocol_id_t protocol, mark_t mark, u_int64_t *bytes)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1581,7 +1582,7 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, del_sa, status_t,
|
||||
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi)
|
||||
u_int32_t spi, protocol_id_t protocol, u_int16_t cpi, mark_t mark)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1632,8 +1633,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
private_kernel_pfkey_ipsec_t *this, host_t *src, host_t *dst,
|
||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts,
|
||||
policy_dir_t direction, u_int32_t spi, protocol_id_t protocol,
|
||||
u_int32_t reqid, ipsec_mode_t mode, u_int16_t ipcomp, u_int16_t cpi,
|
||||
bool routed)
|
||||
u_int32_t reqid, mark_t mark, ipsec_mode_t mode, u_int16_t ipcomp,
|
||||
u_int16_t cpi, bool routed)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1834,7 +1835,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, query_policy, status_t,
|
||||
private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, u_int32_t *use_time)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
u_int32_t *use_time)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
@ -1937,7 +1939,8 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
|||
|
||||
METHOD(kernel_ipsec_t, del_policy, status_t,
|
||||
private_kernel_pfkey_ipsec_t *this, traffic_selector_t *src_ts,
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, bool unrouted)
|
||||
traffic_selector_t *dst_ts, policy_dir_t direction, mark_t mark,
|
||||
bool unrouted)
|
||||
{
|
||||
unsigned char request[PFKEY_BUFFER_SIZE];
|
||||
struct sadb_msg *msg, *out;
|
||||
|
|
|
@ -224,7 +224,7 @@ static peer_cfg_t* generate_config(private_load_tester_config_t *this, uint num)
|
|||
}
|
||||
|
||||
child_cfg = child_cfg_create("load-test", &lifetime, NULL, TRUE,
|
||||
MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
|
||||
MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
|
||||
proposal = proposal_create_from_string(PROTO_ESP, "aes128-sha1");
|
||||
child_cfg->add_proposal(child_cfg, proposal);
|
||||
ts = traffic_selector_create_dynamic(0, 0, 65535);
|
||||
|
|
|
@ -181,8 +181,8 @@ static peer_cfg_t *get_peer_cfg_by_name(private_medcli_config_t *this, char *nam
|
|||
identification_create_from_encoding(ID_KEY_ID, other));
|
||||
peer_cfg->add_auth_cfg(peer_cfg, auth, FALSE);
|
||||
|
||||
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE,
|
||||
MODE_TUNNEL, ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
|
||||
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
|
||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
|
||||
child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
|
||||
|
@ -260,7 +260,7 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
|
|||
this->current->add_auth_cfg(this->current, auth, FALSE);
|
||||
|
||||
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
|
||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE, ts_from_string(local_net));
|
||||
child_cfg->add_traffic_selector(child_cfg, FALSE, ts_from_string(remote_net));
|
||||
|
|
|
@ -444,7 +444,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
|
|||
|
||||
child_cfg = child_cfg_create(priv->name, &lifetime,
|
||||
NULL, TRUE, MODE_TUNNEL, /* updown, hostaccess */
|
||||
ACTION_NONE, ACTION_NONE, ipcomp, 0, 0);
|
||||
ACTION_NONE, ACTION_NONE, ipcomp, 0, 0, NULL);
|
||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
||||
ts = traffic_selector_create_dynamic(0, 0, 65535);
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE, ts);
|
||||
|
|
|
@ -134,7 +134,7 @@ static child_cfg_t *build_child_cfg(private_sql_config_t *this, enumerator_t *e)
|
|||
.time = { .life = lifetime, .rekey = rekeytime, .jitter = jitter }
|
||||
};
|
||||
child_cfg = child_cfg_create(name, &lft, updown, hostaccess, mode,
|
||||
dpd, close, ipcomp, 0, 0);
|
||||
dpd, close, ipcomp, 0, 0, NULL);
|
||||
/* TODO: read proposal from db */
|
||||
child_cfg->add_proposal(child_cfg, proposal_create_default(PROTO_ESP));
|
||||
add_traffic_selectors(this, child_cfg, id);
|
||||
|
|
|
@ -769,6 +769,10 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
|
|||
.jitter = msg->add_conn.rekey.margin_packets * msg->add_conn.rekey.fuzz / 100
|
||||
}
|
||||
};
|
||||
mark_t mark = {
|
||||
.value = msg->add_conn.mark.value,
|
||||
.mask = msg->add_conn.mark.mask
|
||||
};
|
||||
|
||||
switch (msg->add_conn.dpd.action)
|
||||
{ /* map startes magic values to our action type */
|
||||
|
@ -787,7 +791,7 @@ static child_cfg_t *build_child_cfg(private_stroke_config_t *this,
|
|||
msg->add_conn.name, &lifetime,
|
||||
msg->add_conn.me.updown, msg->add_conn.me.hostaccess,
|
||||
msg->add_conn.mode, dpd, dpd, msg->add_conn.ipcomp,
|
||||
msg->add_conn.inactivity, msg->add_conn.reqid);
|
||||
msg->add_conn.inactivity, msg->add_conn.reqid, &mark);
|
||||
child_cfg->set_mipv6_options(child_cfg, msg->add_conn.proxy_mode,
|
||||
msg->add_conn.install_policy);
|
||||
add_ts(this, &msg->add_conn.me, child_cfg, TRUE);
|
||||
|
|
|
@ -196,7 +196,7 @@ static bool peer_enumerator_enumerate(peer_enumerator_t *this, peer_cfg_t **cfg)
|
|||
this->peer_cfg->add_auth_cfg(this->peer_cfg, auth, FALSE);
|
||||
|
||||
child_cfg = child_cfg_create(name, &lifetime, NULL, TRUE, MODE_TUNNEL,
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0);
|
||||
ACTION_NONE, ACTION_NONE, FALSE, 0, 0, NULL);
|
||||
child_cfg->add_proposal(child_cfg, create_proposal(esp_proposal, PROTO_ESP));
|
||||
child_cfg->add_traffic_selector(child_cfg, TRUE, create_ts(local_net));
|
||||
child_cfg->add_traffic_selector(child_cfg, FALSE, create_ts(remote_net));
|
||||
|
|
|
@ -97,6 +97,16 @@ struct private_child_sa_t {
|
|||
*/
|
||||
u_int32_t reqid;
|
||||
|
||||
/**
|
||||
* inbound mark used for this child_sa
|
||||
*/
|
||||
mark_t mark_in;
|
||||
|
||||
/**
|
||||
* outbound mark used for this child_sa
|
||||
*/
|
||||
mark_t mark_out;
|
||||
|
||||
/**
|
||||
* absolute time when rekeying is scheduled
|
||||
*/
|
||||
|
@ -431,10 +441,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
|||
{
|
||||
if (this->my_spi)
|
||||
{
|
||||
status = charon->kernel_interface->query_sa(
|
||||
charon->kernel_interface,
|
||||
status = charon->kernel_interface->query_sa(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr,
|
||||
this->my_spi, this->protocol, &bytes);
|
||||
this->my_spi, this->protocol,
|
||||
this->mark_in, &bytes);
|
||||
if (status == SUCCESS)
|
||||
{
|
||||
if (bytes > this->my_usebytes)
|
||||
|
@ -450,10 +460,10 @@ static status_t update_usebytes(private_child_sa_t *this, bool inbound)
|
|||
{
|
||||
if (this->other_spi)
|
||||
{
|
||||
status = charon->kernel_interface->query_sa(
|
||||
charon->kernel_interface,
|
||||
status = charon->kernel_interface->query_sa(charon->kernel_interface,
|
||||
this->my_addr, this->other_addr,
|
||||
this->other_spi, this->protocol, &bytes);
|
||||
this->other_spi, this->protocol,
|
||||
this->mark_out, &bytes);
|
||||
if (status == SUCCESS)
|
||||
{
|
||||
if (bytes > this->other_usebytes)
|
||||
|
@ -485,14 +495,14 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
|
|||
if (inbound)
|
||||
{
|
||||
if (charon->kernel_interface->query_policy(charon->kernel_interface,
|
||||
other_ts, my_ts, POLICY_IN, &in) == SUCCESS)
|
||||
other_ts, my_ts, POLICY_IN, this->mark_in, &in) == SUCCESS)
|
||||
{
|
||||
last_use = max(last_use, in);
|
||||
}
|
||||
if (this->mode != MODE_TRANSPORT)
|
||||
{
|
||||
if (charon->kernel_interface->query_policy(charon->kernel_interface,
|
||||
other_ts, my_ts, POLICY_FWD, &fwd) == SUCCESS)
|
||||
other_ts, my_ts, POLICY_FWD, this->mark_in, &fwd) == SUCCESS)
|
||||
{
|
||||
last_use = max(last_use, fwd);
|
||||
}
|
||||
|
@ -501,7 +511,7 @@ static void update_usetime(private_child_sa_t *this, bool inbound)
|
|||
else
|
||||
{
|
||||
if (charon->kernel_interface->query_policy(charon->kernel_interface,
|
||||
my_ts, other_ts, POLICY_OUT, &out) == SUCCESS)
|
||||
my_ts, other_ts, POLICY_OUT, this->mark_out, &out) == SUCCESS)
|
||||
{
|
||||
last_use = max(last_use, out);
|
||||
}
|
||||
|
@ -665,9 +675,10 @@ static status_t install(private_child_sa_t *this, chunk_t encr, chunk_t integ,
|
|||
}
|
||||
|
||||
status = charon->kernel_interface->add_sa(charon->kernel_interface,
|
||||
src, dst, spi, this->protocol, this->reqid, lifetime,
|
||||
enc_alg, encr, int_alg, integ, this->mode, this->ipcomp, cpi,
|
||||
this->encap, update, src_ts, dst_ts);
|
||||
src, dst, spi, this->protocol, this->reqid,
|
||||
inbound ? this->mark_in : this->mark_out,
|
||||
lifetime, enc_alg, encr, int_alg, integ, this->mode,
|
||||
this->ipcomp, cpi, this->encap, update, src_ts, dst_ts);
|
||||
|
||||
free(lifetime);
|
||||
|
||||
|
@ -708,19 +719,19 @@ static status_t add_policies(private_child_sa_t *this,
|
|||
/* install 3 policies: out, in and forward */
|
||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
this->my_addr, this->other_addr, my_ts, other_ts, POLICY_OUT,
|
||||
this->other_spi, this->protocol, this->reqid, this->mode,
|
||||
this->ipcomp, this->other_cpi, routed);
|
||||
this->other_spi, this->protocol, this->reqid, this->mark_out,
|
||||
this->mode, this->ipcomp, this->other_cpi, routed);
|
||||
|
||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, other_ts, my_ts, POLICY_IN,
|
||||
this->my_spi, this->protocol, this->reqid, this->mode,
|
||||
this->ipcomp, this->my_cpi, routed);
|
||||
this->my_spi, this->protocol, this->reqid, this->mark_in,
|
||||
this->mode, this->ipcomp, this->my_cpi, routed);
|
||||
if (this->mode != MODE_TRANSPORT)
|
||||
{
|
||||
status |= charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, other_ts, my_ts, POLICY_FWD,
|
||||
this->my_spi, this->protocol, this->reqid, this->mode,
|
||||
this->ipcomp, this->my_cpi, routed);
|
||||
this->my_spi, this->protocol, this->reqid, this->mark_in,
|
||||
this->mode, this->ipcomp, this->my_cpi, routed);
|
||||
}
|
||||
|
||||
if (status != SUCCESS)
|
||||
|
@ -768,7 +779,7 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
|
|||
this->my_spi, this->protocol,
|
||||
this->ipcomp != IPCOMP_NONE ? this->my_cpi : 0,
|
||||
this->other_addr, this->my_addr, other, me,
|
||||
this->encap, encap) == NOT_SUPPORTED)
|
||||
this->encap, encap, this->mark_in) == NOT_SUPPORTED)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -781,7 +792,7 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
|
|||
this->other_spi, this->protocol,
|
||||
this->ipcomp != IPCOMP_NONE ? this->other_cpi : 0,
|
||||
this->my_addr, this->other_addr, me, other,
|
||||
this->encap, encap) == NOT_SUPPORTED)
|
||||
this->encap, encap, this->mark_out) == NOT_SUPPORTED)
|
||||
{
|
||||
return NOT_SUPPORTED;
|
||||
}
|
||||
|
@ -803,13 +814,13 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
|
|||
{
|
||||
/* remove old policies first */
|
||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||
my_ts, other_ts, POLICY_OUT, FALSE);
|
||||
my_ts, other_ts, POLICY_OUT, this->mark_out, FALSE);
|
||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||
other_ts, my_ts, POLICY_IN, FALSE);
|
||||
other_ts, my_ts, POLICY_IN, this->mark_in, FALSE);
|
||||
if (this->mode != MODE_TRANSPORT)
|
||||
{
|
||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||
other_ts, my_ts, POLICY_FWD, FALSE);
|
||||
other_ts, my_ts, POLICY_FWD, this->mark_in, FALSE);
|
||||
}
|
||||
|
||||
/* check whether we have to update a "dynamic" traffic selector */
|
||||
|
@ -835,18 +846,18 @@ static status_t update(private_child_sa_t *this, host_t *me, host_t *other,
|
|||
/* reinstall updated policies */
|
||||
charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
me, other, my_ts, other_ts, POLICY_OUT, this->other_spi,
|
||||
this->protocol, this->reqid, this->mode, this->ipcomp,
|
||||
this->other_cpi, FALSE);
|
||||
this->protocol, this->reqid, this->mark_out, this->mode,
|
||||
this->ipcomp, this->other_cpi, FALSE);
|
||||
charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
other, me, other_ts, my_ts, POLICY_IN, this->my_spi,
|
||||
this->protocol, this->reqid, this->mode, this->ipcomp,
|
||||
this->my_cpi, FALSE);
|
||||
this->protocol, this->reqid, this->mark_in, this->mode,
|
||||
this->ipcomp, this->my_cpi, FALSE);
|
||||
if (this->mode != MODE_TRANSPORT)
|
||||
{
|
||||
charon->kernel_interface->add_policy(charon->kernel_interface,
|
||||
other, me, other_ts, my_ts, POLICY_FWD, this->my_spi,
|
||||
this->protocol, this->reqid, this->mode, this->ipcomp,
|
||||
this->my_cpi, FALSE);
|
||||
this->protocol, this->reqid, this->mark_in, this->mode,
|
||||
this->ipcomp, this->my_cpi, FALSE);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
@ -896,13 +907,13 @@ static void destroy(private_child_sa_t *this)
|
|||
}
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
this->other_addr, this->my_addr, this->my_spi,
|
||||
this->protocol, this->my_cpi);
|
||||
this->protocol, this->my_cpi, this->mark_in);
|
||||
}
|
||||
if (this->other_spi)
|
||||
{
|
||||
charon->kernel_interface->del_sa(charon->kernel_interface,
|
||||
this->my_addr, this->other_addr, this->other_spi,
|
||||
this->protocol, this->other_cpi);
|
||||
this->protocol, this->other_cpi, this->mark_out);
|
||||
}
|
||||
|
||||
if (this->config->install_policy(this->config))
|
||||
|
@ -912,13 +923,13 @@ static void destroy(private_child_sa_t *this)
|
|||
while (enumerator->enumerate(enumerator, &my_ts, &other_ts))
|
||||
{
|
||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||
my_ts, other_ts, POLICY_OUT, unrouted);
|
||||
my_ts, other_ts, POLICY_OUT, this->mark_out, unrouted);
|
||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||
other_ts, my_ts, POLICY_IN, unrouted);
|
||||
other_ts, my_ts, POLICY_IN, this->mark_in, unrouted);
|
||||
if (this->mode != MODE_TRANSPORT)
|
||||
{
|
||||
charon->kernel_interface->del_policy(charon->kernel_interface,
|
||||
other_ts, my_ts, POLICY_FWD, unrouted);
|
||||
other_ts, my_ts, POLICY_FWD, this->mark_in, unrouted);
|
||||
}
|
||||
}
|
||||
enumerator->destroy(enumerator);
|
||||
|
@ -1000,6 +1011,9 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
|||
this->config = config;
|
||||
config->get_ref(config);
|
||||
this->reqid = config->get_reqid(config);
|
||||
this->mark_in = config->get_mark(config, TRUE);
|
||||
this->mark_out = config->get_mark(config, FALSE);
|
||||
|
||||
if (!this->reqid)
|
||||
{
|
||||
/* reuse old reqid if we are rekeying an existing CHILD_SA */
|
||||
|
|
|
@ -235,6 +235,7 @@ static const token_info_t token_info[] =
|
|||
{ ARG_STR, offsetof(starter_conn_t, me_mediated_by), NULL },
|
||||
{ ARG_STR, offsetof(starter_conn_t, me_peerid), NULL },
|
||||
{ ARG_UINT, offsetof(starter_conn_t, reqid), NULL },
|
||||
{ ARG_MISC, 0, NULL /* KW_MARK */ },
|
||||
|
||||
/* ca section keywords */
|
||||
{ ARG_STR, offsetof(starter_ca_t, name), NULL },
|
||||
|
|
|
@ -671,6 +671,41 @@ static void load_conn(starter_conn_t *conn, kw_list_t *kw, starter_config_t *cfg
|
|||
}
|
||||
break;
|
||||
}
|
||||
case KW_MARK:
|
||||
{
|
||||
char *pos, *endptr;
|
||||
|
||||
pos = strchr(kw->value, '/');
|
||||
if (pos)
|
||||
{
|
||||
*pos = '\0';
|
||||
conn->mark_mask = strtoul(pos+1, &endptr, 0);
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
plog("# invalid mark mask: %s", pos+1);
|
||||
cfg->err++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
conn->mark_mask = 0xffffffff;
|
||||
}
|
||||
if (*kw->value == '\0')
|
||||
{
|
||||
conn->mark_value = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
conn->mark_value = strtoul(kw->value, &endptr, 0);
|
||||
if (*endptr != '\0')
|
||||
{
|
||||
plog("# invalid mark value: %s", kw->value);
|
||||
cfg->err++;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case KW_KEYINGTRIES:
|
||||
if (streq(kw->value, "%forever"))
|
||||
{
|
||||
|
|
|
@ -122,6 +122,8 @@ struct starter_conn {
|
|||
unsigned long sa_keying_tries;
|
||||
unsigned long sa_rekey_fuzz;
|
||||
u_int32_t reqid;
|
||||
u_int32_t mark_value;
|
||||
u_int32_t mark_mask;
|
||||
sa_family_t addr_family;
|
||||
sa_family_t tunnel_addr_family;
|
||||
bool install_policy;
|
||||
|
|
|
@ -98,9 +98,10 @@ typedef enum {
|
|||
KW_MEDIATED_BY,
|
||||
KW_ME_PEERID,
|
||||
KW_REQID,
|
||||
KW_MARK,
|
||||
|
||||
#define KW_CONN_FIRST KW_CONN_SETUP
|
||||
#define KW_CONN_LAST KW_REQID
|
||||
#define KW_CONN_LAST KW_MARK
|
||||
|
||||
/* ca section keywords */
|
||||
KW_CA_NAME,
|
||||
|
|
|
@ -89,6 +89,7 @@ mediation, KW_MEDIATION
|
|||
mediated_by, KW_MEDIATED_BY
|
||||
me_peerid, KW_ME_PEERID
|
||||
reqid, KW_REQID
|
||||
mark, KW_MARK
|
||||
cacert, KW_CACERT
|
||||
ldaphost, KW_LDAPHOST
|
||||
ldapbase, KW_LDAPBASE
|
||||
|
|
|
@ -270,6 +270,8 @@ int starter_stroke_add_conn(starter_config_t *cfg, starter_conn_t *conn)
|
|||
msg.add_conn.ikeme.mediated_by = push_string(&msg, conn->me_mediated_by);
|
||||
msg.add_conn.ikeme.peerid = push_string(&msg, conn->me_peerid);
|
||||
msg.add_conn.reqid = conn->reqid;
|
||||
msg.add_conn.mark.value = conn->mark_value;
|
||||
msg.add_conn.mark.mask = conn->mark_mask;
|
||||
|
||||
starter_stroke_add_end(&msg, &msg.add_conn.me, &conn->left);
|
||||
starter_stroke_add_end(&msg, &msg.add_conn.other, &conn->right);
|
||||
|
|
|
@ -256,6 +256,10 @@ struct stroke_msg_t {
|
|||
char *mediated_by;
|
||||
char *peerid;
|
||||
} ikeme;
|
||||
struct {
|
||||
u_int32_t value;
|
||||
u_int32_t mask;
|
||||
} mark;
|
||||
stroke_end_t me, other;
|
||||
} add_conn;
|
||||
|
||||
|
|
Loading…
Reference in New Issue