.B 0xffffffff
is assumed. The special value
.B %unique
-assigns a unique value to each newly created IPsec SA.
+assigns a unique value to each newly created IPsec SA. To additionally
+make the mark unique for each IPsec SA direction (in/out) the special value
+.B %unique-dir
+may be used.
.TP
.BR mark_in " = <value>[/<mask>]"
sets an XFRM mark in the inbound IPsec SA and
{
private_child_sa_t *this;
static refcount_t unique_id = 0, unique_mark = 0;
- refcount_t mark;
+ refcount_t mark = 0;
INIT(this,
.public = {
{
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;
}
}
}
if (strcasepfx(value, "%unique"))
{
- mark->value = MARK_UNIQUE;
endptr = (char*)value + strlen("%unique");
+ if (strcasepfx(endptr, "-dir"))
+ {
+ mark->value = MARK_UNIQUE_DIR;
+ endptr += strlen("-dir");
+ }
+ else if (!*endptr || *endptr == '/')
+ {
+ mark->value = MARK_UNIQUE;
+ }
+ else
+ {
+ DBG1(DBG_APP, "invalid mark value: %s", value);
+ return FALSE;
+ }
}
else
{
};
/**
- * Special mark value that uses a unique mark for each CHILD_SA
+ * Special mark value that uses a unique mark for each CHILD_SA (and direction)
*/
#define MARK_UNIQUE (0xFFFFFFFF)
+#define MARK_UNIQUE_DIR (0xFFFFFFFE)
+#define MARK_IS_UNIQUE(m) ((m) == MARK_UNIQUE || (m) == MARK_UNIQUE_DIR)
/**
* Try to parse a mark_t from the given string of the form mark[/mask].
Netfilter mark and mask for input traffic. On Linux Netfilter may require
marks on each packet to match an SA having that option set. This allows
Netfilter rules to select specific tunnels for incoming traffic. The
- special value _%unique_ sets a unique mark on each CHILD_SA instance.
+ special value _%unique_ sets a unique mark on each CHILD_SA instance,
+ beyond that the value _%unique-dir_ assigns a different unique mark for each
+ CHILD_SA direction (in/out).
An additional mask may be appended to the mark, separated by _/_. The
default mask if omitted is 0xffffffff.
Netfilter mark and mask for output traffic. On Linux Netfilter may require
marks on each packet to match a policy having that option set. This allows
Netfilter rules to select specific tunnels for outgoing traffic. The
- special value _%unique_ sets a unique mark on each CHILD_SA instance.
+ special value _%unique_ sets a unique mark on each CHILD_SA instance,
+ beyond that the value _%unique-dir_ assigns a different unique mark for each
+ CHILD_SA direction (in/out).
An additional mask may be appended to the mark, separated by _/_. The
default mask if omitted is 0xffffffff.