child-sa: Allow requesting different unique marks for in/out
When requiring unique flags for CHILD_SAs, allow the configuration to request different marks for each direction by using the %unique-dir keyword. This is useful when different marks are desired for each direction but the number of peers is not predefined. An example use case is when implementing a site-to-site route-based VPN without VTI devices. A use of 0.0.0.0/0 - 0.0.0.0/0 traffic selectors with identical in/out marks results in outbound traffic being wrongfully matched against the 'fwd' policy - for which the underlay 'template' does not match - and dropped. Using different marks for each direction avoids this issue as the 'fwd' policy uses the 'in' mark will not match outbound traffic. Closes strongswan/strongswan#78.
This commit is contained in:
committed by
Tobias Brunner
parent
00498d78a8
commit
32e5c49234
@@ -1745,7 +1745,7 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
{
|
||||
private_child_sa_t *this;
|
||||
static refcount_t unique_id = 0, unique_mark = 0;
|
||||
refcount_t mark;
|
||||
refcount_t mark = 0;
|
||||
|
||||
INIT(this,
|
||||
.public = {
|
||||
@@ -1818,16 +1818,33 @@ child_sa_t * child_sa_create(host_t *me, host_t* other,
|
||||
{
|
||||
this->mark_out.value = mark_out;
|
||||
}
|
||||
if (this->mark_in.value == MARK_UNIQUE ||
|
||||
this->mark_out.value == MARK_UNIQUE)
|
||||
|
||||
if (MARK_IS_UNIQUE(this->mark_in.value) ||
|
||||
MARK_IS_UNIQUE(this->mark_out.value))
|
||||
{
|
||||
mark = ref_get(&unique_mark);
|
||||
if (this->mark_in.value == MARK_UNIQUE)
|
||||
bool unique_dir;
|
||||
|
||||
unique_dir = this->mark_in.value == MARK_UNIQUE_DIR ||
|
||||
this->mark_out.value == MARK_UNIQUE_DIR;
|
||||
|
||||
if (!unique_dir)
|
||||
{
|
||||
mark = ref_get(&unique_mark);
|
||||
}
|
||||
if (MARK_IS_UNIQUE(this->mark_in.value))
|
||||
{
|
||||
if (unique_dir)
|
||||
{
|
||||
mark = ref_get(&unique_mark);
|
||||
}
|
||||
this->mark_in.value = mark;
|
||||
}
|
||||
if (this->mark_out.value == MARK_UNIQUE)
|
||||
if (MARK_IS_UNIQUE(this->mark_out.value))
|
||||
{
|
||||
if (unique_dir)
|
||||
{
|
||||
mark = ref_get(&unique_mark);
|
||||
}
|
||||
this->mark_out.value = mark;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user