netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC IPTABLES 3/4]: add xt_RATEEST target
@ 2007-11-25 17:11 Patrick McHardy
  2007-11-25 17:34 ` Jan Engelhardt
  0 siblings, 1 reply; 3+ messages in thread
From: Patrick McHardy @ 2007-11-25 17:11 UTC (permalink / raw)
  To: Netfilter Development Mailinglist

[-- Attachment #1: Type: text/plain, Size: 0 bytes --]



[-- Attachment #2: 03-libxt_RATEEST.diff --]
[-- Type: text/x-patch, Size: 8488 bytes --]

[IPTABLES]: add xt_RATEEST target

Signed-off-by: Patrick McHardy <kaber@trash.net>
Index: include/linux/netfilter/xt_RATEEST.h
===================================================================
--- include/linux/netfilter/xt_RATEEST.h	(Revision 0)
+++ include/linux/netfilter/xt_RATEEST.h	(Revision 0)
@@ -0,0 +1,11 @@
+#ifndef _XT_RATEEST_TARGET_H
+#define _XT_RATEEST_TARGET_H
+
+struct xt_rateest_target_info {
+	char			name[IFNAMSIZ];
+	signed char		interval;
+	unsigned char		ewma_log;
+	struct xt_rateest	*est __attribute__((aligned(8)));
+};
+
+#endif /* _XT_RATEEST_TARGET_H */
Index: extensions/libxt_RATEEST.c
===================================================================
--- extensions/libxt_RATEEST.c	(Revision 0)
+++ extensions/libxt_RATEEST.c	(Revision 0)
@@ -0,0 +1,240 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stddef.h>
+#include <getopt.h>
+#include <math.h>
+
+#include <xtables.h>
+#include <linux/netfilter/x_tables.h>
+#include <linux/netfilter/xt_RATEEST.h>
+
+/* hack to pass raw values to final_check */
+static struct xt_rateest_target_info *RATEEST_info;
+static unsigned int interval;
+static unsigned int ewma_log;
+
+static void
+RATEEST_help(void)
+{
+	printf(
+"RATEST target v%s options:\n"
+"  --rateest-name name		Rate estimator name\n"
+"  --rateest-interval sec	Rate measurement interval in seconds\n"
+"  --rateest-ewmalog value	Rate measurement averaging time constant\n"
+"\n",
+	       IPTABLES_VERSION);
+}
+
+enum RATEEST_options {
+	RATEEST_OPT_NAME,
+	RATEEST_OPT_INTERVAL,
+	RATEEST_OPT_EWMALOG,
+};
+
+static const struct option RATEEST_opts[] = {
+	{ "rateest-name",	1, NULL, RATEEST_OPT_NAME },
+	{ "rateest-interval",	1, NULL, RATEEST_OPT_INTERVAL },
+	{ "rateest-ewmalog",	1, NULL, RATEEST_OPT_EWMALOG },
+	{ },
+};
+
+/* Copied from iproute */
+#define TIME_UNITS_PER_SEC	1000000
+
+static int
+RATEEST_get_time(unsigned int *time, const char *str)
+{
+	double t;
+	char *p;
+
+	t = strtod(str, &p);
+	if (p == str)
+		return -1;
+
+	if (*p) {
+		if (strcasecmp(p, "s") == 0 || strcasecmp(p, "sec")==0 ||
+		    strcasecmp(p, "secs")==0)
+			t *= TIME_UNITS_PER_SEC;
+		else if (strcasecmp(p, "ms") == 0 || strcasecmp(p, "msec")==0 ||
+			 strcasecmp(p, "msecs") == 0)
+			t *= TIME_UNITS_PER_SEC/1000;
+		else if (strcasecmp(p, "us") == 0 || strcasecmp(p, "usec")==0 ||
+			 strcasecmp(p, "usecs") == 0)
+			t *= TIME_UNITS_PER_SEC/1000000;
+		else
+			return -1;
+	}
+
+	*time = t;
+	return 0;
+}
+
+static void
+RATEEST_print_time(unsigned int time)
+{
+	double tmp = time;
+
+	if (tmp >= TIME_UNITS_PER_SEC)
+		printf("%.1fs ", tmp/TIME_UNITS_PER_SEC);
+	else if (tmp >= TIME_UNITS_PER_SEC/1000)
+		printf("%.1fms ", tmp/(TIME_UNITS_PER_SEC/1000));
+	else
+		printf("%uus ", time);
+}
+
+static void
+RATEEST_init(struct xt_entry_target *target)
+{
+	interval = 0;
+	ewma_log = 0;
+}
+
+static int
+RATEEST_parse(int c, char **argv, int invert, unsigned int *flags,
+	      const void *entry, struct xt_entry_target **target)
+{
+	struct xt_rateest_target_info *info = (void *)(*target)->data;
+
+	RATEEST_info = info;
+
+	switch (c) {
+	case RATEEST_OPT_NAME:
+		if (*flags & (1 << c))
+			exit_error(PARAMETER_PROBLEM,
+				   "RATEEST: can't specify --rateest-name twice");
+		*flags |= 1 << c;
+
+		strncpy(info->name, optarg, sizeof(info->name) - 1);
+		break;
+
+	case RATEEST_OPT_INTERVAL:
+		if (*flags & (1 << c))
+			exit_error(PARAMETER_PROBLEM,
+				   "RATEEST: can't specify --rateest-interval twice");
+		*flags |= 1 << c;
+
+		if (RATEEST_get_time(&interval, optarg) < 0)
+			exit_error(PARAMETER_PROBLEM,
+				   "RATEEST: bad interval value `%s'", optarg);
+
+		break;
+
+	case RATEEST_OPT_EWMALOG:
+		if (*flags & (1 << c))
+			exit_error(PARAMETER_PROBLEM,
+				   "RATEEST: can't specify --rateest-ewmalog twice");
+		*flags |= 1 << c;
+
+		if (RATEEST_get_time(&ewma_log, optarg) < 0)
+			exit_error(PARAMETER_PROBLEM,
+				   "RATEEST: bad ewmalog value `%s'", optarg);
+
+		break;
+
+	default:
+		return 0;
+	}
+
+	return 1;
+}
+
+static void
+RATEEST_final_check(unsigned int flags)
+{
+	struct xt_rateest_target_info *info = RATEEST_info;
+
+	if (!(flags & (1 << RATEEST_OPT_NAME)))
+		exit_error(PARAMETER_PROBLEM, "RATEEST: no name specified");
+	if (!(flags & (1 << RATEEST_OPT_INTERVAL)))
+		exit_error(PARAMETER_PROBLEM, "RATEEST: no interval specified");
+	if (!(flags & (1 << RATEEST_OPT_EWMALOG)))
+		exit_error(PARAMETER_PROBLEM, "RATEEST: no ewmalog specified");
+
+	for (info->interval = 0; info->interval <= 5; info->interval++) {
+		if (interval <= (1 << info->interval) * (TIME_UNITS_PER_SEC / 4))
+			break;
+	}
+
+	if (info->interval > 5)
+		exit_error(PARAMETER_PROBLEM,
+			   "RATEEST: interval value is too large");
+	info->interval -= 2;
+
+	for (info->ewma_log = 1; info->ewma_log < 32; info->ewma_log++) {
+		double w = 1.0 - 1.0 / (1 << info->ewma_log);
+		if (interval / (-log(w)) > ewma_log)
+			break;
+	}
+	info->ewma_log--;
+
+	if (info->ewma_log == 0 || info->ewma_log >= 31)
+		exit_error(PARAMETER_PROBLEM,
+			   "RATEEST: ewmalog value is out of range");
+}
+
+static void
+__RATEEST_print(const struct xt_entry_target *target, const char *prefix)
+{
+	struct xt_rateest_target_info *info = (void *)target->data;
+	unsigned int interval;
+	unsigned int ewma_log;
+
+	interval = (TIME_UNITS_PER_SEC << (info->interval + 2)) / 4;
+	ewma_log = interval * (1 << (info->ewma_log));
+
+	printf("%sname %s ", prefix, info->name);
+	printf("%sinterval ", prefix);
+	RATEEST_print_time(interval);
+	printf("%sewmalog ", prefix);
+	RATEEST_print_time(ewma_log);
+}
+
+static void
+RATEEST_print(const void *ip, const struct xt_entry_target *target,
+	      int numeric)
+{
+	__RATEEST_print(target, "");
+}
+
+static void
+RATEEST_save(const void *ip, const struct xt_entry_target *target)
+{
+	__RATEEST_print(target, "--rateest-");
+}
+
+static struct xtables_target rateest_target4 = {
+	.family		= AF_INET,
+	.name		= "RATEEST",
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_rateest_target_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_rateest_target_info)),
+	.help		= RATEEST_help,
+	.init		= RATEEST_init,
+	.parse		= RATEEST_parse,
+	.final_check	= RATEEST_final_check,
+	.print		= RATEEST_print,
+	.save		= RATEEST_save,
+	.extra_opts	= RATEEST_opts,
+};
+
+static struct xtables_target rateest_target6 = {
+	.family		= AF_INET6,
+	.name		= "RATEEST",
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_rateest_target_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_rateest_target_info)),
+	.help		= RATEEST_help,
+	.init		= RATEEST_init,
+	.parse		= RATEEST_parse,
+	.final_check	= RATEEST_final_check,
+	.print		= RATEEST_print,
+	.save		= RATEEST_save,
+	.extra_opts	= RATEEST_opts,
+};
+
+void _init(void)
+{
+	xtables_register_target(&rateest_target4);
+	xtables_register_target(&rateest_target6);
+}
Index: extensions/Makefile
===================================================================
--- extensions/Makefile	(Revision 7083)
+++ extensions/Makefile	(Arbeitskopie)
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK RATEEST TCPMSS TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
Index: Makefile
===================================================================
--- Makefile	(Revision 7083)
+++ Makefile	(Arbeitskopie)
@@ -80,7 +80,7 @@
 STATIC_LIBS  =
 STATIC6_LIBS =
 LDFLAGS      = -rdynamic
-LDLIBS       = -ldl
+LDLIBS       = -ldl -lm
 ifeq ($(DO_SELINUX), 1)
 LDLIBS       += -lselinux
 endif
@@ -89,7 +89,7 @@
 STATIC_LIBS  = extensions/libext.a
 STATIC6_LIBS = extensions/libext6.a
 LDFLAGS      = -static
-LDLIBS	     =
+LDLIBS	     = -lm
 ifeq ($(DO_SELINUX), 1)
 LDLIBS       += -lselinux
 endif

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

* Re: [RFC IPTABLES 3/4]: add xt_RATEEST target
  2007-11-25 17:11 [RFC IPTABLES 3/4]: add xt_RATEEST target Patrick McHardy
@ 2007-11-25 17:34 ` Jan Engelhardt
  2007-11-25 17:37   ` Patrick McHardy
  0 siblings, 1 reply; 3+ messages in thread
From: Jan Engelhardt @ 2007-11-25 17:34 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Netfilter Development Mailinglist

On Nov 25 2007 18:11, Patrick McHardy wrote:

>Date: Sun, 25 Nov 2007 18:11:55 +0100
>From: Patrick McHardy <kaber@trash.net>
>To: Netfilter Development Mailinglist <netfilter-devel@vger.kernel.org>
>Subject: [RFC IPTABLES 3/4]: add xt_RATEEST target
>
>
>

>[IPTABLES]: add xt_RATEEST target
>
>Signed-off-by: Patrick McHardy <kaber@trash.net>
>Index: include/linux/netfilter/xt_RATEEST.h
>===================================================================
>--- include/linux/netfilter/xt_RATEEST.h	(Revision 0)
>+++ include/linux/netfilter/xt_RATEEST.h	(Revision 0)
>@@ -0,0 +1,11 @@
>+#ifndef _XT_RATEEST_TARGET_H
>+#define _XT_RATEEST_TARGET_H
>+
>+struct xt_rateest_target_info {
>+	char			name[IFNAMSIZ];
>+	signed char		interval;
>+	unsigned char		ewma_log;

int8/uint8

>+	struct xt_rateest	*est __attribute__((aligned(8)));
>+};
>+
>+#endif /* _XT_RATEEST_TARGET_H */
>Index: extensions/libxt_RATEEST.c
>===================================================================
>--- extensions/libxt_RATEEST.c	(Revision 0)
>+++ extensions/libxt_RATEEST.c	(Revision 0)
>@@ -0,0 +1,240 @@
>+static unsigned int interval;
>+static unsigned int ewma_log;

>+static void
>+RATEEST_final_check(unsigned int flags)
>+{
>+	struct xt_rateest_target_info *info = RATEEST_info;
>+
>+	if (!(flags & (1 << RATEEST_OPT_NAME)))
>+		exit_error(PARAMETER_PROBLEM, "RATEEST: no name specified");
>+	if (!(flags & (1 << RATEEST_OPT_INTERVAL)))
>+		exit_error(PARAMETER_PROBLEM, "RATEEST: no interval specified");
>+	if (!(flags & (1 << RATEEST_OPT_EWMALOG)))
>+		exit_error(PARAMETER_PROBLEM, "RATEEST: no ewmalog specified");
>+
>+	for (info->interval = 0; info->interval <= 5; info->interval++) {
>+		if (interval <= (1 << info->interval) * (TIME_UNITS_PER_SEC / 4))
>+			break;
>+	}

-{}

>+static void
>+__RATEEST_print(const struct xt_entry_target *target, const char *prefix)
>+{
>+	struct xt_rateest_target_info *info = (void *)target->data;
>+	unsigned int interval;
>+	unsigned int ewma_log;

Ouchie - that throws a warning with -Wshadow (which is what I'm trying to slip
in later).

>+
>+	interval = (TIME_UNITS_PER_SEC << (info->interval + 2)) / 4;
>+	ewma_log = interval * (1 << (info->ewma_log));

ewma_log = interval << info->ewma_log;

>+	printf("%sname %s ", prefix, info->name);
>+	printf("%sinterval ", prefix);
>+	RATEEST_print_time(interval);
>+	printf("%sewmalog ", prefix);
>+	RATEEST_print_time(ewma_log);
>+}
>+


>-LDLIBS       = -ldl
>+LDLIBS       = -ldl -lm

I have not seen the function that requires -lm, which was it?


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

* Re: [RFC IPTABLES 3/4]: add xt_RATEEST target
  2007-11-25 17:34 ` Jan Engelhardt
@ 2007-11-25 17:37   ` Patrick McHardy
  0 siblings, 0 replies; 3+ messages in thread
From: Patrick McHardy @ 2007-11-25 17:37 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Netfilter Development Mailinglist

Jan Engelhardt wrote:
> On Nov 25 2007 18:11, Patrick McHardy wrote:
> 
>> +static void
>> +RATEEST_final_check(unsigned int flags)
>> +{
>> +	...
>> +	for (info->interval = 0; info->interval <= 5; info->interval++) {
>> +		if (interval <= (1 << info->interval) * (TIME_UNITS_PER_SEC / 4))
>> +			break;
>> +	}
> 
> -{}

For multiple statements they're fine.

>> +static void
>> +__RATEEST_print(const struct xt_entry_target *target, const char *prefix)
>> +{
>> +	struct xt_rateest_target_info *info = (void *)target->data;
>> +	unsigned int interval;
>> +	unsigned int ewma_log;
> 
> Ouchie - that throws a warning with -Wshadow (which is what I'm trying to slip
> in later).

Will rename.

>> +
>> +	interval = (TIME_UNITS_PER_SEC << (info->interval + 2)) / 4;
>> +	ewma_log = interval * (1 << (info->ewma_log));
> 
> ewma_log = interval << info->ewma_log;

OK.

> 
>> +	printf("%sname %s ", prefix, info->name);
>> +	printf("%sinterval ", prefix);
>> +	RATEEST_print_time(interval);
>> +	printf("%sewmalog ", prefix);
>> +	RATEEST_print_time(ewma_log);
>> +}
>> +
> 
> 
>> -LDLIBS       = -ldl
>> +LDLIBS       = -ldl -lm
> 
> I have not seen the function that requires -lm, which was it?

log():

+		if (interval / (-log(w)) > ewma_log)

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

end of thread, other threads:[~2007-11-25 17:38 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-11-25 17:11 [RFC IPTABLES 3/4]: add xt_RATEEST target Patrick McHardy
2007-11-25 17:34 ` Jan Engelhardt
2007-11-25 17:37   ` Patrick McHardy

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).