All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH,RFC] Route match
@ 2008-07-03  0:39 Phil Oester
  2008-07-03  7:18 ` Jan Engelhardt
                   ` (2 more replies)
  0 siblings, 3 replies; 27+ messages in thread
From: Phil Oester @ 2008-07-03  0:39 UTC (permalink / raw)
  To: netfilter-devel

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

Attached is a new "route" match, which matches against entries
in the kernel routing table.  I've had a need for this functionality
for quite some time, and finally decided to code it up.  

TODO: add IPv6 support to kernel side

Options

[!] --route-src-exists      Route for src exists
    --route-src-eq value    Route for src exists with prefix-length == value
    --route-src-gt value    Route for src exists with prefix-length  > value
    --route-src-lt value    Route for src exists with prefix-length  < value
[!] --route-dst-exists      Route for dst exists
    --route-dst-eq value    Route for dst exists with prefix-length == value
    --route-dst-gt value    Route for dst exists with prefix-length  > value
    --route-dst-lt value    Route for dst exists with prefix-length  < value

Examples:

	Egress filtering:
		iptables -A FORWARD -m route ! --route-src-exists -j DROP

	Ingress filtering:
		iptables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP

	Allow a user to only browse internal websites:
		iptables -A FORWARD -p tcp --dport 80 -m route --route-dst-exists -j ACCEPT

	Allow an SNMP collector to reach all internal routers (/30 or /32 interfaces)
		iptables -A FORWARD -p udp --dport 161 -m route --route-dst-gt 29 -j ACCEPT


Please let me know if anyone else finds this match useful.

Phil

[-- Attachment #2: patch-route-kernel --]
[-- Type: text/plain, Size: 6206 bytes --]

diff --git a/include/linux/netfilter/xt_route.h b/include/linux/netfilter/xt_route.h
new file mode 100644
index 0000000..0c90494
--- /dev/null
+++ b/include/linux/netfilter/xt_route.h
@@ -0,0 +1,21 @@
+#ifndef _XT_ROUTE_H
+#define _XT_ROUTE_H
+
+enum {
+	XT_ROUTE_SRC_EXISTS = 0,
+	XT_ROUTE_SRC_EQ,
+	XT_ROUTE_SRC_GT,
+	XT_ROUTE_SRC_LT,
+	XT_ROUTE_DST_EXISTS,
+	XT_ROUTE_DST_EQ,
+	XT_ROUTE_DST_GT,
+	XT_ROUTE_DST_LT,
+};
+
+struct xt_route_info {
+	u_int8_t	invert;
+	u_int8_t	mode;
+	u_int8_t	prefixlen;
+};
+
+#endif /*_XT_ROUTE_H*/
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 0d4d728..22bbdd5 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -156,6 +156,8 @@ void free_fib_info(struct fib_info *fi)
 	kfree(fi);
 }
 
+EXPORT_SYMBOL_GPL(free_fib_info);
+
 void fib_release_info(struct fib_info *fi)
 {
 	spin_lock_bh(&fib_info_lock);
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index aa8d80c..128b186 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -724,6 +724,16 @@ config NETFILTER_XT_MATCH_REALM
 	  If you want to compile it as a module, say M here and read
 	  <file:Documentation/kbuild/modules.txt>.  If unsure, say `N'.
 
+config NETFILTER_XT_MATCH_ROUTE
+	tristate '"route" match support'
+	depends on NETFILTER_XTABLES
+	depends on NETFILTER_ADVANCED
+	help
+	  This option adds a `route' match, which allows you to match on
+	  the kernel routing table.  
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_SCTP
 	tristate  '"sctp" protocol match support (EXPERIMENTAL)'
 	depends on NETFILTER_XTABLES && EXPERIMENTAL
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 5c4b183..1035372 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -76,6 +76,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_RATEEST) += xt_rateest.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_ROUTE) += xt_route.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_STATISTIC) += xt_statistic.o
diff --git a/net/netfilter/xt_route.c b/net/netfilter/xt_route.c
new file mode 100644
index 0000000..c6e9f94
--- /dev/null
+++ b/net/netfilter/xt_route.c
@@ -0,0 +1,141 @@
+/* Kernel module to match against the kernel routing table. */
+/* (C) 2008 Phil Oester <kernel@linuxace.com>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/ipv6.h>
+#include <net/ip.h>
+#include <net/flow.h>
+#include <net/ip_fib.h>
+
+#include <linux/netfilter/xt_route.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_AUTHOR("Phil Oester <kernel@linuxace.com>");
+MODULE_DESCRIPTION("Xtables: Routing table match");
+MODULE_LICENSE("GPL");
+
+static bool
+route_mt(const struct sk_buff *skb, const struct net_device *in,
+          const struct net_device *out, const struct xt_match *match,
+          const void *matchinfo, int offset, unsigned int protoff,
+          bool *hotdrop)
+{
+	const struct xt_route_info *info = matchinfo;
+	const struct iphdr *iph = ip_hdr(skb);
+	struct fib_result res = {0};
+	struct flowi fl = {0};
+	int ret;
+
+	switch (info->mode) {
+	case XT_ROUTE_SRC_EXISTS:
+		fl.nl_u.ip4_u.daddr = iph->saddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen != 0) {
+			fib_res_put(&res);
+			return true ^ info->invert;
+		}
+	case XT_ROUTE_SRC_EQ:
+		fl.nl_u.ip4_u.daddr = iph->saddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen == info->prefixlen) {
+			fib_res_put(&res);
+			return true;
+		}
+		break;
+	case XT_ROUTE_SRC_GT:
+		fl.nl_u.ip4_u.daddr = iph->saddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen > info->prefixlen) {
+			fib_res_put(&res);
+			return true;
+		}
+		break;
+	case XT_ROUTE_SRC_LT:
+		fl.nl_u.ip4_u.daddr = iph->saddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen < info->prefixlen) {
+			fib_res_put(&res);
+			return true;
+		}
+		break;
+	case XT_ROUTE_DST_EXISTS:
+		fl.nl_u.ip4_u.daddr = iph->daddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen != 0) {
+			fib_res_put(&res);
+			return true ^ info->invert;
+		}
+		break;
+	case XT_ROUTE_DST_EQ:
+		fl.nl_u.ip4_u.daddr = iph->daddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen == info->prefixlen) {
+			fib_res_put(&res);
+			return true;
+		}
+		break;
+	case XT_ROUTE_DST_GT:
+		fl.nl_u.ip4_u.daddr = iph->daddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen > info->prefixlen) {
+			fib_res_put(&res);
+			return true;
+		}
+		break;
+	case XT_ROUTE_DST_LT:
+		fl.nl_u.ip4_u.daddr = iph->daddr;
+		ret = fib_lookup(dev_net(in), &fl, &res);
+		if (ret == 0 && res.prefixlen < info->prefixlen) {
+			fib_res_put(&res);
+			return true;
+		}
+		break;
+	}
+
+	return false;
+}
+
+static bool
+route_mt6(const struct sk_buff *skb, const struct net_device *in,
+           const struct net_device *out, const struct xt_match *match,
+           const void *matchinfo, int offset, unsigned int protoff,
+           bool *hotdrop)
+{
+	return 1;
+}
+
+static struct xt_match route_mt_reg[] __read_mostly = {
+	{
+		.name		= "route",
+		.family		= AF_INET,
+		.match		= route_mt,
+		.matchsize	= sizeof(struct xt_route_info),
+		.me		= THIS_MODULE,
+	},
+	{
+		.name		= "route",
+		.family		= AF_INET6,
+		.match		= route_mt6,
+		.matchsize	= sizeof(struct xt_route_info),
+		.me		= THIS_MODULE,
+	},
+};
+
+static int __init route_mt_init(void)
+{
+	return xt_register_matches(route_mt_reg, ARRAY_SIZE(route_mt_reg));
+}
+
+static void __exit route_mt_exit(void)
+{
+	xt_unregister_matches(route_mt_reg, ARRAY_SIZE(route_mt_reg));
+}
+
+module_init(route_mt_init);
+module_exit(route_mt_exit);

[-- Attachment #3: patch-route-user --]
[-- Type: text/plain, Size: 10259 bytes --]

diff --git a/extensions/libxt_route.c b/extensions/libxt_route.c
new file mode 100644
index 0000000..a2187cb
--- /dev/null
+++ b/extensions/libxt_route.c
@@ -0,0 +1,371 @@
+/* Shared library add-on to iptables to add route matching support 
+ * (C) 2008 by Phil Oester <kernel@linuxace.com>
+ *
+ * This program is released under the terms of GNU GPL */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <getopt.h>
+#include <iptables.h>
+
+#include <xtables.h>
+#include <linux/netfilter/xt_route.h>
+
+static void route_help(void)
+{
+	printf(
+"route match options:\n"
+"  [!] --route-src-exists	Route for src exists\n"
+"      --route-src-eq value	Route for src exists with prefix-length == value\n"
+"      --route-src-gt value	Route for src exists with prefix-length  > value\n"
+"      --route-src-lt value	Route for src exists with prefix-length  < value\n"
+"  [!] --route-dst-exists	Route for dst exists\n"
+"      --route-dst-eq value	Route for dst exists with prefix-length == value\n"
+"      --route-dst-gt value	Route for dst exists with prefix-length  > value\n"
+"      --route-dst-lt value	Route for dst exists with prefix-length  < value\n");
+}
+
+static const struct option route_opts[] = {
+	{ "route-src-exists", 0, NULL, '1' },
+	{ "route-src-eq", 1, NULL, '2' },
+	{ "route-src-gt", 1, NULL, '3' },
+	{ "route-src-lt", 1, NULL, '4' },
+	{ "route-dst-exists", 0, NULL, '5' },
+	{ "route-dst-eq", 1, NULL, '6' },
+	{ "route-dst-gt", 1, NULL, '7' },
+	{ "route-dst-lt", 1, NULL, '8' },
+	{ .name = NULL }
+};
+
+static int route_parse(int c, char **argv, int invert, unsigned int *flags,
+                       const void *entry, struct xt_entry_match **match)
+{
+	struct xt_route_info *info = (struct xt_route_info *) (*match)->data;
+	unsigned int value;
+
+	check_inverse(optarg, &invert, &optind, 0);
+
+	switch (c) {
+		case '1':
+			if (invert)
+				info->invert = 1;
+
+			info->mode = XT_ROUTE_SRC_EXISTS;			
+			break;
+		case '2':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 1, 32, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 1 and 32");
+
+			info->mode = XT_ROUTE_SRC_EQ;
+			info->value = value;
+			break;
+		case '3':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 0, 31, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 0 and 31");
+
+			info->mode = XT_ROUTE_SRC_GT;
+			info->value = value;
+			break;
+		case '4':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 2, 32, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 2 and 32");
+
+			info->mode = XT_ROUTE_SRC_LT;
+			info->value = value;
+			break;
+		case '5':
+			if (invert)
+				info->invert = 1;
+
+			info->mode = XT_ROUTE_DST_EXISTS;			
+			break;
+		case '6':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 1, 32, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 1 and 32");
+
+			info->mode = XT_ROUTE_DST_EQ;
+			info->value = value;
+			break;
+		case '7':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 0, 31, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 0 and 31");
+
+			info->mode = XT_ROUTE_DST_GT;
+			info->value = value;
+			break;
+		case '8':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 2, 32, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 2 and 32");
+
+			info->mode = XT_ROUTE_DST_LT;
+			info->value = value;
+			break;
+		default:
+			return 0;
+
+	}
+
+	if (*flags) 
+		exit_error(PARAMETER_PROBLEM, 
+				"Can't specify route match twice");
+	*flags = 1;
+
+	return 1;
+}
+
+static int route_parse6(int c, char **argv, int invert, unsigned int *flags,
+                       const void *entry, struct xt_entry_match **match)
+{
+	struct xt_route_info *info = (struct xt_route_info *) (*match)->data;
+	unsigned int value;
+
+	check_inverse(optarg, &invert, &optind, 0);
+
+	switch (c) {
+		case '1':
+			if (invert)
+				info->invert = 1;
+
+			info->mode = XT_ROUTE_SRC_EXISTS;			
+			break;
+		case '2':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 1, 128, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 1 and 128");
+
+			info->mode = XT_ROUTE_SRC_EQ;
+			info->value = value;
+			break;
+		case '3':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 0, 127, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 0 and 127");
+
+			info->mode = XT_ROUTE_SRC_GT;
+			info->value = value;
+			break;
+		case '4':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 2, 128, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 2 and 128");
+
+			info->mode = XT_ROUTE_SRC_LT;
+			info->value = value;
+			break;
+		case '5':
+			if (invert)
+				info->invert = 1;
+
+			info->mode = XT_ROUTE_DST_EXISTS;			
+			break;
+		case '6':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 1, 128, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 1 and 128");
+
+			info->mode = XT_ROUTE_DST_EQ;
+			info->value = value;
+			break;
+		case '7':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 0, 127, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 0 and 127");
+
+			info->mode = XT_ROUTE_DST_GT;
+			info->value = value;
+			break;
+		case '8':
+			if (invert) 
+				exit_error(PARAMETER_PROBLEM,
+						"route: unexpected `!'");
+
+			if (string_to_number(optarg, 2, 128, &value) == -1)
+				exit_error(PARAMETER_PROBLEM,
+				           "route: Expected prefix between 2 and 128");
+
+			info->mode = XT_ROUTE_DST_LT;
+			info->value = value;
+			break;
+		default:
+			return 0;
+
+	}
+
+	if (*flags) 
+		exit_error(PARAMETER_PROBLEM, 
+				"Can't specify route match twice");
+	*flags = 1;
+
+	return 1;
+}
+
+static void route_check(unsigned int flags)
+{
+	if (!flags) 
+		exit_error(PARAMETER_PROBLEM,
+			"Route match: You must specify an option");
+}
+
+static void route_print(const void *ip, const struct xt_entry_match *match,
+                      int numeric)
+{
+	const struct xt_route_info *info = 
+		(struct xt_route_info *) match->data;
+
+	printf("Route: ");
+	switch (info->mode) {
+		case XT_ROUTE_SRC_EXISTS:
+			if (info->invert)
+				printf("! ");
+			printf("Src exists ");
+			break;
+		case XT_ROUTE_SRC_EQ:
+			printf("Src prefix == %u ", info->value);
+			break;
+		case XT_ROUTE_SRC_GT:
+			printf("Src prefix > %u ", info->value);
+			break;
+		case XT_ROUTE_SRC_LT:
+			printf("Src prefix < %u ", info->value);
+			break;
+		case XT_ROUTE_DST_EXISTS:
+			if (info->invert)
+				printf("! ");
+			printf("Dst exists ");
+			break;
+		case XT_ROUTE_DST_EQ:
+			printf("Dst prefix == %u ", info->value);
+			break;
+		case XT_ROUTE_DST_GT:
+			printf("Dst prefix > %u ", info->value);
+			break;
+		case XT_ROUTE_DST_LT:
+			printf("Dst prefix < %u ", info->value);
+			break;
+	}
+}
+
+static void route_save(const void *ip, const struct xt_entry_match *match)
+{
+	const struct xt_route_info *info =
+		(struct xt_route_info *) match->data;
+
+	switch (info->mode) {
+		case XT_ROUTE_SRC_EXISTS:
+			if (info->invert)
+				printf("! ");
+			printf("--route-src-exists ");
+			break;
+		case XT_ROUTE_SRC_EQ:
+			printf("--route-src-eq %u ", info->value);
+			break;
+		case XT_ROUTE_SRC_GT:
+			printf("--route-src-gt %u ", info->value);
+			break;
+		case XT_ROUTE_SRC_LT:
+			printf("--route-src-lt %u ", info->value);
+			break;
+		case XT_ROUTE_DST_EXISTS:
+			if (info->invert)
+				printf("! ");
+			printf("--route-dst-exists ");
+			break;
+		case XT_ROUTE_DST_EQ:
+			printf("--route-dst-eq %u ", info->value);
+			break;
+		case XT_ROUTE_DST_GT:
+			printf("--route-dst-gt < %u ", info->value);
+			break;
+		case XT_ROUTE_DST_LT:
+			printf("--route-dst-lt > %u ", info->value);
+			break;
+		default:
+			break;
+	}
+}
+
+static struct xtables_match route_mt = {
+	.name		= "route",
+	.version	= XTABLES_VERSION,
+	.family		= AF_INET,
+	.size		= XT_ALIGN(sizeof(struct xt_route_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_route_info)),
+	.help		= route_help,
+	.parse		= route_parse,
+	.final_check	= route_check,
+	.print		= route_print,
+	.save		= route_save,
+	.extra_opts	= route_opts,
+};
+
+static struct xtables_match route_mt6 = {
+	.name		= "route",
+	.version	= XTABLES_VERSION,
+	.family		= AF_INET6,
+	.size		= XT_ALIGN(sizeof(struct xt_route_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_route_info)),
+	.help		= route_help,
+	.parse		= route_parse6,
+	.final_check	= route_check,
+	.print		= route_print,
+	.save		= route_save,
+	.extra_opts	= route_opts,
+};
+
+
+void _init(void) 
+{
+	xtables_register_match(&route_mt);
+	xtables_register_match(&route_mt6);
+}
diff --git a/include/linux/netfilter/xt_route.h b/include/linux/netfilter/xt_route.h
new file mode 100644
index 0000000..0c90494
--- /dev/null
+++ b/include/linux/netfilter/xt_route.h
@@ -0,0 +1,21 @@
+#ifndef _XT_ROUTE_H
+#define _XT_ROUTE_H
+
+enum {
+	XT_ROUTE_SRC_EXISTS = 0,
+	XT_ROUTE_SRC_EQ,
+	XT_ROUTE_SRC_GT,
+	XT_ROUTE_SRC_LT,
+	XT_ROUTE_DST_EXISTS,
+	XT_ROUTE_DST_EQ,
+	XT_ROUTE_DST_GT,
+	XT_ROUTE_DST_LT,
+};
+
+struct xt_route_info {
+	u_int8_t	invert;
+	u_int8_t	mode;
+	u_int8_t	prefixlen;
+};
+
+#endif /*_XT_ROUTE_H*/

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

* Re: [PATCH,RFC] Route match
  2008-07-03  0:39 [PATCH,RFC] Route match Phil Oester
@ 2008-07-03  7:18 ` Jan Engelhardt
  2008-07-03  9:50   ` Jozsef Kadlecsik
  2008-07-03  7:22 ` [PATCH,RFC] Route match, kernel Jan Engelhardt
  2008-07-03  7:26 ` [PATCH,RFC] Route match, user Jan Engelhardt
  2 siblings, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03  7:18 UTC (permalink / raw)
  To: Phil Oester; +Cc: netfilter-devel


On Thursday 2008-07-03 02:39, Phil Oester wrote:

>Attached is a new "route" match, which matches against entries
>in the kernel routing table.  I've had a need for this functionality
>for quite some time, and finally decided to code it up.  

There is also the 'realm' match..

ip route replace 10.10.96.0/20 dev sis0 realm 5 src 10.10.106.161
iptables -t mangle -A POSTROUTING -m realm 5 -j dowhateveryouwant

>
>TODO: add IPv6 support to kernel side
>
>Options
>
>[!] --route-src-exists      Route for src exists
>    --route-src-eq value    Route for src exists with prefix-length == value
>    --route-src-gt value    Route for src exists with prefix-length  > value
>    --route-src-lt value    Route for src exists with prefix-length  < value
>[!] --route-dst-exists      Route for dst exists
>    --route-dst-eq value    Route for dst exists with prefix-length == value
>    --route-dst-gt value    Route for dst exists with prefix-length  > value
>    --route-dst-lt value    Route for dst exists with prefix-length  < value
>
>Examples:
>
>	Egress filtering:
>		iptables -A FORWARD -m route ! --route-src-exists -j DROP

That's what rp_filter is for.

>	Ingress filtering:
>		iptables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP

rp_filter again.

>	Allow a user to only browse internal websites:
>		iptables -A FORWARD -p tcp --dport 80 -m route --route-dst-exists -j ACCEPT

If there was no fitting dst route, the packet would never get to FORWARD in
the first place.

>	Allow an SNMP collector to reach all internal routers (/30 or /32 interfaces)
>		iptables -A FORWARD -p udp --dport 161 -m route --route-dst-gt 29 -j ACCEPT

And this could be modeled with -s xxx/30 -d xxx/30 maybe.

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

* Re: [PATCH,RFC] Route match, kernel
  2008-07-03  0:39 [PATCH,RFC] Route match Phil Oester
  2008-07-03  7:18 ` Jan Engelhardt
@ 2008-07-03  7:22 ` Jan Engelhardt
  2008-07-03 16:27   ` Phil Oester
  2008-07-03  7:26 ` [PATCH,RFC] Route match, user Jan Engelhardt
  2 siblings, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03  7:22 UTC (permalink / raw)
  To: Phil Oester; +Cc: netfilter-devel


>+	case XT_ROUTE_SRC_EXISTS:
>+		fl.nl_u.ip4_u.daddr = iph->saddr;
>+		ret = fib_lookup(dev_net(in), &fl, &res);
>+		if (ret == 0 && res.prefixlen != 0) {
>+			fib_res_put(&res);
>+			return true ^ info->invert;
>+		}
>+	case XT_ROUTE_SRC_EQ:
>+		fl.nl_u.ip4_u.daddr = iph->saddr;
>+		ret = fib_lookup(dev_net(in), &fl, &res);
>+		if (ret == 0 && res.prefixlen == info->prefixlen) {
>+			fib_res_put(&res);
>+			return true;
>+		}
>+		break;

Should not these be true ^ info->invert too?

I would probably combine mode and invert, to save a byte.

>+static bool
>+route_mt6(const struct sk_buff *skb, const struct net_device *in,
>+           const struct net_device *out, const struct xt_match *match,
>+           const void *matchinfo, int offset, unsigned int protoff,
>+           bool *hotdrop)
>+{
>+	return 1;
>+}

If you do not support IPv6, do not write a function for it ;-)

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

* Re: [PATCH,RFC] Route match, user
  2008-07-03  0:39 [PATCH,RFC] Route match Phil Oester
  2008-07-03  7:18 ` Jan Engelhardt
  2008-07-03  7:22 ` [PATCH,RFC] Route match, kernel Jan Engelhardt
@ 2008-07-03  7:26 ` Jan Engelhardt
  2008-07-03 16:29   ` Phil Oester
  2 siblings, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03  7:26 UTC (permalink / raw)
  To: Phil Oester; +Cc: netfilter-devel


>+static const struct option route_opts[] = {
>+	{ "route-src-exists", 0, NULL, '1' },
>+	{ "route-src-eq", 1, NULL, '2' },
>+	{ "route-src-gt", 1, NULL, '3' },
>+	{ "route-src-lt", 1, NULL, '4' },
>+	{ "route-dst-exists", 0, NULL, '5' },
>+	{ "route-dst-eq", 1, NULL, '6' },
>+	{ "route-dst-gt", 1, NULL, '7' },
>+	{ "route-dst-lt", 1, NULL, '8' },
>+	{ .name = NULL }
>+};

You are mixing non-C99 and C99 style.

>+static int route_parse(int c, char **argv, int invert, unsigned int *flags,
>+                       const void *entry, struct xt_entry_match **match)
>+{
>+	struct xt_route_info *info = (struct xt_route_info *) (*match)->data;
>+	unsigned int value;
>+
>+	check_inverse(optarg, &invert, &optind, 0);

I would not bother supporting intraplaced ! at all. Just remove that line.

>+		case '6':
>+			if (invert) 
>+				exit_error(PARAMETER_PROBLEM,
>+						"route: unexpected `!'");
>+
>+			if (string_to_number(optarg, 1, 128, &value) == -1)
>+				exit_error(PARAMETER_PROBLEM,
>+				           "route: Expected prefix between 1 and 128");
>+
>+			info->mode = XT_ROUTE_DST_EQ;
>+			info->value = value;
>+			break;

There is a lot of code to unify between route_mt_parse and route_mt6_parse.

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

* Re: [PATCH,RFC] Route match
  2008-07-03  7:18 ` Jan Engelhardt
@ 2008-07-03  9:50   ` Jozsef Kadlecsik
  2008-07-03 11:22     ` Jan Engelhardt
  2008-07-03 18:53     ` Patrick McHardy
  0 siblings, 2 replies; 27+ messages in thread
From: Jozsef Kadlecsik @ 2008-07-03  9:50 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Phil Oester, netfilter-devel

On Thu, 3 Jul 2008, Jan Engelhardt wrote:

> >
> >TODO: add IPv6 support to kernel side
> >
> >Examples:
> >
> >	Egress filtering:
> >		iptables -A FORWARD -m route ! --route-src-exists -j DROP
> 
> That's what rp_filter is for.
> 
> >	Ingress filtering:
> >		iptables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP
> 
> rp_filter again.

Quick and not good examples, I'd say. The main problem with rp_filter is 
that it drops the packets >silently<. The real benefit of such a match is 
the possibility to log (and drop) faked packets. If the patch had IPv6 
support, one could add that additionally (as far as I know) there's no 
rp_filter for IPv6 at all.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH,RFC] Route match
  2008-07-03  9:50   ` Jozsef Kadlecsik
@ 2008-07-03 11:22     ` Jan Engelhardt
  2008-07-03 12:39       ` Jozsef Kadlecsik
                         ` (2 more replies)
  2008-07-03 18:53     ` Patrick McHardy
  1 sibling, 3 replies; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 11:22 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: Phil Oester, netfilter-devel


On Thursday 2008-07-03 11:50, Jozsef Kadlecsik wrote:
>> 
>> >	Ingress filtering:
>> >		iptables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP
>> 
>> rp_filter again.
>
>Quick and not good examples, I'd say. The main problem with rp_filter is 
>that it drops the packets >silently<. The real benefit of such a match is 
>the possibility to log (and drop) faked packets. If the patch had IPv6 
>support, one could add that additionally (as far as I know) there's no 
>rp_filter for IPv6 at all.

You know what's been bugging me... why don't we replace the entire
routing infrastructure by an xtables "route" table, with something like

# rp_filter
iptables -t route -A ROUTING -m route ! --route-src-exists -j DROP

# policy routing
iptables -t route -A ROUTING -m statistic --mode nth --every 2
-j ROUTE --dev eth0

# ipsec (vaguely)
iptables -t route -A OUTPUT -s 192.168.1.0/24 -d 192.168.2.0/24
-j IPSEC --mode tunnel --right-side 82.83.84.85

That would get rid of the tons of different-kind tables (xt tables,
routing tables, routing rules, xfrm policy and xfrm subs) and
put it into one thing people understand reasonably well.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 11:22     ` Jan Engelhardt
@ 2008-07-03 12:39       ` Jozsef Kadlecsik
  2008-07-03 13:13         ` Jan Engelhardt
  2008-07-03 15:51       ` Krzysztof Oledzki
  2008-07-04 15:15       ` Henrik Nordstrom
  2 siblings, 1 reply; 27+ messages in thread
From: Jozsef Kadlecsik @ 2008-07-03 12:39 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Phil Oester, netfilter-devel

On Thu, 3 Jul 2008, Jan Engelhardt wrote:

> You know what's been bugging me... why don't we replace the entire
> routing infrastructure by an xtables "route" table, with something like
> 
> # rp_filter
> iptables -t route -A ROUTING -m route ! --route-src-exists -j DROP
> 
> # policy routing
> iptables -t route -A ROUTING -m statistic --mode nth --every 2
> -j ROUTE --dev eth0
> 
> # ipsec (vaguely)
> iptables -t route -A OUTPUT -s 192.168.1.0/24 -d 192.168.2.0/24
> -j IPSEC --mode tunnel --right-side 82.83.84.85
> 
> That would get rid of the tons of different-kind tables (xt tables,
> routing tables, routing rules, xfrm policy and xfrm subs) and
> put it into one thing people understand reasonably well.

The nf-hipac people also suggested it long time ago.

One can find a lot of smaller and bigger missing pieces, like a new table, 
new hook, if we'd associate a 'routing table' to a 'chain in the iptables 
route table', then we'd need a default policy support (i.e. default route) 
for the user defined chains too, etc.

If iptables were converted to netlink, that'd be a huge step toward such a 
goal.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH,RFC] Route match
  2008-07-03 12:39       ` Jozsef Kadlecsik
@ 2008-07-03 13:13         ` Jan Engelhardt
  2008-07-03 13:31           ` Jozsef Kadlecsik
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 13:13 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: Phil Oester, netfilter-devel


On Thursday 2008-07-03 14:39, Jozsef Kadlecsik wrote:
>
>One can find a lot of smaller and bigger missing pieces, like a new table, 
>new hook, if we'd associate a 'routing table' to a 'chain in the iptables 
>route table', then we'd need a default policy support (i.e. default route) 
>for the user defined chains too, etc.

User-defined chains always have an implicit policy of 'RETURN',
and I would not turn a knob on that property anytime.
The default policy for the main chain is of course 'UNREACHABLE'.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 13:13         ` Jan Engelhardt
@ 2008-07-03 13:31           ` Jozsef Kadlecsik
  2008-07-03 14:15             ` Jan Engelhardt
  0 siblings, 1 reply; 27+ messages in thread
From: Jozsef Kadlecsik @ 2008-07-03 13:31 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Phil Oester, netfilter-devel

On Thu, 3 Jul 2008, Jan Engelhardt wrote:

> On Thursday 2008-07-03 14:39, Jozsef Kadlecsik wrote:
> >
> >One can find a lot of smaller and bigger missing pieces, like a new table, 
> >new hook, if we'd associate a 'routing table' to a 'chain in the iptables 
> >route table', then we'd need a default policy support (i.e. default route) 
> >for the user defined chains too, etc.
> 
> User-defined chains always have an implicit policy of 'RETURN',
> and I would not turn a knob on that property anytime.

Routing cannot be replaced by netfilter 'route' table without supporting a 
'default policy' (as default route) in the user defined chains (as routing 
tables).

> The default policy for the main chain is of course 'UNREACHABLE'.

Hm, I don't understand you: if we want to replace routing with a 'route'
table, then the default policy (i.e. the default route) cannot be 
'UNREACHABLE'.

Unless you intend to define the 'default route' as the last rule in any 
chain...

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH,RFC] Route match
  2008-07-03 13:31           ` Jozsef Kadlecsik
@ 2008-07-03 14:15             ` Jan Engelhardt
  2008-07-03 22:02               ` Jozsef Kadlecsik
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 14:15 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: Phil Oester, netfilter-devel


On Thursday 2008-07-03 15:31, Jozsef Kadlecsik wrote:
>On Thu, 3 Jul 2008, Jan Engelhardt wrote:
>> On Thursday 2008-07-03 14:39, Jozsef Kadlecsik wrote:
>> >
>> >One can find a lot of smaller and bigger missing pieces, like a new table, 
>> >new hook, if we'd associate a 'routing table' to a 'chain in the iptables 
>> >route table', then we'd need a default policy support (i.e. default route) 
>> >for the user defined chains too, etc.
>> 
>> User-defined chains always have an implicit policy of 'RETURN',
>> and I would not turn a knob on that property anytime.
>
>Routing cannot be replaced by netfilter 'route' table without supporting a 
>'default policy' (as default route) in the user defined chains (as routing 
>tables).

User-defines chains return to the main chain once control runs off their end.
Since the main chain has a default policy, I do not see aproblem.

>> The default policy for the main chain is of course 'UNREACHABLE'.
>
>Hm, I don't understand you: if we want to replace routing with a 'route'
>table, then the default policy (i.e. the default route) cannot be 
>'UNREACHABLE'.

It can (well, we'd have to make UNREACHABLE an acceptable
default policy). This is what routing does today. For example:


$ ip r g 2001::1
unreachable 2001::1 from :: dev lo  table unspec  proto none  src ::1  metric
-1  error -101 hoplimit 255


>Unless you intend to define the 'default route' as the last rule in any 
>chain...

No, default route would be

	iptables -t route -A ROUTING <no further conditions> -j ROUTE --via
my-default-gw-ip


Because traditional routing tables can have no default route,
xtables should not be forced to have one either.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 11:22     ` Jan Engelhardt
  2008-07-03 12:39       ` Jozsef Kadlecsik
@ 2008-07-03 15:51       ` Krzysztof Oledzki
  2008-07-03 16:07         ` Jan Engelhardt
  2008-07-03 16:14         ` Jan Engelhardt
  2008-07-04 15:15       ` Henrik Nordstrom
  2 siblings, 2 replies; 27+ messages in thread
From: Krzysztof Oledzki @ 2008-07-03 15:51 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 838 bytes --]



On Thu, 3 Jul 2008, Jan Engelhardt wrote:

>
> On Thursday 2008-07-03 11:50, Jozsef Kadlecsik wrote:
>>>
>>>> 	Ingress filtering:
>>>> 		iptables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP
>>>
>>> rp_filter again.
>>
>> Quick and not good examples, I'd say. The main problem with rp_filter is
>> that it drops the packets >silently<. The real benefit of such a match is
>> the possibility to log (and drop) faked packets. If the patch had IPv6
>> support, one could add that additionally (as far as I know) there's no
>> rp_filter for IPv6 at all.
>
> You know what's been bugging me... why don't we replace the entire
> routing infrastructure by an xtables "route" table, with something like

Because routing in a firewall is slow and too complicated?

Best regards,

 				Krzysztof Olędzki

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

* Re: [PATCH,RFC] Route match
  2008-07-03 15:51       ` Krzysztof Oledzki
@ 2008-07-03 16:07         ` Jan Engelhardt
  2008-07-03 16:10           ` Patrick McHardy
  2008-07-03 16:14           ` Krzysztof Oledzki
  2008-07-03 16:14         ` Jan Engelhardt
  1 sibling, 2 replies; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 16:07 UTC (permalink / raw)
  To: Krzysztof Oledzki; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel


On Thursday 2008-07-03 17:51, Krzysztof Oledzki wrote:
>>
>> You know what's been bugging me... why don't we replace the entire
>> routing infrastructure by an xtables "route" table, with something like
>
> Because routing in a firewall is slow and too complicated?

Proof?

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

* Re: [PATCH,RFC] Route match
  2008-07-03 16:07         ` Jan Engelhardt
@ 2008-07-03 16:10           ` Patrick McHardy
  2008-07-03 16:14           ` Krzysztof Oledzki
  1 sibling, 0 replies; 27+ messages in thread
From: Patrick McHardy @ 2008-07-03 16:10 UTC (permalink / raw)
  To: Jan Engelhardt
  Cc: Krzysztof Oledzki, Jozsef Kadlecsik, Phil Oester, netfilter-devel

Jan Engelhardt wrote:
> On Thursday 2008-07-03 17:51, Krzysztof Oledzki wrote:
>   
>>> You know what's been bugging me... why don't we replace the entire
>>> routing infrastructure by an xtables "route" table, with something like
>>>       
>> Because routing in a firewall is slow and too complicated?
>>     
>
> Proof?

Its obvious, routing lookups are optimized for the specific case while
iptables is trying to be generic.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 15:51       ` Krzysztof Oledzki
  2008-07-03 16:07         ` Jan Engelhardt
@ 2008-07-03 16:14         ` Jan Engelhardt
  2008-07-04 13:47           ` Benny Amorsen
  1 sibling, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 16:14 UTC (permalink / raw)
  To: Krzysztof Oledzki; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel


On Thursday 2008-07-03 17:51, Krzysztof Oledzki wrote:
>> >
>> > Quick and not good examples, I'd say. The main problem with rp_filter is
>> > that it drops the packets >silently<. The real benefit of such a match is
>> > the possibility to log (and drop) faked packets. If the patch had IPv6
>> > support, one could add that additionally (as far as I know) there's no
>> > rp_filter for IPv6 at all.
>>
>> You know what's been bugging me... why don't we replace the entire
>> routing infrastructure by an xtables "route" table, with something like
>
> Because routing in a firewall is slow and too complicated?
                                                     [Citation needed]

I fail to see why Xtables (not just a firewall) should be slower
than the routing table (without routing cache, to make it fair).

Iterating over an IPv4 table compares, at a minimum,
interface name(s), src/dst address and an L4 protocol, plus extra
flags like inversion.

Routing? Well, let's see, it can match src address, src interface,
out interface, dst address, and so on. Sounds pretty much like
the same.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 16:07         ` Jan Engelhardt
  2008-07-03 16:10           ` Patrick McHardy
@ 2008-07-03 16:14           ` Krzysztof Oledzki
  1 sibling, 0 replies; 27+ messages in thread
From: Krzysztof Oledzki @ 2008-07-03 16:14 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel

[-- Attachment #1: Type: TEXT/PLAIN, Size: 523 bytes --]



On Thu, 3 Jul 2008, Jan Engelhardt wrote:

>
> On Thursday 2008-07-03 17:51, Krzysztof Oledzki wrote:
>>>
>>> You know what's been bugging me... why don't we replace the entire
>>> routing infrastructure by an xtables "route" table, with something like
>>
>> Because routing in a firewall is slow and too complicated?
>
> Proof?

Proof of what? Of a performance penalty?

http://people.netfilter.org/kadlec/nftest.pdf

# ip route show table all|wc -l
456292


Best regards,

 				Krzysztof Olędzki

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

* Re: [PATCH,RFC] Route match, kernel
  2008-07-03  7:22 ` [PATCH,RFC] Route match, kernel Jan Engelhardt
@ 2008-07-03 16:27   ` Phil Oester
  0 siblings, 0 replies; 27+ messages in thread
From: Phil Oester @ 2008-07-03 16:27 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Thu, Jul 03, 2008 at 09:22:03AM +0200, Jan Engelhardt wrote:
> 
> >+	case XT_ROUTE_SRC_EXISTS:
> >+		fl.nl_u.ip4_u.daddr = iph->saddr;
> >+		ret = fib_lookup(dev_net(in), &fl, &res);
> >+		if (ret == 0 && res.prefixlen != 0) {
> >+			fib_res_put(&res);
> >+			return true ^ info->invert;
> >+		}
> >+	case XT_ROUTE_SRC_EQ:
> >+		fl.nl_u.ip4_u.daddr = iph->saddr;
> >+		ret = fib_lookup(dev_net(in), &fl, &res);
> >+		if (ret == 0 && res.prefixlen == info->prefixlen) {
> >+			fib_res_put(&res);
> >+			return true;
> >+		}
> >+		break;
> 
> Should not these be true ^ info->invert too?

No - invert is only supported on the *_EXISTS case.  Didn't see any point
in supporting invert on gt/lt, but now that I think of it perhaps supporting
it on _EQ may be useful.  But can you see a point on gt/lt?

> I would probably combine mode and invert, to save a byte.

Possible.

> >+static bool
> >+route_mt6(const struct sk_buff *skb, const struct net_device *in,
> >+           const struct net_device *out, const struct xt_match *match,
> >+           const void *matchinfo, int offset, unsigned int protoff,
> >+           bool *hotdrop)
> >+{
> >+	return 1;
> >+}
> 
> If you do not support IPv6, do not write a function for it ;-)

OK, so I should have #if 0 it...but this is just an RFC and that was
listed in the TODO ;-)

Thanks for the review BTW.

Phil

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

* Re: [PATCH,RFC] Route match, user
  2008-07-03  7:26 ` [PATCH,RFC] Route match, user Jan Engelhardt
@ 2008-07-03 16:29   ` Phil Oester
  2008-07-03 16:55     ` Jan Engelhardt
  0 siblings, 1 reply; 27+ messages in thread
From: Phil Oester @ 2008-07-03 16:29 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: netfilter-devel

On Thu, Jul 03, 2008 at 09:26:04AM +0200, Jan Engelhardt wrote:
> 
> >+static const struct option route_opts[] = {
> >+	{ "route-src-exists", 0, NULL, '1' },
> >+	{ "route-src-eq", 1, NULL, '2' },
> >+	{ "route-src-gt", 1, NULL, '3' },
> >+	{ "route-src-lt", 1, NULL, '4' },
> >+	{ "route-dst-exists", 0, NULL, '5' },
> >+	{ "route-dst-eq", 1, NULL, '6' },
> >+	{ "route-dst-gt", 1, NULL, '7' },
> >+	{ "route-dst-lt", 1, NULL, '8' },
> >+	{ .name = NULL }
> >+};
> 
> You are mixing non-C99 and C99 style.

Copy/paste from other iptables code.  Guess a new match should remain
consistent.
 
> >+static int route_parse(int c, char **argv, int invert, unsigned int *flags,
> >+                       const void *entry, struct xt_entry_match **match)
> >+{
> >+	struct xt_route_info *info = (struct xt_route_info *) (*match)->data;
> >+	unsigned int value;
> >+
> >+	check_inverse(optarg, &invert, &optind, 0);
> 
> I would not bother supporting intraplaced ! at all. Just remove that line.

Sorry..."intraplaced"?
 
> >+		case '6':
> >+			if (invert) 
> >+				exit_error(PARAMETER_PROBLEM,
> >+						"route: unexpected `!'");
> >+
> >+			if (string_to_number(optarg, 1, 128, &value) == -1)
> >+				exit_error(PARAMETER_PROBLEM,
> >+				           "route: Expected prefix between 1 and 128");
> >+
> >+			info->mode = XT_ROUTE_DST_EQ;
> >+			info->value = value;
> >+			break;
> 
> There is a lot of code to unify between route_mt_parse and route_mt6_parse.

I suppose I could pass a 32 or 128 to a common function, yes.

Phil

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

* Re: [PATCH,RFC] Route match, user
  2008-07-03 16:29   ` Phil Oester
@ 2008-07-03 16:55     ` Jan Engelhardt
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 16:55 UTC (permalink / raw)
  To: Phil Oester; +Cc: netfilter-devel


On Thursday 2008-07-03 18:29, Phil Oester wrote:
> 
>> >+static int route_parse(int c, char **argv, int invert, unsigned int *flags,
>> >+                       const void *entry, struct xt_entry_match **match)
>> >+{
>> >+	struct xt_route_info *info = (struct xt_route_info *) (*match)->data;
>> >+	unsigned int value;
>> >+
>> >+	check_inverse(optarg, &invert, &optind, 0);
>> 
>> I would not bother supporting intraplaced ! at all. Just remove that line.
>
>Sorry..."intraplaced"?

intra = within/inside

There is

	iptables ! -s 192.168.1.5	(normal)
and
	iptables -s ! 192.168.1.5	(intraplaced)

Considering that most extensions only support the normal form,
I would not add any more intraplace support to new modules
to reduce the number of supported styles. Real robustness can
only be achieved when one is strict.

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

* Re: [PATCH,RFC] Route match
  2008-07-03  9:50   ` Jozsef Kadlecsik
  2008-07-03 11:22     ` Jan Engelhardt
@ 2008-07-03 18:53     ` Patrick McHardy
  2008-07-03 22:21       ` Jozsef Kadlecsik
  1 sibling, 1 reply; 27+ messages in thread
From: Patrick McHardy @ 2008-07-03 18:53 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: Jan Engelhardt, Phil Oester, netfilter-devel

Jozsef Kadlecsik wrote:
> On Thu, 3 Jul 2008, Jan Engelhardt wrote:
> 
>>> TODO: add IPv6 support to kernel side
>>>
>>> Examples:
>>>
>>> 	Egress filtering:
>>> 		iptables -A FORWARD -m route ! --route-src-exists -j DROP
>> That's what rp_filter is for.
>>
>>> 	Ingress filtering:
>>> 		iptables -A FORWARD -i $EXTERNAL_IF -m route --route-src-exists -j DROP
>> rp_filter again.
> 
> Quick and not good examples, I'd say. The main problem with rp_filter is 
> that it drops the packets >silently<. The real benefit of such a match is 
> the possibility to log (and drop) faked packets. If the patch had IPv6 
> support, one could add that additionally (as far as I know) there's no 
> rp_filter for IPv6 at all.


I agree. While I find rp_filter highly annoying (Debian has it enabled
by default), this patch at least allows you to notice whats going on
easily. I'm also sure there are people who would like to use rp_filter
like functionality for IPv6.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 14:15             ` Jan Engelhardt
@ 2008-07-03 22:02               ` Jozsef Kadlecsik
  2008-07-03 23:02                 ` Jan Engelhardt
  0 siblings, 1 reply; 27+ messages in thread
From: Jozsef Kadlecsik @ 2008-07-03 22:02 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Phil Oester, netfilter-devel

On Thu, 3 Jul 2008, Jan Engelhardt wrote:

> On Thursday 2008-07-03 15:31, Jozsef Kadlecsik wrote:
> >On Thu, 3 Jul 2008, Jan Engelhardt wrote:
> >> On Thursday 2008-07-03 14:39, Jozsef Kadlecsik wrote:
> >> >
> >> >One can find a lot of smaller and bigger missing pieces, like a new table, 
> >> >new hook, if we'd associate a 'routing table' to a 'chain in the iptables 
> >> >route table', then we'd need a default policy support (i.e. default route) 
> >> >for the user defined chains too, etc.
> >> 
> >> User-defined chains always have an implicit policy of 'RETURN',
> >> and I would not turn a knob on that property anytime.
> >
> >Routing cannot be replaced by netfilter 'route' table without supporting a 
> >'default policy' (as default route) in the user defined chains (as routing 
> >tables).
> 
> User-defines chains return to the main chain once control runs off their end.
> Since the main chain has a default policy, I do not see aproblem.

That means we'd not support multiple routing tables with default routes.
We'd loose an important functionality, which is unacceptable.

[...] 
> >Unless you intend to define the 'default route' as the last rule in any 
> >chain...
> 
> No, default route would be
> 
> 	iptables -t route -A ROUTING <no further conditions> -j ROUTE --via
> my-default-gw-ip
> 
> Because traditional routing tables can have no default route,
> xtables should not be forced to have one either.

Routing tables can have default route. Most of the time this is the main 
point when using multiple routing tables: source routing via another
default route.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH,RFC] Route match
  2008-07-03 18:53     ` Patrick McHardy
@ 2008-07-03 22:21       ` Jozsef Kadlecsik
  2008-07-04 20:26         ` Jozsef Kadlecsik
  0 siblings, 1 reply; 27+ messages in thread
From: Jozsef Kadlecsik @ 2008-07-03 22:21 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Jan Engelhardt, Phil Oester, netfilter-devel

On Thu, 3 Jul 2008, Patrick McHardy wrote:

> Jozsef Kadlecsik wrote:
> > On Thu, 3 Jul 2008, Jan Engelhardt wrote:
> > 
> > > > TODO: add IPv6 support to kernel side
> > > > 
> > > > Examples:
> > > > 
> > > > 	Egress filtering:
> > > > 		iptables -A FORWARD -m route ! --route-src-exists -j DROP
> > > That's what rp_filter is for.
> > > 
> > > > 	Ingress filtering:
> > > > 		iptables -A FORWARD -i $EXTERNAL_IF -m route
> > > > --route-src-exists -j DROP
> > > rp_filter again.
> > 
> > Quick and not good examples, I'd say. The main problem with rp_filter is
> > that it drops the packets >silently<. The real benefit of such a match is
> > the possibility to log (and drop) faked packets. If the patch had IPv6
> > support, one could add that additionally (as far as I know) there's no
> > rp_filter for IPv6 at all.
> 
> I agree. While I find rp_filter highly annoying (Debian has it enabled
> by default), this patch at least allows you to notice whats going on
> easily. I'm also sure there are people who would like to use rp_filter
> like functionality for IPv6.

A single loop in the routing paths is enough and rp_filter enabled ruins 
everything. :-)

If there's dynamic routing (say OSPF), then sometimes it's not so easy at 
all to write (static) iptables rules for egress/ingress filtering. That is 
also a case where the route match can be important (besides the 
possibility to log nasty packets when the routing is trivial).

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH,RFC] Route match
  2008-07-03 22:02               ` Jozsef Kadlecsik
@ 2008-07-03 23:02                 ` Jan Engelhardt
  2008-07-04  0:19                   ` James King
  0 siblings, 1 reply; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-03 23:02 UTC (permalink / raw)
  To: Jozsef Kadlecsik; +Cc: Phil Oester, netfilter-devel


On Friday 2008-07-04 00:02, Jozsef Kadlecsik wrote:
>> 
>> User-defines chains return to the main chain once control runs off
>> their end. Since the main chain has a default policy, I do not see
>> aproblem.
>
>That means we'd not support multiple routing tables with default
>routes. We'd loose an important functionality, which is
>unacceptable.

Routing tables become xtables chains. We would not lose anything.
In fact, you would gain the possibilty to jump to further chains,
something not possible in routing today.

rt input:

ip rule fwmark 5 table 5
ip rule fwmark 6 table 6
ip route add 10.10.96.2/32 dev eth2 table 5
ip route add via 10.10.96.1 dev eth0 table 5 # default route
ip route add via 10.11.96.1 dev eth1 table 6 # default orute

in xtables (ROUTE is a terminating target):

-N table5
-N table6
-A table5 -d 10.10.96.2 -j ROUTE --dev eth2
-A table5 -j ROUTE --via 10.10.96.1 --dev eth0  # default route!
-A table6 -j ROUTE --via 10.11.96.1 --dev eth1  # also a default
-A ROUTING -m mark --mark 5 -j table5
-A ROUTING -m mark --mark 6 -j table6


>> Because traditional routing tables can have no default route,
>> xtables should not be forced to have one either.
>
>Routing tables can have default route. Most of the time this is the main 
>point when using multiple routing tables: source routing via another
>default route.

It is very easy to not have a default gateway.

ip route flush
ip route add 10.10.96.0/20 dev eth0

Try pinging 134.76.12.5 with that. Will fail with Network Unreachable.
The xtables representation henceforth:

-A ROUTING -d 10.10.96.0/20 -j ROUTE --dev eth0
-A ROUTING -j ROUTE --unreachable

or alternatively something like -P ROUTING UNREACHABLE.

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

* Re: [PATCH,RFC] Route match
  2008-07-03 23:02                 ` Jan Engelhardt
@ 2008-07-04  0:19                   ` James King
  2008-07-04  0:37                     ` Jan Engelhardt
  0 siblings, 1 reply; 27+ messages in thread
From: James King @ 2008-07-04  0:19 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel

On Thu, Jul 3, 2008 at 4:02 PM, Jan Engelhardt <jengelh@medozas.de> wrote:

> Routing tables become xtables chains. We would not lose anything.
> In fact, you would gain the possibilty to jump to further chains,
> something not possible in routing today.
>
> rt input:
>
> ip rule fwmark 5 table 5
> ip rule fwmark 6 table 6
> ip route add 10.10.96.2/32 dev eth2 table 5
> ip route add via 10.10.96.1 dev eth0 table 5 # default route
> ip route add via 10.11.96.1 dev eth1 table 6 # default orute
>
> in xtables (ROUTE is a terminating target):
>
> -N table5
> -N table6
> -A table5 -d 10.10.96.2 -j ROUTE --dev eth2
> -A table5 -j ROUTE --via 10.10.96.1 --dev eth0  # default route!
> -A table6 -j ROUTE --via 10.11.96.1 --dev eth1  # also a default
> -A ROUTING -m mark --mark 5 -j table5
> -A ROUTING -m mark --mark 6 -j table6

Wouldn't this break with normal routing concepts, since xtables
traverses the chain linearly, while routing lookups use longest prefix
match (most specific route wins)?  IOW, unless xtables automatically
inserted the rule into the correct spot in the chain (as opposed to
just appending to the end of the chain like -A implies), you could run
into situations where specifying the rules out of order would send the
packet to the wrong next-hop.


Regards,
James

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

* Re: [PATCH,RFC] Route match
  2008-07-04  0:19                   ` James King
@ 2008-07-04  0:37                     ` Jan Engelhardt
  0 siblings, 0 replies; 27+ messages in thread
From: Jan Engelhardt @ 2008-07-04  0:37 UTC (permalink / raw)
  To: James King; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel


On Friday 2008-07-04 02:19, James King wrote:
>>
>> -N table5
>> -N table6
>> -A table5 -d 10.10.96.2 -j ROUTE --dev eth2
>> -A table5 -j ROUTE --via 10.10.96.1 --dev eth0  # default route!
>> -A table6 -j ROUTE --via 10.11.96.1 --dev eth1  # also a default
>> -A ROUTING -m mark --mark 5 -j table5
>> -A ROUTING -m mark --mark 6 -j table6
>
>Wouldn't this break with normal routing concepts, since xtables
>traverses the chain linearly, while routing lookups use longest prefix
>match (most specific route wins)?

Very well observed. However,

- the kernel is likely to do a linear rule list search (in `ip ru l`)
  too, because I would not imagine how you could optimize _that_
  more than Xtables when it has to compare src/dst addresses, fwmarks,
  etc.

- you are right, the *routing* table is sorted by longest prefix,
  and that is probably why people tout it as "optimized for the case".
  But I would not see anything wrong with the user doing the sorting
  (or even Xtables).

 (Maybe I just want a new command-line interface for routing instead
  of a new in-core architecture...)


> IOW, unless xtables automatically
>inserted the rule into the correct spot in the chain (as opposed to
>just appending to the end of the chain like -A implies), you could run
>into situations where specifying the rules out of order would send the
>packet to the wrong next-hop.

Or you could actually optimize it. If, say 95% of all your packets
go out on eth0, the following route table (which is dependent
upon cabling), with its ordering, is suboptimal:

	192.168.1.1/32 dev isp0
	192.168.1.0/24 dev eth0

Relaxing the longest-prefix ordering would mean less traversal
time through the chains (i.e. minimizing the time taken
for routing table traversal for randomly distributed packets,
but weighted according to network situation, over a given
time period.)

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

* Re: [PATCH,RFC] Route match
  2008-07-03 16:14         ` Jan Engelhardt
@ 2008-07-04 13:47           ` Benny Amorsen
  0 siblings, 0 replies; 27+ messages in thread
From: Benny Amorsen @ 2008-07-04 13:47 UTC (permalink / raw)
  To: netfilter-devel

Jan Engelhardt <jengelh@medozas.de> writes:

> I fail to see why Xtables (not just a firewall) should be slower
> than the routing table (without routing cache, to make it fair).

What about the routing cache, though?

Our Linux-based routers handle considerably less than 1Gbps peak, and
they drop packets when the cache is flushed. (So I had to set the
automatic flush to 86400 seconds instead of 10).

It would be necessary to either reinvent the route cache or come up
with something better. Preferably the latter, of course.


/Benny



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

* Re: [PATCH,RFC] Route match
  2008-07-03 11:22     ` Jan Engelhardt
  2008-07-03 12:39       ` Jozsef Kadlecsik
  2008-07-03 15:51       ` Krzysztof Oledzki
@ 2008-07-04 15:15       ` Henrik Nordstrom
  2 siblings, 0 replies; 27+ messages in thread
From: Henrik Nordstrom @ 2008-07-04 15:15 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: Jozsef Kadlecsik, Phil Oester, netfilter-devel

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

On tor, 2008-07-03 at 13:22 +0200, Jan Engelhardt wrote:

> You know what's been bugging me... why don't we replace the entire
> routing infrastructure by an xtables "route" table, with something like

It's been discussed off-list many times. 

The problem with the routing table is that it's more to that table than
what's visible. It's heavily cached and annotated by the kernel beyond
just the plain routing table, and used in a number of different ways
such as when assigning the source address on outgoing connections, way
before there even is a packet.

Regards
Henrik

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 307 bytes --]

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

* Re: [PATCH,RFC] Route match
  2008-07-03 22:21       ` Jozsef Kadlecsik
@ 2008-07-04 20:26         ` Jozsef Kadlecsik
  0 siblings, 0 replies; 27+ messages in thread
From: Jozsef Kadlecsik @ 2008-07-04 20:26 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: Jan Engelhardt, Phil Oester, netfilter-devel

On Fri, 4 Jul 2008, Jozsef Kadlecsik wrote:

> If there's dynamic routing (say OSPF), then sometimes it's not so easy at 
> all to write (static) iptables rules for egress/ingress filtering. That is 
> also a case where the route match can be important (besides the 
> possibility to log nasty packets when the routing is trivial).

I have to correct myself: when rp_filter produces false results then the 
route match does also at egress/ingress filtering.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlec@mail.kfki.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : KFKI Research Institute for Particle and Nuclear Physics
          H-1525 Budapest 114, POB. 49, Hungary

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

end of thread, other threads:[~2008-07-04 20:26 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-03  0:39 [PATCH,RFC] Route match Phil Oester
2008-07-03  7:18 ` Jan Engelhardt
2008-07-03  9:50   ` Jozsef Kadlecsik
2008-07-03 11:22     ` Jan Engelhardt
2008-07-03 12:39       ` Jozsef Kadlecsik
2008-07-03 13:13         ` Jan Engelhardt
2008-07-03 13:31           ` Jozsef Kadlecsik
2008-07-03 14:15             ` Jan Engelhardt
2008-07-03 22:02               ` Jozsef Kadlecsik
2008-07-03 23:02                 ` Jan Engelhardt
2008-07-04  0:19                   ` James King
2008-07-04  0:37                     ` Jan Engelhardt
2008-07-03 15:51       ` Krzysztof Oledzki
2008-07-03 16:07         ` Jan Engelhardt
2008-07-03 16:10           ` Patrick McHardy
2008-07-03 16:14           ` Krzysztof Oledzki
2008-07-03 16:14         ` Jan Engelhardt
2008-07-04 13:47           ` Benny Amorsen
2008-07-04 15:15       ` Henrik Nordstrom
2008-07-03 18:53     ` Patrick McHardy
2008-07-03 22:21       ` Jozsef Kadlecsik
2008-07-04 20:26         ` Jozsef Kadlecsik
2008-07-03  7:22 ` [PATCH,RFC] Route match, kernel Jan Engelhardt
2008-07-03 16:27   ` Phil Oester
2008-07-03  7:26 ` [PATCH,RFC] Route match, user Jan Engelhardt
2008-07-03 16:29   ` Phil Oester
2008-07-03 16:55     ` Jan Engelhardt

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.