Hi Florian,
I attached two 'draft' patches in this email :)
Thanks,
Jack
From 6d811e63c9c777ed4287bc4547134c99e939b49d Mon Sep 17 00:00:00 2001
From: Jack Ma <jack.ma@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 12 Feb 2018 13:41:29 +1300
Subject: [PATCH] libxt_CONNMARK: Support bit-shifting for --restore,set and
save-mark
Added bit-shifting operations for --restore & set & save-mark.
Signed-off-by: Jack Ma <jack.ma@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
extensions/libxt_CONNMARK.c | 176 ++++++++++++++++++++++++++--------
include/linux/netfilter/xt_connmark.h | 2 +-
2 files changed, 139 insertions(+), 39 deletions(-)
diff --git a/extensions/libxt_CONNMARK.c b/extensions/libxt_CONNMARK.c
index f60be583..dbd02351 100644
--- a/extensions/libxt_CONNMARK.c
+++ b/extensions/libxt_CONNMARK.c
@@ -28,32 +28,43 @@
struct xt_connmark_target_info {
unsigned long mark;
unsigned long mask;
+ uint8_t shift_dir;
+ uint8_t shift_bits;
uint8_t mode;
};
enum {
+ D_SHIFT_LEFT = 0,
+ D_SHIFT_RIGHT,
+};
+
+enum {
O_SET_MARK = 0,
O_SAVE_MARK,
O_RESTORE_MARK,
O_AND_MARK,
O_OR_MARK,
O_XOR_MARK,
+ O_LEFT_SHIFT_MARK,
+ O_RIGHT_SHIFT_MARK,
O_SET_XMARK,
O_CTMASK,
O_NFMASK,
O_MASK,
- F_SET_MARK = 1 << O_SET_MARK,
- F_SAVE_MARK = 1 << O_SAVE_MARK,
- F_RESTORE_MARK = 1 << O_RESTORE_MARK,
- F_AND_MARK = 1 << O_AND_MARK,
- F_OR_MARK = 1 << O_OR_MARK,
- F_XOR_MARK = 1 << O_XOR_MARK,
- F_SET_XMARK = 1 << O_SET_XMARK,
- F_CTMASK = 1 << O_CTMASK,
- F_NFMASK = 1 << O_NFMASK,
- F_MASK = 1 << O_MASK,
- F_OP_ANY = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
- F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
+ F_SET_MARK = 1 << O_SET_MARK,
+ F_SAVE_MARK = 1 << O_SAVE_MARK,
+ F_RESTORE_MARK = 1 << O_RESTORE_MARK,
+ F_AND_MARK = 1 << O_AND_MARK,
+ F_OR_MARK = 1 << O_OR_MARK,
+ F_XOR_MARK = 1 << O_XOR_MARK,
+ F_LEFT_SHIFT_MARK = 1 << O_LEFT_SHIFT_MARK,
+ F_RIGHT_SHIFT_MARK = 1 << O_RIGHT_SHIFT_MARK,
+ F_SET_XMARK = 1 << O_SET_XMARK,
+ F_CTMASK = 1 << O_CTMASK,
+ F_NFMASK = 1 << O_NFMASK,
+ F_MASK = 1 << O_MASK,
+ F_OP_ANY = F_SET_MARK | F_SAVE_MARK | F_RESTORE_MARK |
+ F_AND_MARK | F_OR_MARK | F_XOR_MARK | F_SET_XMARK,
};
static void CONNMARK_help(void)
@@ -74,6 +85,8 @@ static const struct xt_option_entry CONNMARK_opts[] = {
{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
.excl = F_OP_ANY},
{.name = "mask", .id = O_MASK, .type = XTTYPE_UINT32},
+ {.name = "left-shift-mark", .id = O_LEFT_SHIFT_MARK, .type = XTTYPE_UINT8},
+ {.name = "right-shift-mark", .id = O_RIGHT_SHIFT_MARK, .type = XTTYPE_UINT8},
XTOPT_TABLEEND,
};
#undef s
@@ -94,6 +107,8 @@ static const struct xt_option_entry connmark_tg_opts[] = {
.excl = F_OP_ANY},
{.name = "restore-mark", .id = O_RESTORE_MARK, .type = XTTYPE_NONE,
.excl = F_OP_ANY},
+ {.name = "left-shift-mark", .id = O_LEFT_SHIFT_MARK, .type = XTTYPE_UINT8},
+ {.name = "right-shift-mark", .id = O_RIGHT_SHIFT_MARK, .type = XTTYPE_UINT8},
{.name = "ctmask", .id = O_CTMASK, .type = XTTYPE_UINT32,
.excl = F_MASK, .flags = XTOPT_PUT, XTOPT_POINTER(s, ctmask)},
{.name = "nfmask", .id = O_NFMASK, .type = XTTYPE_UINT32,
@@ -119,6 +134,8 @@ static void connmark_tg_help(void)
" --and-mark value Binary AND the ctmark with bits\n"
" --or-mark value Binary OR the ctmark with bits\n"
" --xor-mark value Binary XOR the ctmark with bits\n"
+" --left-shift-mark value Left shift the ctmark with bits\n"
+" --right-shift-mark value Right shift the ctmark with bits\n"
);
}
@@ -154,6 +171,16 @@ static void CONNMARK_parse(struct xt_option_call *cb)
case O_MASK:
markinfo->mask = cb->val.u32;
break;
+ case O_LEFT_SHIFT_MARK:
+ markinfo->mode = XT_CONNMARK_RESTORE;
+ markinfo->shift_dir = D_SHIFT_LEFT;
+ markinfo->shift_bits = cb->val.u8;
+ break;
+ case O_RIGHT_SHIFT_MARK:
+ markinfo->mode = XT_CONNMARK_RESTORE;
+ markinfo->shift_dir = D_SHIFT_RIGHT;
+ markinfo->shift_bits = cb->val.u8;
+ break;
}
}
@@ -197,6 +224,14 @@ static void connmark_tg_parse(struct xt_option_call *cb)
case O_MASK:
info->nfmask = info->ctmask = cb->val.u32;
break;
+ case O_LEFT_SHIFT_MARK:
+ info->shift_dir = D_SHIFT_LEFT;
+ info->shift_bits = cb->val.u8;
+ break;
+ case O_RIGHT_SHIFT_MARK:
+ info->shift_dir = D_SHIFT_RIGHT;
+ info->shift_bits = cb->val.u8;
+ break;
}
}
@@ -253,36 +288,101 @@ connmark_tg_print(const void *ip, const struct xt_entry_target *target,
switch (info->mode) {
case XT_CONNMARK_SET:
- if (info->ctmark == 0)
- printf(" CONNMARK and 0x%x",
- (unsigned int)(uint32_t)~info->ctmask);
- else if (info->ctmark == info->ctmask)
- printf(" CONNMARK or 0x%x", info->ctmark);
- else if (info->ctmask == 0)
- printf(" CONNMARK xor 0x%x", info->ctmark);
- else if (info->ctmask == 0xFFFFFFFFU)
- printf(" CONNMARK set 0x%x", info->ctmark);
- else
- printf(" CONNMARK xset 0x%x/0x%x",
- info->ctmark, info->ctmask);
+ if (info->ctmark == 0) {
+ if (info->shift_bits)
+ printf(" CONNMARK and 0x%x %s %d",
+ (unsigned int)(uint32_t)~info->ctmask,
+ info->shift_dir == D_SHIFT_LEFT ? "<<" : ">>",
+ info->shift_bits);
+ else
+ printf(" CONNMARK and 0x%x",
+ (unsigned int)(uint32_t)~info->ctmask);
+ }
+ else if (info->ctmark == info->ctmask) {
+ if (info->shift_bits)
+ printf(" CONNMARK or 0x%x %s %d", info->ctmark,
+ info->shift_dir == D_SHIFT_LEFT ? "<<" : ">>",
+ info->shift_bits);
+ else
+ printf(" CONNMARK or 0x%x", info->ctmark);
+ }
+ else if (info->ctmask == 0) {
+ if (info->shift_bits)
+ printf(" CONNMARK xor 0x%x %s %d", info->ctmark,
+ info->shift_dir == D_SHIFT_LEFT ? "<<" : ">>",
+ info->shift_bits);
+ else
+ printf(" CONNMARK xor 0x%x", info->ctmark);
+ }
+ else if (info->ctmask == 0xFFFFFFFFU) {
+ if (info->shift_bits)
+ printf(" CONNMARK set 0x%x %s %d", info->ctmark,
+ info->shift_dir == D_SHIFT_LEFT ? "<<" : ">>",
+ info->shift_bits);
+ else
+ printf(" CONNMARK set 0x%x", info->ctmark);
+ }
+ else {
+ if (info->shift_bits)
+ printf(" CONNMARK xset 0x%x/0x%x %s %d",
+ info->ctmark, info->ctmask, info->shift_dir ==
+ D_SHIFT_LEFT ? "<<" : ">>", info->shift_bits);
+ else
+ printf(" CONNMARK xset 0x%x/0x%x",
+ info->ctmark, info->ctmask);
+ }
break;
case XT_CONNMARK_SAVE:
- if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX)
- printf(" CONNMARK save");
- else if (info->nfmask == info->ctmask)
- printf(" CONNMARK save mask 0x%x", info->nfmask);
- else
- printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
- info->nfmask, info->ctmask);
+ if (info->nfmask == UINT32_MAX && info->ctmask == UINT32_MAX) {
+ if (info->shift_bits)
+ printf(" CONNMARK save %s %d", info->shift_dir ==
+ D_SHIFT_LEFT ? "<<" : ">>", info->shift_bits);
+ else
+ printf(" CONNMARK save");
+ }
+ else if (info->nfmask == info->ctmask) {
+ if (info->shift_bits)
+ printf(" CONNMARK save mask 0x%x %s %d", info->nfmask,
+ info->shift_dir == D_SHIFT_LEFT ? "<<" : ">>",
+ info->shift_bits);
+ else
+ printf(" CONNMARK save mask 0x%x", info->nfmask);
+ }
+ else {
+ if (info->shift_bits)
+ printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x %s %d",
+ info->nfmask, info->ctmask, info->shift_dir ==
+ D_SHIFT_LEFT ? "<<" : ">>", info->shift_bits);
+ else
+ printf(" CONNMARK save nfmask 0x%x ctmask ~0x%x",
+ info->nfmask, info->ctmask);
+ }
break;
case XT_CONNMARK_RESTORE:
- if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX)
- printf(" CONNMARK restore");
- else if (info->ctmask == info->nfmask)
- printf(" CONNMARK restore mask 0x%x", info->ctmask);
- else
- printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
- info->ctmask, info->nfmask);
+ if (info->ctmask == UINT32_MAX && info->nfmask == UINT32_MAX) {
+ if (info->shift_bits)
+ printf(" CONNMARK restore %s %d", info->shift_dir ==
+ D_SHIFT_LEFT ? "<<" : ">>", info->shift_bits);
+ else
+ printf(" CONNMARK restore");
+ }
+ else if (info->ctmask == info->nfmask) {
+ if (info->shift_bits)
+ printf(" CONNMARK restore mask 0x%x %s %d", info->ctmask,
+ info->shift_dir == D_SHIFT_LEFT ? "<<" : ">>",
+ info->shift_bits);
+ else
+ printf(" CONNMARK restore mask 0x%x", info->ctmask);
+ }
+ else {
+ if (info->shift_bits)
+ printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x %s %d",
+ info->ctmask, info->nfmask, info->shift_dir ==
+ D_SHIFT_LEFT ? "<<" : ">>", info->shift_bits);
+ else
+ printf(" CONNMARK restore ctmask 0x%x nfmask ~0x%x",
+ info->ctmask, info->nfmask);
+ }
break;
default:
diff --git a/include/linux/netfilter/xt_connmark.h b/include/linux/netfilter/xt_connmark.h
index efc17a83..2010a40c 100644
--- a/include/linux/netfilter/xt_connmark.h
+++ b/include/linux/netfilter/xt_connmark.h
@@ -20,7 +20,7 @@ enum {
struct xt_connmark_tginfo1 {
__u32 ctmark, ctmask, nfmask;
- __u8 mode;
+ __u8 shift_dir, shift_bits, mode;
};
struct xt_connmark_mtinfo1 {
--
2.13.0
From b6ff58635bb42cd4c14e03ebfccb9236fd0d5001 Mon Sep 17 00:00:00 2001
From: Jack Ma <jack.ma@xxxxxxxxxxxxxxxxxxx>
Date: Mon, 12 Feb 2018 11:13:08 +1300
Subject: [PATCH] xt_conntrack: Support bit-shifting for CONNMARK & MARK.
Bit-shifting operations are added to accompany with --restore,set,
save-mark + --mask.
Signed-off-by: Jack Ma <jack.ma@xxxxxxxxxxxxxxxxxxx>
Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
include/uapi/linux/netfilter/xt_connmark.h | 7 ++++++-
net/netfilter/xt_connmark.c | 16 ++++++++++++----
2 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/include/uapi/linux/netfilter/xt_connmark.h b/include/uapi/linux/netfilter/xt_connmark.h
index 408a9654f05c..28834812124f 100644
--- a/include/uapi/linux/netfilter/xt_connmark.h
+++ b/include/uapi/linux/netfilter/xt_connmark.h
@@ -19,9 +19,14 @@ enum {
XT_CONNMARK_RESTORE
};
+enum {
+ D_SHIFT_LEFT = 0,
+ D_SHIFT_RIGHT,
+};
+
struct xt_connmark_tginfo1 {
__u32 ctmark, ctmask, nfmask;
- __u8 mode;
+ __u8 shift_dir, shift_bits, mode;
};
struct xt_connmark_mtinfo1 {
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index ec377cc6a369..31cb0acb6208 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -51,7 +51,10 @@ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
case XT_CONNMARK_SET:
newmark = (ct->mark & ~info->ctmask) ^ info->ctmark;
if (ct->mark != newmark) {
- ct->mark = newmark;
+ if (info->shift_dir == D_SHIFT_RIGHT)
+ ct->mark = newmark >> info->shift_bits;
+ else
+ ct->mark = newmark << info->shift_bits;
nf_conntrack_event_cache(IPCT_MARK, ct);
}
break;
@@ -59,17 +62,22 @@ connmark_tg(struct sk_buff *skb, const struct xt_action_param *par)
newmark = (ct->mark & ~info->ctmask) ^
(skb->mark & info->nfmask);
if (ct->mark != newmark) {
- ct->mark = newmark;
+ if (info->shift_dir == D_SHIFT_RIGHT)
+ ct->mark = newmark >> info->shift_bits;
+ else
+ ct->mark = newmark << info->shift_bits;
nf_conntrack_event_cache(IPCT_MARK, ct);
}
break;
case XT_CONNMARK_RESTORE:
newmark = (skb->mark & ~info->nfmask) ^
(ct->mark & info->ctmask);
- skb->mark = newmark;
+ if (info->shift_dir == D_SHIFT_RIGHT)
+ skb->mark = newmark >> info->shift_bits;
+ else
+ skb->mark = newmark << info->shift_bits;
break;
}
-
return XT_CONTINUE;
}
--
2.13.0