kernel-netlink: Make interface ID configurable on SAs and policies
This commit is contained in:
parent
d1cd2a0541
commit
b32c3ce8fe
|
@ -55,6 +55,8 @@ struct kernel_ipsec_sa_id_t {
|
||||||
uint8_t proto;
|
uint8_t proto;
|
||||||
/** Optional mark */
|
/** Optional mark */
|
||||||
mark_t mark;
|
mark_t mark;
|
||||||
|
/** Optional interface ID */
|
||||||
|
uint32_t if_id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -154,6 +156,8 @@ struct kernel_ipsec_policy_id_t {
|
||||||
traffic_selector_t *dst_ts;
|
traffic_selector_t *dst_ts;
|
||||||
/** Optional mark */
|
/** Optional mark */
|
||||||
mark_t mark;
|
mark_t mark;
|
||||||
|
/** Optional interface ID */
|
||||||
|
uint32_t if_id;
|
||||||
/** Network interface restricting policy */
|
/** Network interface restricting policy */
|
||||||
char *interface;
|
char *interface;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2006-2018 Tobias Brunner
|
* Copyright (C) 2006-2019 Tobias Brunner
|
||||||
* Copyright (C) 2005-2009 Martin Willi
|
* Copyright (C) 2005-2009 Martin Willi
|
||||||
* Copyright (C) 2008-2016 Andreas Steffen
|
* Copyright (C) 2008-2016 Andreas Steffen
|
||||||
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
|
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
|
||||||
|
@ -430,6 +430,9 @@ struct ipsec_sa_t {
|
||||||
/** Optional mark */
|
/** Optional mark */
|
||||||
mark_t mark;
|
mark_t mark;
|
||||||
|
|
||||||
|
/** Optional mark */
|
||||||
|
uint32_t if_id;
|
||||||
|
|
||||||
/** Description of this SA */
|
/** Description of this SA */
|
||||||
ipsec_sa_cfg_t cfg;
|
ipsec_sa_cfg_t cfg;
|
||||||
|
|
||||||
|
@ -445,7 +448,8 @@ static u_int ipsec_sa_hash(ipsec_sa_t *sa)
|
||||||
return chunk_hash_inc(sa->src->get_address(sa->src),
|
return chunk_hash_inc(sa->src->get_address(sa->src),
|
||||||
chunk_hash_inc(sa->dst->get_address(sa->dst),
|
chunk_hash_inc(sa->dst->get_address(sa->dst),
|
||||||
chunk_hash_inc(chunk_from_thing(sa->mark),
|
chunk_hash_inc(chunk_from_thing(sa->mark),
|
||||||
chunk_hash(chunk_from_thing(sa->cfg)))));
|
chunk_hash_inc(chunk_from_thing(sa->if_id),
|
||||||
|
chunk_hash(chunk_from_thing(sa->cfg))))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -457,6 +461,7 @@ static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa)
|
||||||
sa->dst->ip_equals(sa->dst, other_sa->dst) &&
|
sa->dst->ip_equals(sa->dst, other_sa->dst) &&
|
||||||
sa->mark.value == other_sa->mark.value &&
|
sa->mark.value == other_sa->mark.value &&
|
||||||
sa->mark.mask == other_sa->mark.mask &&
|
sa->mark.mask == other_sa->mark.mask &&
|
||||||
|
sa->if_id == other_sa->if_id &&
|
||||||
ipsec_sa_cfg_equals(&sa->cfg, &other_sa->cfg);
|
ipsec_sa_cfg_equals(&sa->cfg, &other_sa->cfg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,13 +470,14 @@ static bool ipsec_sa_equals(ipsec_sa_t *sa, ipsec_sa_t *other_sa)
|
||||||
*/
|
*/
|
||||||
static ipsec_sa_t *ipsec_sa_create(private_kernel_netlink_ipsec_t *this,
|
static ipsec_sa_t *ipsec_sa_create(private_kernel_netlink_ipsec_t *this,
|
||||||
host_t *src, host_t *dst, mark_t mark,
|
host_t *src, host_t *dst, mark_t mark,
|
||||||
ipsec_sa_cfg_t *cfg)
|
uint32_t if_id, ipsec_sa_cfg_t *cfg)
|
||||||
{
|
{
|
||||||
ipsec_sa_t *sa, *found;
|
ipsec_sa_t *sa, *found;
|
||||||
INIT(sa,
|
INIT(sa,
|
||||||
.src = src,
|
.src = src,
|
||||||
.dst = dst,
|
.dst = dst,
|
||||||
.mark = mark,
|
.mark = mark,
|
||||||
|
.if_id = if_id,
|
||||||
.cfg = *cfg,
|
.cfg = *cfg,
|
||||||
);
|
);
|
||||||
found = this->sas->get(this->sas, sa);
|
found = this->sas->get(this->sas, sa);
|
||||||
|
@ -546,7 +552,7 @@ struct policy_sa_out_t {
|
||||||
static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
|
static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
|
||||||
policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst,
|
policy_dir_t dir, policy_type_t type, host_t *src, host_t *dst,
|
||||||
traffic_selector_t *src_ts, traffic_selector_t *dst_ts, mark_t mark,
|
traffic_selector_t *src_ts, traffic_selector_t *dst_ts, mark_t mark,
|
||||||
ipsec_sa_cfg_t *cfg)
|
uint32_t if_id, ipsec_sa_cfg_t *cfg)
|
||||||
{
|
{
|
||||||
policy_sa_t *policy;
|
policy_sa_t *policy;
|
||||||
|
|
||||||
|
@ -564,7 +570,7 @@ static policy_sa_t *policy_sa_create(private_kernel_netlink_ipsec_t *this,
|
||||||
INIT(policy, .priority = 0);
|
INIT(policy, .priority = 0);
|
||||||
}
|
}
|
||||||
policy->type = type;
|
policy->type = type;
|
||||||
policy->sa = ipsec_sa_create(this, src, dst, mark, cfg);
|
policy->sa = ipsec_sa_create(this, src, dst, mark, if_id, cfg);
|
||||||
return policy;
|
return policy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -610,6 +616,9 @@ struct policy_entry_t {
|
||||||
/** Optional mark */
|
/** Optional mark */
|
||||||
uint32_t mark;
|
uint32_t mark;
|
||||||
|
|
||||||
|
/** Optional interface ID */
|
||||||
|
uint32_t if_id;
|
||||||
|
|
||||||
/** Associated route installed for this policy */
|
/** Associated route installed for this policy */
|
||||||
route_entry_t *route;
|
route_entry_t *route;
|
||||||
|
|
||||||
|
@ -651,7 +660,8 @@ static void policy_entry_destroy(private_kernel_netlink_ipsec_t *this,
|
||||||
static u_int policy_hash(policy_entry_t *key)
|
static u_int policy_hash(policy_entry_t *key)
|
||||||
{
|
{
|
||||||
chunk_t chunk = chunk_from_thing(key->sel);
|
chunk_t chunk = chunk_from_thing(key->sel);
|
||||||
return chunk_hash_inc(chunk, chunk_hash(chunk_from_thing(key->mark)));
|
return chunk_hash_inc(chunk, chunk_hash_inc(chunk_from_thing(key->mark),
|
||||||
|
chunk_hash(chunk_from_thing(key->if_id))));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -661,6 +671,7 @@ 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)) &&
|
||||||
key->mark == other_key->mark &&
|
key->mark == other_key->mark &&
|
||||||
|
key->if_id == other_key->if_id &&
|
||||||
key->direction == other_key->direction;
|
key->direction == other_key->direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1577,6 +1588,7 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||||
.spi = htonl(ntohs(data->cpi)),
|
.spi = htonl(ntohs(data->cpi)),
|
||||||
.proto = IPPROTO_COMP,
|
.proto = IPPROTO_COMP,
|
||||||
.mark = id->mark,
|
.mark = id->mark,
|
||||||
|
.if_id = id->if_id,
|
||||||
};
|
};
|
||||||
kernel_ipsec_add_sa_t ipcomp_sa = {
|
kernel_ipsec_add_sa_t ipcomp_sa = {
|
||||||
.reqid = data->reqid,
|
.reqid = data->reqid,
|
||||||
|
@ -1902,6 +1914,11 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||||
goto failed;
|
goto failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, id->if_id))
|
||||||
|
{
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
if (ipcomp == IPCOMP_NONE && (data->mark.value | data->mark.mask))
|
if (ipcomp == IPCOMP_NONE && (data->mark.value | data->mark.mask))
|
||||||
{
|
{
|
||||||
if (!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK,
|
if (!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK,
|
||||||
|
@ -2034,6 +2051,10 @@ static void get_replay_state(private_kernel_netlink_ipsec_t *this,
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (sa->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, sa->if_id))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -2132,6 +2153,10 @@ METHOD(kernel_ipsec_t, query_sa, status_t,
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (id->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, id->if_id))
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -2236,6 +2261,10 @@ METHOD(kernel_ipsec_t, del_sa, status_t,
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (id->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, id->if_id))
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
switch (this->socket_xfrm->send_ack(this->socket_xfrm, hdr))
|
switch (this->socket_xfrm->send_ack(this->socket_xfrm, hdr))
|
||||||
{
|
{
|
||||||
|
@ -2282,6 +2311,7 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||||
.spi = htonl(ntohs(data->cpi)),
|
.spi = htonl(ntohs(data->cpi)),
|
||||||
.proto = IPPROTO_COMP,
|
.proto = IPPROTO_COMP,
|
||||||
.mark = id->mark,
|
.mark = id->mark,
|
||||||
|
.if_id = id->if_id,
|
||||||
};
|
};
|
||||||
kernel_ipsec_update_sa_t ipcomp = {
|
kernel_ipsec_update_sa_t ipcomp = {
|
||||||
.new_src = data->new_src,
|
.new_src = data->new_src,
|
||||||
|
@ -2312,6 +2342,10 @@ METHOD(kernel_ipsec_t, update_sa, status_t,
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (id->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, id->if_id))
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -2786,6 +2820,12 @@ static status_t add_policy_internal(private_kernel_netlink_ipsec_t *this,
|
||||||
policy_change_done(this, policy);
|
policy_change_done(this, policy);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (ipsec->if_id &&
|
||||||
|
!add_uint32(hdr, sizeof(request), XFRMA_IF_ID, ipsec->if_id))
|
||||||
|
{
|
||||||
|
policy_change_done(this, policy);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
this->mutex->unlock(this->mutex);
|
this->mutex->unlock(this->mutex);
|
||||||
|
|
||||||
status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr);
|
status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr);
|
||||||
|
@ -2837,6 +2877,7 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
||||||
INIT(policy,
|
INIT(policy,
|
||||||
.sel = ts2selector(id->src_ts, id->dst_ts, id->interface),
|
.sel = ts2selector(id->src_ts, id->dst_ts, id->interface),
|
||||||
.mark = id->mark.value & id->mark.mask,
|
.mark = id->mark.value & id->mark.mask,
|
||||||
|
.if_id = id->if_id,
|
||||||
.direction = id->dir,
|
.direction = id->dir,
|
||||||
.reqid = data->sa->reqid,
|
.reqid = data->sa->reqid,
|
||||||
);
|
);
|
||||||
|
@ -2882,7 +2923,8 @@ METHOD(kernel_ipsec_t, add_policy, status_t,
|
||||||
|
|
||||||
/* cache the assigned IPsec SA */
|
/* cache the assigned IPsec SA */
|
||||||
assigned_sa = policy_sa_create(this, id->dir, data->type, data->src,
|
assigned_sa = policy_sa_create(this, id->dir, data->type, data->src,
|
||||||
data->dst, id->src_ts, id->dst_ts, id->mark, data->sa);
|
data->dst, id->src_ts, id->dst_ts, id->mark,
|
||||||
|
id->if_id, data->sa);
|
||||||
assigned_sa->auto_priority = get_priority(policy, data->prio, id->interface);
|
assigned_sa->auto_priority = get_priority(policy, data->prio, id->interface);
|
||||||
assigned_sa->priority = this->get_priority ? this->get_priority(id, data)
|
assigned_sa->priority = this->get_priority ? this->get_priority(id, data)
|
||||||
: data->manual_prio;
|
: data->manual_prio;
|
||||||
|
@ -2980,6 +3022,10 @@ METHOD(kernel_ipsec_t, query_policy, status_t,
|
||||||
{
|
{
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (id->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, id->if_id))
|
||||||
|
{
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
if (this->socket_xfrm->send(this->socket_xfrm, hdr, &out, &len) == SUCCESS)
|
||||||
{
|
{
|
||||||
|
@ -3048,6 +3094,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
||||||
.src = data->src,
|
.src = data->src,
|
||||||
.dst = data->dst,
|
.dst = data->dst,
|
||||||
.mark = id->mark,
|
.mark = id->mark,
|
||||||
|
.if_id = id->if_id,
|
||||||
.cfg = *data->sa,
|
.cfg = *data->sa,
|
||||||
};
|
};
|
||||||
char markstr[32] = "";
|
char markstr[32] = "";
|
||||||
|
@ -3063,6 +3110,7 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
||||||
memset(&policy, 0, sizeof(policy_entry_t));
|
memset(&policy, 0, sizeof(policy_entry_t));
|
||||||
policy.sel = ts2selector(id->src_ts, id->dst_ts, id->interface);
|
policy.sel = ts2selector(id->src_ts, id->dst_ts, id->interface);
|
||||||
policy.mark = id->mark.value & id->mark.mask;
|
policy.mark = id->mark.value & id->mark.mask;
|
||||||
|
policy.if_id = id->if_id;
|
||||||
policy.direction = id->dir;
|
policy.direction = id->dir;
|
||||||
|
|
||||||
/* find the policy */
|
/* find the policy */
|
||||||
|
@ -3153,6 +3201,11 @@ METHOD(kernel_ipsec_t, del_policy, status_t,
|
||||||
policy_change_done(this, current);
|
policy_change_done(this, current);
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
if (id->if_id && !add_uint32(hdr, sizeof(request), XFRMA_IF_ID, id->if_id))
|
||||||
|
{
|
||||||
|
policy_change_done(this, current);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
if (current->route)
|
if (current->route)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue