netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH 2/2] extensions: add HMARK target
@ 2012-07-12  7:34 Hans Schillstrom
  2012-07-12 15:29 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 5+ messages in thread
From: Hans Schillstrom @ 2012-07-12  7:34 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Hi Pablo
[snip]
+static void HMARK_check(struct xt_fcheck_call *cb)
>+{
>+	if (!(cb->xflags & (1 << O_HMARK_MODULUS)))
>+		xtables_error(PARAMETER_PROBLEM, "--hmark-mod is mandatory");
>+	if (!(cb->xflags & (1 << O_HMARK_RND)))
>+		xtables_error(PARAMETER_PROBLEM, "--hmark-rnd is mandatory");

I don't think rnd should be mandatory, a default value is enough.
offset however should be mandatory.




^ permalink raw reply	[flat|nested] 5+ messages in thread
* Re[2]:  [PATCH 2/2] extensions: add HMARK target
@ 2012-07-14 22:53 Hans Schillstrom
  2012-07-16 12:22 ` Pablo Neira Ayuso
  0 siblings, 1 reply; 5+ messages in thread
From: Hans Schillstrom @ 2012-07-14 22:53 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

>
>On Thu, Jul 12, 2012 at 09:34:45AM +0200, Hans Schillstrom wrote:
>> Hi Pablo
>> [snip]
>> +static void HMARK_check(struct xt_fcheck_call *cb)
>> >+{
>> >+	if (!(cb->xflags & (1 << O_HMARK_MODULUS)))
>> >+		xtables_error(PARAMETER_PROBLEM, "--hmark-mod is mandatory");
>> >+	if (!(cb->xflags & (1 << O_HMARK_RND)))
>> >+		xtables_error(PARAMETER_PROBLEM, "--hmark-rnd is mandatory");
>> 
>> I don't think rnd should be mandatory, a default value is enough.
>> offset however should be mandatory.
>
>As I said, parameters that are not set will likely not be set by
>users. If default value for random, the easier it will be for an
>attacker to direct all flows to the same target.

If he knows the modulo, and assume that default rand.value  is used....
I still don't think rnd should be mandatory, but I can live with it.

>
>I'll be OK to make --hmark-offset mandatory, BTW.
Well,  if people use it to other things than PBR it will be bad to have it mandatory
so I think we leave it as it is.

I don't like is that MODE_L3 is gone 
L3 can be substituted by using --hamrk-tuple src, dst. so that might be OK
but there is no flag set. (causing a lot of extra cpu cycles)

All masks have gone from set to  zero, (due to hmark-tuple ?)
If it's more clear or not , I don't know  but the man page needs to be updated
 --hmark-tuple ct alone doesn't do much.

iptables \-t mangle \-A PREROUTING \-m state \-\-state NEW
- \-j HMARK \-\-hmark-tuple ct \-\-hmark-offset 10000 \-\-hmark\-mod 10
change to
+ \-j HMARK \-\-hmark-tuple ct,src,dst \-\-hmark-offset 10000 \-\-hmark\-mod 10
\-\-hmark\-rnd 0xfeedcafe

Some faults found during my first sanity check.
(I have not run any real tests so far, just some manual command  tests
Due to the new behaviour and syntax the test suite needs some update)

diff --git a/extensions/libxt_HMARK.c b/extensions/libxt_HMARK.c
index ee2629d..053bc10 100644
--- a/extensions/libxt_HMARK.c
+++ b/extensions/libxt_HMARK.c
@@ -280,15 +280,15 @@ static void HMARK_check(struct xt_fcheck_call *cb)
 
 static void HMARK_print(const struct xt_hmark_info *info)
 {
-       if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
+       if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
                printf("sport-mask 0x%x ", htons(info->port_mask.p16.src));
-       if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
+       if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
                printf("dport-mask 0x%x ", htons(info->port_mask.p16.dst));
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
                printf("spi-mask 0x%x ", htonl(info->port_mask.v32));
-       if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
+       if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
                printf("sport-set 0x%x ", htons(info->port_set.p16.src));
-       if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
+       if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
                printf("dport-set 0x%x ", htons(info->port_set.p16.dst));
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
                printf("spi-set 0x%x ", htonl(info->port_set.v32));
@@ -333,11 +333,11 @@ static void HMARK_ip4_print(const void *ip,
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
                printf("ct, ");
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
-               printf("src-prefix %s ",
-                      xtables_ipmask_to_numeric(&info->src_mask.in) + 1);
+               printf("src-prefix %d ",
+                      xtables_ipmask_to_cidr(&info->src_mask.in));
        if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
-               printf("dst-prefix %s ",
-                      xtables_ipmask_to_numeric(&info->dst_mask.in) + 1);
+               printf("dst-prefix %d ",
+                      xtables_ipmask_to_cidr(&info->dst_mask.in));
        HMARK_print(info);
 }




^ permalink raw reply related	[flat|nested] 5+ messages in thread
* Re: [PATCH 2/2] extensions: add HMARK target
@ 2012-07-12  7:29 Hans Schillstrom
  0 siblings, 0 replies; 5+ messages in thread
From: Hans Schillstrom @ 2012-07-12  7:29 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Hi Pablo
Some minor typos,
>
>The target allows you to set mark packets based Jenkins' hash calculation:
>
>h(t, rnd) = x
>
>mark = (x % mod) + offset
>
>where:
>
>* t is a tuple that is used for the hashing:
>
> t = [ src, dst, proto, sport, dport ]
>
>Note that you can customize the tuple, thus, removing some component
>that you don't want to use for the calculation. You can also use spi
>instead of sport and dport, btw.
>
>* rnd is the random seed that is explicitly passed via --hmark-mod

Typo , --hmark-rnd is better

>* mod is the modulus, to determine the range of possible marks
>* offset determines where the mark starts from
>
>This target only works for the "raw" and "mangle" tables.
>
>This can be used to distribute flows between a cluster of
>systems and uplinks.
>
>Initially based on work from Hans Schillingstrom. Pablo took it
>over and introduced several improvements.
>
>Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
>Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>---
> extensions/libxt_HMARK.c           |  441 ++++++++++++++++++++++++++++++++++++
> extensions/libxt_HMARK.man         |   60 +++++
> include/linux/netfilter/xt_HMARK.h |   50 ++++
> 3 files changed, 551 insertions(+)
> create mode 100644 extensions/libxt_HMARK.c
> create mode 100644 extensions/libxt_HMARK.man
> create mode 100644 include/linux/netfilter/xt_HMARK.h
>
>diff --git a/extensions/libxt_HMARK.c b/extensions/libxt_HMARK.c
>new file mode 100644
>index 0000000..ee2629d
>--- /dev/null
>+++ b/extensions/libxt_HMARK.c
>@@ -0,0 +1,441 @@
>+/*
>+ * (C) 2012 by Hans Schillstrom <hans.schillstrom@ericsson.com>
>+ * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
>+ *
>+ * This program is free software; you can redistribute it and/or modify
>+ * it under the terms of the GNU General Public License version 2 as
>+ * published by the Free Software Foundation.
>+ *
>+ * Description: shared library add-on to iptables to add HMARK target support
>+ *
>+ * Initial development by Hans Schillstrom. Pablo's improvements to this piece
>+ * of software has been sponsored by Sophos Astaro <http://www.sophos.com>.
>+ */
>+
>+#include <stdbool.h>
>+#include <stdio.h>
>+#include <string.h>
>+
>+#include "xtables.h"
>+#include <linux/netfilter/xt_HMARK.h>
>+
>+static void HMARK_help(void)
>+{
>+	printf(
>+"HMARK target options, i.e. modify hash calculation by:\n"
>+"  --hmark-tuple [src|dst|sport|dport|spi|proto|ct][,...]\n"
>+"  --hmark-mod value		    nfmark modulus value\n"
>+"  --hmark-offset value		    Last action add value to nfmark\n\n"
>+"  --hmark-rnd			    Random see for hashing\n"

Random seed...

>+" Alternatively, fine tuning of what will be included in hash calculation\n"
>+"  --hmark-src-prefix length	    Source address mask CIDR prefix\n"
>+"  --hmark-dst-prefix length	    Dest address mask CIDR prefix\n"
>+"  --hmark-sport-mask value	    Mask src port with value\n"
>+"  --hmark-dport-mask value	    Mask dst port with value\n"
>+"  --hmark-spi-mask value	    For esp and ah AND spi with value\n"
>+"  --hmark-sport-set value	    OR src port with value\n"
>+"  --hmark-dport-set value	    OR dst port with value\n"
>+"  --hmark-spi-set value	    For esp and ah OR spi with value\n"
>+"  --hmark-proto-mask value	    Mask Protocol with value\n");
>+}
>+
>+#define hi struct xt_hmark_info
>+
>+enum {
>+	O_HMARK_SADDR_MASK,
>+	O_HMARK_DADDR_MASK,
>+	O_HMARK_SPI,
>+	O_HMARK_SPI_MASK,
>+	O_HMARK_SPORT,
>+	O_HMARK_DPORT,
>+	O_HMARK_SPORT_MASK,
>+	O_HMARK_DPORT_MASK,
>+	O_HMARK_PROTO_MASK,
>+	O_HMARK_RND,
>+	O_HMARK_MODULUS,
>+	O_HMARK_OFFSET,
>+	O_HMARK_CT,
>+	O_HMARK_TYPE,
>+};
>+
>+#define HMARK_OPT_PKT_MASK			\
>+	((1 << O_HMARK_SADDR_MASK)		| \
>+	 (1 << O_HMARK_DADDR_MASK)		| \
>+	 (1 << O_HMARK_SPI_MASK)		| \
>+	 (1 << O_HMARK_SPORT_MASK)		| \
>+	 (1 << O_HMARK_DPORT_MASK)		| \
>+	 (1 << O_HMARK_PROTO_MASK)		| \
>+	 (1 << O_HMARK_SPI_MASK)		| \
>+	 (1 << O_HMARK_SPORT)			| \
>+	 (1 << O_HMARK_DPORT)			| \
>+	 (1 << O_HMARK_SPI))
>+
>+static const struct xt_option_entry HMARK_opts[] = {
>+	{ .name  = "hmark-tuple",
>+	  .type  = XTTYPE_STRING,
>+	  .id	 = O_HMARK_TYPE,
>+	},
>+	{ .name  = "hmark-src-prefix",
>+	  .type  = XTTYPE_PLENMASK,
>+	  .id	 = O_HMARK_SADDR_MASK,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, src_mask)
>+	},
>+	{ .name  = "hmark-dst-prefix",
>+	  .type  = XTTYPE_PLENMASK,
>+	  .id	 = O_HMARK_DADDR_MASK,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, dst_mask)
>+	},
>+	{ .name  = "hmark-sport-mask",
>+	  .type  = XTTYPE_UINT16,
>+	  .id	 = O_HMARK_SPORT_MASK,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.p16.src)
>+	},
>+	{ .name  = "hmark-dport-mask",
>+	  .type  = XTTYPE_UINT16,
>+	  .id	 = O_HMARK_DPORT_MASK,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.p16.dst)
>+	},
>+	{ .name  = "hmark-spi-mask",
>+	  .type  = XTTYPE_UINT32,
>+	  .id	 = O_HMARK_SPI_MASK,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_mask.v32)
>+	},
>+	{ .name  = "hmark-sport",
>+	  .type  = XTTYPE_UINT16,
>+	  .id	 = O_HMARK_SPORT,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.p16.src)
>+	},
>+	{ .name  = "hmark-dport",
>+	  .type  = XTTYPE_UINT16,
>+	  .id	 = O_HMARK_DPORT,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.p16.dst)
>+	},
>+	{ .name  = "hmark-spi",
>+	  .type  = XTTYPE_UINT32,
>+	  .id	 = O_HMARK_SPI,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, port_set.v32)
>+	},
>+	{ .name  = "hmark-proto-mask",
>+	  .type  = XTTYPE_UINT16,
>+	  .id	 = O_HMARK_PROTO_MASK,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, proto_mask)
>+	},
>+	{ .name  = "hmark-rnd",
>+	  .type  = XTTYPE_UINT32,
>+	  .id	 = O_HMARK_RND,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, hashrnd)
>+	},
>+	{ .name = "hmark-mod",
>+	  .type = XTTYPE_UINT32,
>+	  .id = O_HMARK_MODULUS,
>+	  .min = 1,
>+	  .flags = XTOPT_PUT | XTOPT_MAND, XTOPT_POINTER(hi, hmodulus)
>+	},
>+	{ .name  = "hmark-offset",
>+	  .type  = XTTYPE_UINT32,
>+	  .id	 = O_HMARK_OFFSET,
>+	  .flags = XTOPT_PUT, XTOPT_POINTER(hi, hoffset)
>+	},
>+	XTOPT_TABLEEND,
>+};
>+
>+static int
>+hmark_parse(const char *type, size_t len, struct xt_hmark_info *info,
>+	    unsigned int *xflags)
>+{
>+	if (strncasecmp(type, "ct", len) == 0) {
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_CT);
>+		*xflags |= (1 << O_HMARK_CT);
>+	} else if (strncasecmp(type, "src", len) == 0) {
>+		memset(&info->src_mask, 0xff, sizeof(info->src_mask));
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SADDR_MASK);
>+		*xflags |= (1 << O_HMARK_SADDR_MASK);
>+	} else if (strncasecmp(type, "dst", len) == 0) {
>+		memset(&info->dst_mask, 0xff, sizeof(info->dst_mask));
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_DADDR_MASK);
>+		*xflags |= (1 << O_HMARK_DADDR_MASK);
>+	} else if (strncasecmp(type, "sport", len) == 0) {
>+		memset(&info->port_mask.p16.src, 0xff,
>+			sizeof(info->port_mask.p16.src));
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT_MASK);
>+		*xflags |= (1 << O_HMARK_SPORT_MASK);
>+	} else if (strncasecmp(type, "dport", len) == 0) {
>+		memset(&info->port_mask.p16.dst, 0xff,
>+			sizeof(info->port_mask.p16.dst));
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT_MASK);
>+		*xflags |= (1 << O_HMARK_DPORT_MASK);
>+	} else if (strncasecmp(type, "proto", len) == 0) {
>+		memset(&info->proto_mask, 0xff, sizeof(info->proto_mask));
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_PROTO_MASK);
>+		*xflags |= (1 << O_HMARK_PROTO_MASK);
>+	} else if (strncasecmp(type, "spi", len) == 0) {
>+		memset(&info->port_mask.v32, 0xff, sizeof(info->port_mask.v32));
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI_MASK);
>+		*xflags |= (1 << O_HMARK_SPI_MASK);
>+	} else
>+		return 0;
>+
>+	return 1;
>+}
>+
>+static void
>+hmark_parse_type(struct xt_option_call *cb)
>+{
>+	const char *arg = cb->arg;
>+	struct xt_hmark_info *info = cb->data;
>+	const char *comma;
>+
>+	while ((comma = strchr(arg, ',')) != NULL) {
>+		if (comma == arg ||
>+		    !hmark_parse(arg, comma-arg, info, &cb->xflags))
>+			xtables_error(PARAMETER_PROBLEM, "Bad type \"%s\"", arg);
>+		arg = comma+1;
>+	}
>+	if (!*arg)
>+		xtables_error(PARAMETER_PROBLEM, "\"--hmark-tuple\" requires "
>+						 "a list of types with no "
>+						 "spaces, e.g. "
>+						 "src,dst,sport,dport,proto");
>+	if (strlen(arg) == 0 ||
>+	    !hmark_parse(arg, strlen(arg), info, &cb->xflags))
>+		xtables_error(PARAMETER_PROBLEM, "Bad type \"%s\"", arg);
>+}
>+
>+static void HMARK_parse(struct xt_option_call *cb, int plen)
>+{
>+	struct xt_hmark_info *info = cb->data;
>+
>+	xtables_option_parse(cb);
>+
>+	switch (cb->entry->id) {
>+	case O_HMARK_TYPE:
>+		hmark_parse_type(cb);
>+		break;
>+	case O_HMARK_SADDR_MASK:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SADDR_MASK);
>+		break;
>+	case O_HMARK_DADDR_MASK:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_DADDR_MASK);
>+		break;
>+	case O_HMARK_SPI:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPI_MASK);
>+		break;
>+	case O_HMARK_SPORT:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT);
>+		break;
>+	case O_HMARK_DPORT:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT);
>+		break;
>+	case O_HMARK_SPORT_MASK:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_SPORT_MASK);
>+		break;
>+	case O_HMARK_DPORT_MASK:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_DPORT_MASK);
>+		break;
>+	case O_HMARK_PROTO_MASK:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_PROTO_MASK);
>+		break;
>+	case O_HMARK_RND:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_RND);
>+		break;
>+	case O_HMARK_MODULUS:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_MODULUS);
>+		break;
>+	case O_HMARK_OFFSET:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_OFFSET);
>+		break;
>+	case O_HMARK_CT:
>+		info->flags |= XT_HMARK_FLAG(XT_HMARK_CT);
>+		break;
>+	}
>+	cb->xflags |= (1 << cb->entry->id);
>+}
>+
>+static void HMARK_ip4_parse(struct xt_option_call *cb)
>+{
>+	HMARK_parse(cb, 32);
>+}
>+static void HMARK_ip6_parse(struct xt_option_call *cb)
>+{
>+	HMARK_parse(cb, 128);
>+}
>+
>+static void HMARK_check(struct xt_fcheck_call *cb)
>+{
>+	if (!(cb->xflags & (1 << O_HMARK_MODULUS)))
>+		xtables_error(PARAMETER_PROBLEM, "--hmark-mod is mandatory");
>+	if (!(cb->xflags & (1 << O_HMARK_RND)))
>+		xtables_error(PARAMETER_PROBLEM, "--hmark-rnd is mandatory");
>+	if (cb->xflags & (1 << O_HMARK_SPI_MASK) &&
>+	    (cb->xflags & (1 << O_HMARK_SPORT_MASK ||
>+	     cb->xflags & (1 << O_HMARK_DPORT_MASK))))
>+		xtables_error(PARAMETER_PROBLEM, "you cannot use "
>+				"--hmark-spi-mask and --hmark-?port-mask,"
>+				"at the same time");
>+	if (!((cb->xflags & HMARK_OPT_PKT_MASK) ||
>+	       cb->xflags & (1 << O_HMARK_CT)))
>+		xtables_error(PARAMETER_PROBLEM, "you have to specify "
>+				"--hmark-tuple at least");
>+}
>+
>+static void HMARK_print(const struct xt_hmark_info *info)
>+{
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
>+		printf("sport-mask 0x%x ", htons(info->port_mask.p16.src));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
>+		printf("dport-mask 0x%x ", htons(info->port_mask.p16.dst));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
>+		printf("spi-mask 0x%x ", htonl(info->port_mask.v32));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
>+		printf("sport-set 0x%x ", htons(info->port_set.p16.src));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
>+		printf("dport-set 0x%x ", htons(info->port_set.p16.dst));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
>+		printf("spi-set 0x%x ", htonl(info->port_set.v32));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_PROTO_MASK))
>+		printf("proto-mask 0x%x ", info->proto_mask);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_RND))
>+		printf("rnd 0x%x ", info->hashrnd);
>+}
>+
>+static void HMARK_ip6_print(const void *ip,
>+			    const struct xt_entry_target *target, int numeric)
>+{
>+	const struct xt_hmark_info *info =
>+			(const struct xt_hmark_info *)target->data;
>+
>+	printf(" HMARK ");
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
>+		printf("mod %u ", info->hmodulus);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
>+		printf("+ 0x%x ", info->hoffset);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
>+		printf("ct, ");
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
>+		printf("src-prefix %s ",
>+		       xtables_ip6mask_to_numeric(&info->src_mask.in6) + 1);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
>+		printf("dst-prefix %s ",
>+		       xtables_ip6mask_to_numeric(&info->dst_mask.in6) + 1);
>+	HMARK_print(info);
>+}
>+static void HMARK_ip4_print(const void *ip,
>+			    const struct xt_entry_target *target, int numeric)
>+{
>+	const struct xt_hmark_info *info =
>+		(const struct xt_hmark_info *)target->data;
>+
>+	printf(" HMARK ");
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
>+		printf("mod %u ", info->hmodulus);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
>+		printf("+ 0x%x ", info->hoffset);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
>+		printf("ct, ");
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK))
>+		printf("src-prefix %s ",
>+		       xtables_ipmask_to_numeric(&info->src_mask.in) + 1);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK))
>+		printf("dst-prefix %s ",
>+		       xtables_ipmask_to_numeric(&info->dst_mask.in) + 1);
>+	HMARK_print(info);
>+}
>+
>+static void HMARK_save(const struct xt_hmark_info *info)
>+{
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT_MASK))
>+		printf(" --hmark-sport-mask 0x%04x",
>+		       htons(info->port_mask.p16.src));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT_MASK))
>+		printf(" --hmark-dport-mask 0x%04x",
>+		       htons(info->port_mask.p16.dst));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI))
>+		printf(" --hmark-spi-mask 0x%08x",
>+		       htonl(info->port_mask.v32));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPORT))
>+		printf(" --hmark-sport-set 0x%04x",
>+		       htons(info->port_set.p16.src));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DPORT))
>+		printf(" --hmark-dport-set 0x%04x",
>+		       htons(info->port_set.p16.dst));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SPI_MASK))
>+		printf(" --hmark-spi-set 0x%08x", htonl(info->port_set.v32));
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_PROTO_MASK))
>+		printf(" --hmark-proto-mask 0x%02x", info->proto_mask);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_RND))
>+		printf(" --hmark-rnd 0x%08x", info->hashrnd);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_MODULUS))
>+		printf(" --hmark-mod %u", info->hmodulus);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_OFFSET))
>+		printf(" --hmark-offset %u", info->hoffset);
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_CT))
>+		printf(" --hmark-tuple ct");
>+}
>+
>+static void HMARK_ip6_save(const void *ip, const struct xt_entry_target *target)
>+{
>+	const struct xt_hmark_info *info =
>+		(const struct xt_hmark_info *)target->data;
>+	int ret;
>+
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK)) {
>+		ret = xtables_ip6mask_to_cidr(&info->src_mask.in6);
>+		printf(" --hmark-src-prefix %d", ret);
>+	}
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK)) {
>+		ret = xtables_ip6mask_to_cidr(&info->dst_mask.in6);
>+		printf(" --hmark-dst-prefix %d", ret);
>+	}
>+	HMARK_save(info);
>+}
>+
>+static void HMARK_ip4_save(const void *ip, const struct xt_entry_target *target)
>+{
>+	const struct xt_hmark_info *info =
>+		(const struct xt_hmark_info *)target->data;
>+	int ret;
>+
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_SADDR_MASK)) {
>+		ret = xtables_ipmask_to_cidr(&info->src_mask.in);
>+		printf(" --hmark-src-prefix %d", ret);
>+	}
>+	if (info->flags & XT_HMARK_FLAG(XT_HMARK_DADDR_MASK)) {
>+		ret = xtables_ipmask_to_cidr(&info->dst_mask.in);
>+		printf(" --hmark-dst-prefix %d", ret);
>+	}
>+	HMARK_save(info);
>+}
>+
>+static struct xtables_target mark_tg_reg[] = {
>+	{
>+		.family        = NFPROTO_IPV4,
>+		.name	       = "HMARK",
>+		.version       = XTABLES_VERSION,
>+		.size	       = XT_ALIGN(sizeof(struct xt_hmark_info)),
>+		.userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
>+		.help	       = HMARK_help,
>+		.print	       = HMARK_ip4_print,
>+		.save	       = HMARK_ip4_save,
>+		.x6_parse      = HMARK_ip4_parse,
>+		.x6_fcheck     = HMARK_check,
>+		.x6_options    = HMARK_opts,
>+	},
>+	{
>+		.family        = NFPROTO_IPV6,
>+		.name	       = "HMARK",
>+		.version       = XTABLES_VERSION,
>+		.size	       = XT_ALIGN(sizeof(struct xt_hmark_info)),
>+		.userspacesize = XT_ALIGN(sizeof(struct xt_hmark_info)),
>+		.help	       = HMARK_help,
>+		.print	       = HMARK_ip6_print,
>+		.save	       = HMARK_ip6_save,
>+		.x6_parse      = HMARK_ip6_parse,
>+		.x6_fcheck     = HMARK_check,
>+		.x6_options    = HMARK_opts,
>+	},
>+};
>+
>+void _init(void)
>+{
>+	xtables_register_targets(mark_tg_reg, ARRAY_SIZE(mark_tg_reg));
>+}
>diff --git a/extensions/libxt_HMARK.man b/extensions/libxt_HMARK.man
>new file mode 100644
>index 0000000..6b36b58
>--- /dev/null
>+++ b/extensions/libxt_HMARK.man
>@@ -0,0 +1,60 @@
>+Like MARK, i.e. set the fwmark, but the mark is calculated from hashing
>+packet selector at choice. You have also to specify the mark range and,
>+optionally, the offset to start from. ICMP error messages are inspected
>+and used to calculate the hashing.
>+.PP
>+Existing options are:
>+.TP
>+\fB\-\-hmark\-tuple\fP tuple\fI\fP
>+Possible tuple members are:
>+.B src
>+meaning source address (IPv4, IPv6 address),
>+.B dst
>+meaning destination address (IPv4, IPv6 address),
>+.B sport
>+meaning source port (TCP, UDP, UDPlite, SCTP, DCCP),
>+.B dport
>+meaning destination port (TCP, UDP, UDPlite, SCTP, DCCP),
>+.B spi
>+meaning Security Parameter Index (AH, ESP), and
>+.B ct
>+meaning the usage of the conntrack tuple instead of the packet selectors.
>+.TP
>+\fB\-\-hmark\-mod\fP \fIvalue (must be > 0)\fP
>+Modulus for hash calculation (to limit the range of possible marks)
>+.TP
>+\fB\-\-hmark\-offset\fP \fIvalue\fP
>+Offset to start marks from.
>+.TP
>+For advanced usage, instead of using \-\-hmark\-tuple, you can specify custom
>+prefixes and masks:
>+.TP
>+\fB\-\-hmark\-src\-prefix\fP \fIcidr\fP
>+The source address mask in CIDR notation.
>+.TP
>+\fB\-\-hmark\-dst\-prefix\fP \fIcidr\fP
>+The destination address mask in CIDR notation.
>+.TP
>+\fB\-\-hmark\-sport\-mask\fP \fIvalue\fP
>+A 16 bit source port mask in hexadecimal.
>+.TP
>+\fB\-\-hmark\-dport\-mask\fP \fIvalue\fP
>+A 16 bit destination port mask in hexadecimal.
>+.TP
>+\fB\-\-hmark\-spi\-mask\fP \fIvalue\fP
>+A 32 bit field with spi mask.
>+.TP
>+\fB\-\-hmark\-proto\-mask\fP \fIvalue\fP
>+An 8 bit field with layer 4 protocol number.
>+.TP
>+\fB\-\-hmark\-rnd\fP \fIvalue\fP
>+A 32 bit random custom value to feed hash calculation.
>+.PP
>+\fIExamples:\fP
>+.PP
>+iptables \-t mangle \-A PREROUTING \-m state \-\-state NEW
>+ \-j HMARK \-\-hmark-tuple ct \-\-hmark-offset 10000 \-\-hmark\-mod 10
>+\-\-hmark\-rnd 0xfeedcafe
>+.PP
>+iptables \-t mangle \-A PREROUTING -j HMARK \-\-hmark-tuple src,dst,proto
>+\-\-hmark-mod 10 \-\-hmark\-rand 0xdeafbeef
>diff --git a/include/linux/netfilter/xt_HMARK.h b/include/linux/netfilter/xt_HMARK.h
>new file mode 100644
>index 0000000..826fc58
>--- /dev/null
>+++ b/include/linux/netfilter/xt_HMARK.h
>@@ -0,0 +1,50 @@
>+#ifndef XT_HMARK_H_
>+#define XT_HMARK_H_
>+
>+#include <linux/types.h>
>+
>+enum {
>+	XT_HMARK_SADDR_MASK,
>+	XT_HMARK_DADDR_MASK,
>+	XT_HMARK_SPI,
>+	XT_HMARK_SPI_MASK,
>+	XT_HMARK_SPORT,
>+	XT_HMARK_DPORT,
>+	XT_HMARK_SPORT_MASK,
>+	XT_HMARK_DPORT_MASK,
>+	XT_HMARK_PROTO_MASK,
>+	XT_HMARK_RND,
>+	XT_HMARK_MODULUS,
>+	XT_HMARK_OFFSET,
>+	XT_HMARK_CT,
>+	XT_HMARK_METHOD_L3,
>+	XT_HMARK_METHOD_L3_4,
>+};
>+#define XT_HMARK_FLAG(flag)	(1 << flag)
>+
>+union hmark_ports {
>+	struct {
>+		__u16	src;
>+		__u16	dst;
>+	} p16;
>+	struct {
>+		__be16	src;
>+		__be16	dst;
>+	} b16;
>+	__u32	v32;
>+	__be32	b32;
>+};
>+
>+struct xt_hmark_info {
>+	union nf_inet_addr	src_mask;
>+	union nf_inet_addr	dst_mask;
>+	union hmark_ports	port_mask;
>+	union hmark_ports	port_set;
>+	__u32			flags;
>+	__u16			proto_mask;
>+	__u32			hashrnd;
>+	__u32			hmodulus;
>+	__u32			hoffset;	/* Mark offset to start from */
>+};
>+
>+#endif /* XT_HMARK_H_ */
>-- 
>1.7.10


^ permalink raw reply	[flat|nested] 5+ messages in thread
* [PATCH 0/2] revamped HMARK extension
@ 2012-07-10 23:17 pablo
  2012-07-10 23:17 ` [PATCH 2/2] extensions: add HMARK target pablo
  0 siblings, 1 reply; 5+ messages in thread
From: pablo @ 2012-07-10 23:17 UTC (permalink / raw)
  To: netfilter-devel; +Cc: Hans Schillstrom

From: Pablo Neira Ayuso <pablo@netfilter.org>

Hi Hans,

I'm taking over your initial HMARK extension for iptables and took the freedom
to revamp it.

It now provides a shortcut for easy configuration:

iptables -I PREROUTING -t mangle -j HMARK \
	--hmark-tuple src,dst,proto \
	--hmark-mod 2 \
	--hmark-rnd 0xfeedcafe

Where --hmark-tuple can be src,dst,proto,sport,dport,spi,ct

Of course, you cannot set spi and sport/dport at the same time and ct must be
used all alone.

You can still use the advanced options for fine tweaking --hmark-*-prefix
and --hmark-*-mask.

I also needed to add some new functions to libxtables to obtain the network
prefix a.k.a CIDR notation. Also reworked xtables_ip[6]mask_to_numeric.
Frankly, I think they now look better from the string handling perspective.

Note that the --hmark-rnd and --hmark-mod are mandatory. Specifically, I don't
want any assumption on --hmark-rnd, users are lazy, they don't set what is not
mandatory (and I believe this parameter is important).

Please, test and report any issue with this asap. I'd like to integrate this
into iptables' master branch by when 3.5 is out so people upgrading to that
kernel can enjoy it.

I'm respecting your authorship in the HMARK extension, as you started this
code.

You can also find these two patches in the hmark branch of the iptables git tree.

Hans Schillstrom (1):
  extensions: add HMARK target

Pablo Neira Ayuso (1):
  libxtables: add xtables_ip[6]mask_to_cidr

 extensions/libxt_HMARK.c           |  441 ++++++++++++++++++++++++++++++++++++
 extensions/libxt_HMARK.man         |   60 +++++
 include/linux/netfilter/xt_HMARK.h |   50 ++++
 include/xtables.h.in               |    2 +
 libxtables/xtables.c               |   33 ++-
 5 files changed, 577 insertions(+), 9 deletions(-)
 create mode 100644 extensions/libxt_HMARK.c
 create mode 100644 extensions/libxt_HMARK.man
 create mode 100644 include/linux/netfilter/xt_HMARK.h

-- 
1.7.10


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2012-07-16 12:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-07-12  7:34 [PATCH 2/2] extensions: add HMARK target Hans Schillstrom
2012-07-12 15:29 ` Pablo Neira Ayuso
  -- strict thread matches above, loose matches on Subject: below --
2012-07-14 22:53 Re[2]: " Hans Schillstrom
2012-07-16 12:22 ` Pablo Neira Ayuso
2012-07-12  7:29 Hans Schillstrom
2012-07-10 23:17 [PATCH 0/2] revamped HMARK extension pablo
2012-07-10 23:17 ` [PATCH 2/2] extensions: add HMARK target pablo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).