aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2016-03-07 16:52:43 +0100
committerTobias Brunner <tobias@strongswan.org>2016-03-10 17:26:26 +0100
commitc659d369a0b81c0e723d73964ddf80a79bc1d44e (patch)
tree2edd3720cdec8aca4a3a756f9680d656582a6f3d /src
parent7c9e7eb9334beeca94e7d97f7b4cbed718e9dc2d (diff)
downloadstrongswan-c659d369a0b81c0e723d73964ddf80a79bc1d44e.tar.bz2
strongswan-c659d369a0b81c0e723d73964ddf80a79bc1d44e.tar.xz
connmark: Don't restore CONNMARK for packets that already have a mark set
This allows e.g. modified versions of xl2tpd to set the mark in situations where two clients are using the same source port behind the same NAT, which CONNMARK can't restore properly as only one conntrack entry will exist with the mark set to that of the client that sent the last packet. Fixes #1230.
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/connmark/connmark_listener.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/src/libcharon/plugins/connmark/connmark_listener.c b/src/libcharon/plugins/connmark/connmark_listener.c
index 9dde7c1c5..607316f7b 100644
--- a/src/libcharon/plugins/connmark/connmark_listener.c
+++ b/src/libcharon/plugins/connmark/connmark_listener.c
@@ -308,13 +308,16 @@ static bool manage_in(private_connmark_listener_t *this,
}
/**
- * Add outbund rule restoring CONNMARK on matching traffic
+ * Add outbund rule restoring CONNMARK on matching traffic unless the packet
+ * already has a mark set
*/
static bool manage_out(private_connmark_listener_t *this,
struct iptc_handle *ipth, bool add,
traffic_selector_t *dst, traffic_selector_t *src)
{
- u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry));
+ u_int16_t match_size = XT_ALIGN(sizeof(struct ipt_entry_match)) +
+ XT_ALIGN(sizeof(struct xt_mark_mtinfo1));
+ u_int16_t target_offset = XT_ALIGN(sizeof(struct ipt_entry)) + match_size;
u_int16_t target_size = XT_ALIGN(sizeof(struct ipt_entry_target)) +
XT_ALIGN(sizeof(struct xt_connmark_tginfo1));
u_int16_t entry_size = target_offset + target_size;
@@ -331,6 +334,18 @@ static bool manage_out(private_connmark_listener_t *this,
{
return FALSE;
}
+ ADD_STRUCT(pos, struct ipt_entry_match,
+ .u = {
+ .user = {
+ .match_size = match_size,
+ .name = "mark",
+ .revision = 1,
+ },
+ },
+ );
+ ADD_STRUCT(pos, struct xt_mark_mtinfo1,
+ .mask = ~0,
+ );
ADD_STRUCT(pos, struct ipt_entry_target,
.u = {
.user = {