/*
- * Copyright (C) 2006-2018 Tobias Brunner
+ * Copyright (C) 2006-2019 Tobias Brunner
* Copyright (C) 2005-2009 Martin Willi
* Copyright (C) 2008-2016 Andreas Steffen
* Copyright (C) 2006-2007 Fabian Hartmann, Noah Heusser
/** Optional mark */
mark_t mark;
+ /** Optional mark */
+ uint32_t if_id;
+
/** Description of this SA */
ipsec_sa_cfg_t cfg;
return chunk_hash_inc(sa->src->get_address(sa->src),
chunk_hash_inc(sa->dst->get_address(sa->dst),
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))))));
}
/**
sa->dst->ip_equals(sa->dst, other_sa->dst) &&
sa->mark.value == other_sa->mark.value &&
sa->mark.mask == other_sa->mark.mask &&
+ sa->if_id == other_sa->if_id &&
ipsec_sa_cfg_equals(&sa->cfg, &other_sa->cfg);
}
*/
static ipsec_sa_t *ipsec_sa_create(private_kernel_netlink_ipsec_t *this,
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;
INIT(sa,
.src = src,
.dst = dst,
.mark = mark,
+ .if_id = if_id,
.cfg = *cfg,
);
found = this->sas->get(this->sas, sa);
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,
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;
INIT(policy, .priority = 0);
}
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;
}
/** Optional mark */
uint32_t mark;
+ /** Optional interface ID */
+ uint32_t if_id;
+
/** Associated route installed for this policy */
route_entry_t *route;
static u_int policy_hash(policy_entry_t *key)
{
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))));
}
/**
{
return memeq(&key->sel, &other_key->sel, sizeof(struct xfrm_selector)) &&
key->mark == other_key->mark &&
+ key->if_id == other_key->if_id &&
key->direction == other_key->direction;
}
.spi = htonl(ntohs(data->cpi)),
.proto = IPPROTO_COMP,
.mark = id->mark,
+ .if_id = id->if_id,
};
kernel_ipsec_add_sa_t ipcomp_sa = {
.reqid = data->reqid,
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 (!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK,
{
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)
{
{
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)
{
{
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))
{
.spi = htonl(ntohs(data->cpi)),
.proto = IPPROTO_COMP,
.mark = id->mark,
+ .if_id = id->if_id,
};
kernel_ipsec_update_sa_t ipcomp = {
.new_src = data->new_src,
{
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)
{
policy_change_done(this, policy);
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);
status = this->socket_xfrm->send_ack(this->socket_xfrm, hdr);
INIT(policy,
.sel = ts2selector(id->src_ts, id->dst_ts, id->interface),
.mark = id->mark.value & id->mark.mask,
+ .if_id = id->if_id,
.direction = id->dir,
.reqid = data->sa->reqid,
);
/* cache the assigned IPsec SA */
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->priority = this->get_priority ? this->get_priority(id, data)
: data->manual_prio;
{
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)
{
.src = data->src,
.dst = data->dst,
.mark = id->mark,
+ .if_id = id->if_id,
.cfg = *data->sa,
};
char markstr[32] = "";
memset(&policy, 0, sizeof(policy_entry_t));
policy.sel = ts2selector(id->src_ts, id->dst_ts, id->interface);
policy.mark = id->mark.value & id->mark.mask;
+ policy.if_id = id->if_id;
policy.direction = id->dir;
/* find the policy */
policy_change_done(this, current);
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)
{