Merge branch 'xfrm-set-mark'
This adds the ability to configure marks the in- and/or outbound SA should apply to packets after processing on Linux. Configuring such a mark for outbound SAs requires at least a 4.14 kernel. The ability to set a mask and configuring a mark/mask for inbound SAs will be added with the upcoming 4.19 kernel.
This commit is contained in:
@@ -302,8 +302,11 @@ enum xfrm_attr_type_t {
|
||||
XFRMA_ADDRESS_FILTER, /* struct xfrm_address_filter */
|
||||
XFRMA_PAD,
|
||||
XFRMA_OFFLOAD_DEV, /* struct xfrm_state_offload */
|
||||
XFRMA_SET_MARK, /* __u32 */
|
||||
XFRMA_SET_MARK_MASK, /* __u32 */
|
||||
__XFRMA_MAX
|
||||
|
||||
#define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */
|
||||
#define XFRMA_MAX (__XFRMA_MAX - 1)
|
||||
};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2017 Tobias Brunner
|
||||
* Copyright (C) 2008-2018 Tobias Brunner
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -123,6 +123,16 @@ struct private_child_cfg_t {
|
||||
*/
|
||||
mark_t mark_out;
|
||||
|
||||
/**
|
||||
* Optional mark to set to packets after inbound processing
|
||||
*/
|
||||
mark_t set_mark_in;
|
||||
|
||||
/**
|
||||
* Optional mark to set to packets after outbound processing
|
||||
*/
|
||||
mark_t set_mark_out;
|
||||
|
||||
/**
|
||||
* Traffic Flow Confidentiality padding, if enabled
|
||||
*/
|
||||
@@ -547,6 +557,12 @@ METHOD(child_cfg_t, get_mark, mark_t,
|
||||
return inbound ? this->mark_in : this->mark_out;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, get_set_mark, mark_t,
|
||||
private_child_cfg_t *this, bool inbound)
|
||||
{
|
||||
return inbound ? this->set_mark_in : this->set_mark_out;
|
||||
}
|
||||
|
||||
METHOD(child_cfg_t, get_tfc, uint32_t,
|
||||
private_child_cfg_t *this)
|
||||
{
|
||||
@@ -620,6 +636,10 @@ METHOD(child_cfg_t, equals, bool,
|
||||
this->mark_in.mask == other->mark_in.mask &&
|
||||
this->mark_out.value == other->mark_out.value &&
|
||||
this->mark_out.mask == other->mark_out.mask &&
|
||||
this->set_mark_in.value == other->set_mark_in.value &&
|
||||
this->set_mark_in.mask == other->set_mark_in.mask &&
|
||||
this->set_mark_out.value == other->set_mark_out.value &&
|
||||
this->set_mark_out.mask == other->set_mark_out.mask &&
|
||||
this->tfc == other->tfc &&
|
||||
this->manual_prio == other->manual_prio &&
|
||||
this->replay_window == other->replay_window &&
|
||||
@@ -676,6 +696,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
||||
.get_inactivity = _get_inactivity,
|
||||
.get_reqid = _get_reqid,
|
||||
.get_mark = _get_mark,
|
||||
.get_set_mark = _get_set_mark,
|
||||
.get_tfc = _get_tfc,
|
||||
.get_manual_prio = _get_manual_prio,
|
||||
.get_interface = _get_interface,
|
||||
@@ -698,6 +719,8 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
|
||||
.close_action = data->close_action,
|
||||
.mark_in = data->mark_in,
|
||||
.mark_out = data->mark_out,
|
||||
.set_mark_in = data->set_mark_in,
|
||||
.set_mark_out = data->set_mark_out,
|
||||
.lifetime = data->lifetime,
|
||||
.inactivity = data->inactivity,
|
||||
.tfc = data->tfc,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (C) 2008-2017 Tobias Brunner
|
||||
* Copyright (C) 2008-2018 Tobias Brunner
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2005-2007 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -227,13 +227,21 @@ struct child_cfg_t {
|
||||
uint32_t (*get_reqid)(child_cfg_t *this);
|
||||
|
||||
/**
|
||||
* Optional mark for CHILD_SA.
|
||||
* Optional mark to set on policies/SAs.
|
||||
*
|
||||
* @param inbound TRUE for inbound, FALSE for outbound
|
||||
* @return mark
|
||||
*/
|
||||
mark_t (*get_mark)(child_cfg_t *this, bool inbound);
|
||||
|
||||
/**
|
||||
* Optional mark the SAs should apply after processing packets.
|
||||
*
|
||||
* @param inbound TRUE for inbound, FALSE for outbound
|
||||
* @return mark
|
||||
*/
|
||||
mark_t (*get_set_mark)(child_cfg_t *this, bool inbound);
|
||||
|
||||
/**
|
||||
* Get the TFC padding value to use for CHILD_SA.
|
||||
*
|
||||
@@ -346,6 +354,10 @@ struct child_cfg_create_t {
|
||||
mark_t mark_in;
|
||||
/** Optional outbound mark */
|
||||
mark_t mark_out;
|
||||
/** Optional inbound mark the SA should apply to traffic */
|
||||
mark_t set_mark_in;
|
||||
/** Optional outbound mark the SA should apply to traffic */
|
||||
mark_t set_mark_out;
|
||||
/** Mode to propose for CHILD_SA */
|
||||
ipsec_mode_t mode;
|
||||
/** TFC padding size, 0 to disable, -1 to pad to PMTU */
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Andreas Steffen
|
||||
* Copyright (C) 2006-2016 Tobias Brunner
|
||||
* Copyright (C) 2006-2018 Tobias Brunner
|
||||
* Copyright (C) 2006 Daniel Roethlisberger
|
||||
* Copyright (C) 2005-2006 Martin Willi
|
||||
* Copyright (C) 2005 Jan Hutter
|
||||
@@ -93,6 +93,8 @@ struct kernel_ipsec_add_sa_t {
|
||||
bool encap;
|
||||
/** no (disabled), yes (enabled), auto (enabled if supported) */
|
||||
hw_offload_t hw_offload;
|
||||
/** Mark the SA should apply to packets after processing */
|
||||
mark_t mark;
|
||||
/** TRUE to use Extended Sequence Numbers */
|
||||
bool esn;
|
||||
/** TRUE to copy the DF bit to the outer IPv4 header in tunnel mode */
|
||||
|
||||
@@ -1335,6 +1335,23 @@ static bool add_mark(struct nlmsghdr *hdr, int buflen, mark_t mark)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a uint32 attribute to message
|
||||
*/
|
||||
static bool add_uint32(struct nlmsghdr *hdr, int buflen,
|
||||
enum xfrm_attr_type_t type, uint32_t value)
|
||||
{
|
||||
uint32_t *xvalue;
|
||||
|
||||
xvalue = netlink_reserve(hdr, buflen, type, sizeof(*xvalue));
|
||||
if (!xvalue)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
*xvalue = value;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if kernel supports HW offload
|
||||
*/
|
||||
@@ -1616,16 +1633,12 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
case DSCP_COPY_IN_ONLY:
|
||||
case DSCP_COPY_NO:
|
||||
{
|
||||
uint32_t *xflags;
|
||||
|
||||
xflags = netlink_reserve(hdr, sizeof(request),
|
||||
XFRMA_SA_EXTRA_FLAGS, sizeof(*xflags));
|
||||
if (!xflags)
|
||||
/* currently the only extra flag */
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_SA_EXTRA_FLAGS,
|
||||
XFRM_SA_XFLAG_DONT_ENCAP_DSCP))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
/* currently the only extra flag */
|
||||
*xflags |= XFRM_SA_XFLAG_DONT_ENCAP_DSCP;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@@ -1876,17 +1889,23 @@ METHOD(kernel_ipsec_t, add_sa, status_t,
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ipcomp == IPCOMP_NONE && (data->mark.value | data->mark.mask))
|
||||
{
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK,
|
||||
data->mark.value) ||
|
||||
!add_uint32(hdr, sizeof(request), XFRMA_SET_MARK_MASK,
|
||||
data->mark.mask))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
if (data->tfc && id->proto == IPPROTO_ESP && mode == MODE_TUNNEL)
|
||||
{ /* the kernel supports TFC padding only for tunnel mode ESP SAs */
|
||||
uint32_t *tfcpad;
|
||||
|
||||
tfcpad = netlink_reserve(hdr, sizeof(request), XFRMA_TFCPAD,
|
||||
sizeof(*tfcpad));
|
||||
if (!tfcpad)
|
||||
if (!add_uint32(hdr, sizeof(request), XFRMA_TFCPAD, data->tfc))
|
||||
{
|
||||
goto failed;
|
||||
}
|
||||
*tfcpad = data->tfc;
|
||||
}
|
||||
|
||||
if (id->proto != IPPROTO_COMP)
|
||||
|
||||
@@ -2925,7 +2925,7 @@ static status_t manage_rule(private_kernel_netlink_net_t *this, int nlmsg_type,
|
||||
msg->rtm_flags |= FIB_RULE_INVERT;
|
||||
fwmark++;
|
||||
}
|
||||
if (mark_from_string(fwmark, &mark))
|
||||
if (mark_from_string(fwmark, MARK_OP_NONE, &mark))
|
||||
{
|
||||
chunk = chunk_from_thing(mark.value);
|
||||
netlink_add_attribute(hdr, FRA_FWMARK, chunk, sizeof(request));
|
||||
|
||||
@@ -745,7 +745,7 @@ static int open_socket(private_socket_default_socket_t *this,
|
||||
|
||||
fwmark = lib->settings->get_str(lib->settings,
|
||||
"%s.plugins.socket-default.fwmark", NULL, lib->ns);
|
||||
if (fwmark && mark_from_string(fwmark, &mark))
|
||||
if (fwmark && mark_from_string(fwmark, MARK_OP_NONE, &mark))
|
||||
{
|
||||
if (setsockopt(skt, SOL_SOCKET, SO_MARK, &mark.value,
|
||||
sizeof(mark.value)) < 0)
|
||||
|
||||
@@ -528,6 +528,10 @@ static void log_child_data(child_data_t *data, char *name)
|
||||
DBG2(DBG_CFG, " mark_in_sa = %u", has_opt(OPT_MARK_IN_SA));
|
||||
DBG2(DBG_CFG, " mark_out = %u/%u",
|
||||
cfg->mark_out.value, cfg->mark_out.mask);
|
||||
DBG2(DBG_CFG, " set_mark_in = %u/%u",
|
||||
cfg->set_mark_in.value, cfg->set_mark_in.mask);
|
||||
DBG2(DBG_CFG, " set_mark_out = %u/%u",
|
||||
cfg->set_mark_out.value, cfg->set_mark_out.mask);
|
||||
DBG2(DBG_CFG, " inactivity = %llu", cfg->inactivity);
|
||||
DBG2(DBG_CFG, " proposals = %#P", data->proposals);
|
||||
DBG2(DBG_CFG, " local_ts = %#R", data->local_ts);
|
||||
@@ -1177,7 +1181,22 @@ CALLBACK(parse_mark, bool,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return mark_from_string(buf, out);
|
||||
return mark_from_string(buf, MARK_OP_UNIQUE, out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a mark_t when using it as set_mark.
|
||||
*/
|
||||
CALLBACK(parse_set_mark, bool,
|
||||
mark_t *out, chunk_t v)
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
if (!vici_stringify(v, buf, sizeof(buf)))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return mark_from_string(buf, MARK_OP_SAME, out);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1639,6 +1658,8 @@ CALLBACK(child_kv, bool,
|
||||
{ "mark_in", parse_mark, &child->cfg.mark_in },
|
||||
{ "mark_in_sa", parse_opt_mark_in, &child->cfg.options },
|
||||
{ "mark_out", parse_mark, &child->cfg.mark_out },
|
||||
{ "set_mark_in", parse_set_mark, &child->cfg.set_mark_in },
|
||||
{ "set_mark_out", parse_set_mark, &child->cfg.set_mark_out },
|
||||
{ "tfc_padding", parse_tfc, &child->cfg.tfc },
|
||||
{ "priority", parse_uint32, &child->cfg.priority },
|
||||
{ "interface", parse_string, &child->cfg.interface },
|
||||
|
||||
@@ -890,6 +890,7 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
|
||||
.cpi = cpi,
|
||||
.encap = this->encap,
|
||||
.hw_offload = this->config->get_hw_offload(this->config),
|
||||
.mark = this->config->get_set_mark(this->config, inbound),
|
||||
.esn = esn,
|
||||
.copy_df = !this->config->has_option(this->config, OPT_NO_COPY_DF),
|
||||
.copy_ecn = !this->config->has_option(this->config, OPT_NO_COPY_ECN),
|
||||
@@ -899,6 +900,11 @@ static status_t install_internal(private_child_sa_t *this, chunk_t encr,
|
||||
.update = update,
|
||||
};
|
||||
|
||||
if (sa.mark.value == MARK_SAME)
|
||||
{
|
||||
sa.mark.value = inbound ? this->mark_in.value : this->mark_out.value;
|
||||
}
|
||||
|
||||
status = charon->kernel->add_sa(charon->kernel, &id, &sa);
|
||||
|
||||
my_ts->destroy(my_ts);
|
||||
|
||||
@@ -69,7 +69,7 @@ bool ipsec_sa_cfg_equals(ipsec_sa_cfg_t *a, ipsec_sa_cfg_t *b)
|
||||
/*
|
||||
* See header
|
||||
*/
|
||||
bool mark_from_string(const char *value, mark_t *mark)
|
||||
bool mark_from_string(const char *value, mark_op_t ops, mark_t *mark)
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
@@ -79,6 +79,11 @@ bool mark_from_string(const char *value, mark_t *mark)
|
||||
}
|
||||
if (strcasepfx(value, "%unique"))
|
||||
{
|
||||
if (!(ops & MARK_OP_UNIQUE))
|
||||
{
|
||||
DBG1(DBG_APP, "unexpected use of %%unique mark", value);
|
||||
return FALSE;
|
||||
}
|
||||
endptr = (char*)value + strlen("%unique");
|
||||
if (strcasepfx(endptr, "-dir"))
|
||||
{
|
||||
@@ -95,6 +100,24 @@ bool mark_from_string(const char *value, mark_t *mark)
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (strcasepfx(value, "%same"))
|
||||
{
|
||||
if (!(ops & MARK_OP_SAME))
|
||||
{
|
||||
DBG1(DBG_APP, "unexpected use of %%same mark", value);
|
||||
return FALSE;
|
||||
}
|
||||
endptr = (char*)value + strlen("%same");
|
||||
if (!*endptr || *endptr == '/')
|
||||
{
|
||||
mark->value = MARK_SAME;
|
||||
}
|
||||
else
|
||||
{
|
||||
DBG1(DBG_APP, "invalid mark value: %s", value);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mark->value = strtoul(value, &endptr, 0);
|
||||
|
||||
@@ -28,6 +28,7 @@ typedef enum policy_priority_t policy_priority_t;
|
||||
typedef enum ipcomp_transform_t ipcomp_transform_t;
|
||||
typedef enum hw_offload_t hw_offload_t;
|
||||
typedef enum dscp_copy_t dscp_copy_t;
|
||||
typedef enum mark_op_t mark_op_t;
|
||||
typedef struct ipsec_sa_cfg_t ipsec_sa_cfg_t;
|
||||
typedef struct lifetime_cfg_t lifetime_cfg_t;
|
||||
typedef struct mark_t mark_t;
|
||||
@@ -214,15 +215,29 @@ struct mark_t {
|
||||
*/
|
||||
#define MARK_UNIQUE (0xFFFFFFFF)
|
||||
#define MARK_UNIQUE_DIR (0xFFFFFFFE)
|
||||
#define MARK_SAME (0xFFFFFFFF)
|
||||
#define MARK_IS_UNIQUE(m) ((m) == MARK_UNIQUE || (m) == MARK_UNIQUE_DIR)
|
||||
|
||||
/**
|
||||
* Special mark operations to accept when parsing marks.
|
||||
*/
|
||||
enum mark_op_t {
|
||||
/** none of the following */
|
||||
MARK_OP_NONE = 0,
|
||||
/** %unique and %unique-dir */
|
||||
MARK_OP_UNIQUE = (1<<0),
|
||||
/** %same */
|
||||
MARK_OP_SAME = (1<<1),
|
||||
};
|
||||
|
||||
/**
|
||||
* Try to parse a mark_t from the given string of the form mark[/mask].
|
||||
*
|
||||
* @param value string to parse
|
||||
* @param ops operations to accept
|
||||
* @param mark mark to fill
|
||||
* @return TRUE if parsing was successful
|
||||
*/
|
||||
bool mark_from_string(const char *value, mark_t *mark);
|
||||
bool mark_from_string(const char *value, mark_op_t ops, mark_t *mark);
|
||||
|
||||
#endif /** IPSEC_TYPES_H_ @}*/
|
||||
|
||||
@@ -860,47 +860,75 @@ END_TEST
|
||||
static struct {
|
||||
char *s;
|
||||
bool ok;
|
||||
mark_op_t ops;
|
||||
mark_t m;
|
||||
} mark_data[] = {
|
||||
{NULL, FALSE, { 0 }},
|
||||
{"", TRUE, { 0, 0xffffffff }},
|
||||
{"/", TRUE, { 0, 0 }},
|
||||
{"42", TRUE, { 42, 0xffffffff }},
|
||||
{"0x42", TRUE, { 0x42, 0xffffffff }},
|
||||
{"x", FALSE, { 0 }},
|
||||
{"42/", TRUE, { 0, 0 }},
|
||||
{"42/0", TRUE, { 0, 0 }},
|
||||
{"42/x", FALSE, { 0 }},
|
||||
{"42/42", TRUE, { 42, 42 }},
|
||||
{"42/0xff", TRUE, { 42, 0xff }},
|
||||
{"0x42/0xff", TRUE, { 0x42, 0xff }},
|
||||
{"/0xff", TRUE, { 0, 0xff }},
|
||||
{"/x", FALSE, { 0 }},
|
||||
{"x/x", FALSE, { 0 }},
|
||||
{"0xfffffff0/0x0000ffff", TRUE, { 0x0000fff0, 0x0000ffff }},
|
||||
{"%unique", TRUE, { MARK_UNIQUE, 0xffffffff }},
|
||||
{"%unique/", TRUE, { MARK_UNIQUE, 0 }},
|
||||
{"%unique/0x0000ffff", TRUE, { MARK_UNIQUE, 0x0000ffff }},
|
||||
{"%unique/0xffffffff", TRUE, { MARK_UNIQUE, 0xffffffff }},
|
||||
{"%unique0xffffffffff", FALSE, { 0, 0 }},
|
||||
{"0xffffffff/0x0000ffff", TRUE, { MARK_UNIQUE, 0x0000ffff }},
|
||||
{"0xffffffff/0xffffffff", TRUE, { MARK_UNIQUE, 0xffffffff }},
|
||||
{"%unique-dir", TRUE, { MARK_UNIQUE_DIR, 0xffffffff }},
|
||||
{"%unique-dir/", TRUE, { MARK_UNIQUE_DIR, 0 }},
|
||||
{"%unique-dir/0x0000ffff", TRUE, { MARK_UNIQUE_DIR, 0x0000ffff }},
|
||||
{"%unique-dir/0xffffffff", TRUE, { MARK_UNIQUE_DIR, 0xffffffff }},
|
||||
{"%unique-dir0xffffffff", FALSE, { 0, 0 }},
|
||||
{"0xfffffffe/0x0000ffff", TRUE, { MARK_UNIQUE_DIR, 0x0000ffff }},
|
||||
{"0xfffffffe/0xffffffff", TRUE, { MARK_UNIQUE_DIR, 0xffffffff }},
|
||||
{"%unique-/0xffffffff", FALSE, { 0, 0 }},
|
||||
{"%unique-foo/0xffffffff", FALSE, { 0, 0 }},
|
||||
{NULL, FALSE, MARK_OP_NONE, { 0 }},
|
||||
{"", TRUE, MARK_OP_NONE, { 0, 0xffffffff }},
|
||||
{"/", TRUE, MARK_OP_NONE, { 0, 0 }},
|
||||
{"42", TRUE, MARK_OP_NONE, { 42, 0xffffffff }},
|
||||
{"0x42", TRUE, MARK_OP_NONE, { 0x42, 0xffffffff }},
|
||||
{"x", FALSE, MARK_OP_NONE, { 0 }},
|
||||
{"42/", TRUE, MARK_OP_NONE, { 0, 0 }},
|
||||
{"42/0", TRUE, MARK_OP_NONE, { 0, 0 }},
|
||||
{"42/x", FALSE, MARK_OP_NONE, { 0 }},
|
||||
{"42/42", TRUE, MARK_OP_NONE, { 42, 42 }},
|
||||
{"42/0xff", TRUE, MARK_OP_NONE, { 42, 0xff }},
|
||||
{"0x42/0xff", TRUE, MARK_OP_NONE, { 0x42, 0xff }},
|
||||
{"/0xff", TRUE, MARK_OP_NONE, { 0, 0xff }},
|
||||
{"/x", FALSE, MARK_OP_NONE, { 0 }},
|
||||
{"x/x", FALSE, MARK_OP_NONE, { 0 }},
|
||||
{"0xfffffff0/0x0000ffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ 0x0000fff0, 0x0000ffff }},
|
||||
{"%unique", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE, 0xffffffff }},
|
||||
{"%unique/", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE, 0 }},
|
||||
{"%unique", FALSE, MARK_OP_NONE,
|
||||
{ 0, 0 }},
|
||||
{"%unique/0x0000ffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE, 0x0000ffff }},
|
||||
{"%unique/0xffffffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE, 0xffffffff }},
|
||||
{"%unique0xffffffffff", FALSE, MARK_OP_UNIQUE,
|
||||
{ 0, 0 }},
|
||||
{"0xffffffff/0x0000ffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE, 0x0000ffff }},
|
||||
{"0xffffffff/0xffffffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE, 0xffffffff }},
|
||||
{"%unique-dir", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE_DIR, 0xffffffff }},
|
||||
{"%unique-dir/", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE_DIR, 0 }},
|
||||
{"%unique-dir", FALSE, MARK_OP_NONE,
|
||||
{ 0, 0 }},
|
||||
{"%unique-dir/0x0000ffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE_DIR, 0x0000ffff }},
|
||||
{"%unique-dir/0xffffffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE_DIR, 0xffffffff }},
|
||||
{"%unique-dir0xffffffff", FALSE, MARK_OP_UNIQUE,
|
||||
{ 0, 0 }},
|
||||
{"0xfffffffe/0x0000ffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE_DIR, 0x0000ffff }},
|
||||
{"0xfffffffe/0xffffffff", TRUE, MARK_OP_UNIQUE,
|
||||
{ MARK_UNIQUE_DIR, 0xffffffff }},
|
||||
{"%unique-/0xffffffff", FALSE, MARK_OP_UNIQUE,
|
||||
{ 0, 0 }},
|
||||
{"%unique-foo/0xffffffff", FALSE, MARK_OP_UNIQUE,
|
||||
{ 0, 0 }},
|
||||
{"%same", TRUE, MARK_OP_SAME,
|
||||
{ MARK_SAME, 0xffffffff }},
|
||||
{"%same/0x0000ffff", TRUE, MARK_OP_SAME,
|
||||
{ MARK_SAME, 0x0000ffff }},
|
||||
{"%%same", FALSE, MARK_OP_NONE,
|
||||
{ 0, 0 }},
|
||||
};
|
||||
|
||||
START_TEST(test_mark_from_string)
|
||||
{
|
||||
mark_t mark;
|
||||
|
||||
if (mark_from_string(mark_data[_i].s, &mark))
|
||||
if (mark_from_string(mark_data[_i].s, mark_data[_i].ops, &mark))
|
||||
{
|
||||
ck_assert_int_eq(mark.value, mark_data[_i].m.value);
|
||||
ck_assert_int_eq(mark.mask, mark_data[_i].m.mask);
|
||||
|
||||
@@ -444,7 +444,7 @@ static void handle_keyword(kw_token_t token, starter_conn_t *conn, char *key,
|
||||
KW_SA_OPTION_FLAG("yes", "no", SA_OPTION_COMPRESS)
|
||||
break;
|
||||
case KW_MARK:
|
||||
if (!mark_from_string(value, &conn->mark_in))
|
||||
if (!mark_from_string(value, MARK_OP_UNIQUE, &conn->mark_in))
|
||||
{
|
||||
cfg->err++;
|
||||
break;
|
||||
@@ -452,13 +452,13 @@ static void handle_keyword(kw_token_t token, starter_conn_t *conn, char *key,
|
||||
conn->mark_out = conn->mark_in;
|
||||
break;
|
||||
case KW_MARK_IN:
|
||||
if (!mark_from_string(value, &conn->mark_in))
|
||||
if (!mark_from_string(value, MARK_OP_UNIQUE, &conn->mark_in))
|
||||
{
|
||||
cfg->err++;
|
||||
}
|
||||
break;
|
||||
case KW_MARK_OUT:
|
||||
if (!mark_from_string(value, &conn->mark_out))
|
||||
if (!mark_from_string(value, MARK_OP_UNIQUE, &conn->mark_out))
|
||||
{
|
||||
cfg->err++;
|
||||
}
|
||||
|
||||
@@ -910,6 +910,37 @@ connections.<conn>.children.<child>.mark_out = 0/0x00000000
|
||||
An additional mask may be appended to the mark, separated by _/_. The
|
||||
default mask if omitted is 0xffffffff.
|
||||
|
||||
connections.<conn>.children.<child>.set_mark_in = 0/0x00000000
|
||||
Netfilter mark applied to packets after the inbound IPsec SA processed them.
|
||||
|
||||
Netfilter mark applied to packets after the inbound IPsec SA processed them.
|
||||
This way it's not necessary to mark packets via Netfilter before decryption
|
||||
or right afterwards to match policies or process them differently (e.g. via
|
||||
policy routing).
|
||||
|
||||
An additional mask may be appended to the mark, separated by _/_. The
|
||||
default mask if omitted is 0xffffffff. The special value _%same_ uses
|
||||
the value (but not the mask) from **mark_in** as mark value, which can be
|
||||
fixed, _%unique_ or _%unique-dir_.
|
||||
|
||||
Setting marks in XFRM input requires Linux 4.19 or higher.
|
||||
|
||||
connections.<conn>.children.<child>.set_mark_out = 0/0x00000000
|
||||
Netfilter mark applied to packets after the outbound IPsec SA processed
|
||||
them.
|
||||
|
||||
Netfilter mark applied to packets after the outbound IPsec SA processed
|
||||
them. This allows processing ESP packets differently than the original
|
||||
traffic (e.g. via policy routing).
|
||||
|
||||
An additional mask may be appended to the mark, separated by _/_. The
|
||||
default mask if omitted is 0xffffffff. The special value _%same_ uses
|
||||
the value (but not the mask) from **mark_out** as mark value, which can be
|
||||
fixed, _%unique_ or _%unique-dir_.
|
||||
|
||||
Setting marks in XFRM output is supported since Linux 4.14. Setting a mask
|
||||
requires at least Linux 4.19.
|
||||
|
||||
connections.<conn>.children.<child>.tfc_padding = 0
|
||||
Traffic Flow Confidentiality padding.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user