From c659d369a0b81c0e723d73964ddf80a79bc1d44e Mon Sep 17 00:00:00 2001 From: Tobias Brunner Date: Mon, 7 Mar 2016 16:52:43 +0100 Subject: [PATCH] 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. --- .../plugins/connmark/connmark_listener.c | 19 +++++++++++++++++-- 1 file 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 = {