All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv3 0/2+1] Find address type on the packet's interface
@ 2007-11-15 17:14 Laszlo Attila Toth
  2007-11-15 17:14 ` [PATCHv3 1/2] Find address type on a specific or on any interface Laszlo Attila Toth
  0 siblings, 1 reply; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-15 17:14 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Laszlo Attila Toth

Hi Patrick,

This extension of ipt_addrtype match lets the address type checking be
limited to the incoming or outgoing interface of the packets depending
on the current hook.

In the FORWARD chain only one check is allowed but the user can choose
which one would like to specifiy.

Because of this extension the match has a new revision. Rev 0 can be
used by older tools and rev 1 is for the modified iptables match.

The iptables patch is for revision 1 only.

Usage:
  iptables -A INPUT -m addrtype ... --limit-iface-in -j ACCEPT
  iptables -A OUTPUT -m addrtype ... --limit-iface-out -j ACCEPT
  # 2 rules in the FORWARD chain
  iptables -A FORWARD -m addrtype ... --limit-iface-in -j ACCEPT
  iptables -A FORWARD -m addrtype ... --limit-iface-out -j ACCEPT

Regards,
  Attila

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

* [PATCHv3 1/2] Find address type on a specific or on any interface
  2007-11-15 17:14 [PATCHv3 0/2+1] Find address type on the packet's interface Laszlo Attila Toth
@ 2007-11-15 17:14 ` Laszlo Attila Toth
  2007-11-15 17:14   ` [PATCHv3 2/2] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
  0 siblings, 1 reply; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-15 17:14 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Laszlo Attila Toth

Address type search can be limited to an interface by
inet_dev_addr_type function.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/net/route.h     |    1 +
 net/ipv4/fib_frontend.c |   20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/net/route.h b/include/net/route.h
index f7ce625..d155c29 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -119,6 +119,7 @@ extern unsigned short	ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mt
 extern void		ip_rt_send_redirect(struct sk_buff *skb);
 
 extern unsigned		inet_addr_type(__be32 addr);
+extern unsigned		inet_dev_addr_type(__be32 addr, const struct net_device *dev);
 extern void		ip_rt_multicast_event(struct in_device *);
 extern int		ip_rt_ioctl(unsigned int cmd, void __user *arg);
 extern void		ip_rt_get_source(u8 *src, struct rtable *rt);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 732d8f0..f116f61 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -155,7 +155,11 @@ out:
 	return dev;
 }
 
-unsigned inet_addr_type(__be32 addr)
+/*
+ * Find address type as if only "dev" was present in the system. If
+ * on_dev is NULL then all interfaces are taken into consideration.
+ */
+static inline unsigned __inet_dev_addr_type(__be32 addr, const struct net_device *dev)
 {
 	struct flowi		fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
 	struct fib_result	res;
@@ -175,13 +179,24 @@ unsigned inet_addr_type(__be32 addr)
 	if (local_table) {
 		ret = RTN_UNICAST;
 		if (!local_table->tb_lookup(local_table, &fl, &res)) {
-			ret = res.type;
+			if ((!dev || dev == res.fi->fib_dev))
+				ret = res.type;
 			fib_res_put(&res);
 		}
 	}
 	return ret;
 }
 
+unsigned inet_addr_type(__be32 addr)
+{
+	return __inet_dev_addr_type(addr, NULL);
+}
+
+unsigned inet_dev_addr_type(__be32 addr, const struct net_device *dev)
+{
+       return __inet_dev_addr_type(addr, dev);
+}
+
 /* Given (packet source, input interface) and optional (dst, oif, tos):
    - (main) check, that source is valid i.e. not broadcast or our local
      address.
@@ -925,4 +940,5 @@ void __init ip_fib_init(void)
 }
 
 EXPORT_SYMBOL(inet_addr_type);
+EXPORT_SYMBOL(inet_dev_addr_type);
 EXPORT_SYMBOL(ip_dev_find);
-- 
1.5.2.5


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

* [PATCHv3 2/2] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-15 17:14 ` [PATCHv3 1/2] Find address type on a specific or on any interface Laszlo Attila Toth
@ 2007-11-15 17:14   ` Laszlo Attila Toth
  2007-11-15 17:14     ` [PATCHv3 iptables] Find address type on a specific or on any interface Laszlo Attila Toth
  2007-11-16 14:22     ` [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
  0 siblings, 2 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-15 17:14 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Laszlo Attila Toth

Addrtype match has a new revision (1), which lets address type checking
limited to the interface the current packet belongs to. Either incoming
or outgoing interface can be used depending on the current hook. In the
FORWARD hook two maches should be used if both interfaces have to be checked.

Revision 0 lets older userspace programs use the match as earlier.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/netfilter_ipv4/ipt_addrtype.h |   16 ++++-
 net/ipv4/netfilter/ipt_addrtype.c           |  118 +++++++++++++++++++++++----
 2 files changed, 115 insertions(+), 19 deletions(-)

diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
index 166ed01..83062a0 100644
--- a/include/linux/netfilter_ipv4/ipt_addrtype.h
+++ b/include/linux/netfilter_ipv4/ipt_addrtype.h
@@ -1,7 +1,21 @@
 #ifndef _IPT_ADDRTYPE_H
 #define _IPT_ADDRTYPE_H
 
-struct ipt_addrtype_info {
+enum
+{
+	IPT_ADDRTYPE_INVERT_SOURCE	= 0x0001,
+	IPT_ADDRTYPE_INVERT_DEST	= 0x0002,
+	IPT_ADDRTYPE_LIMIT_IFACE_IN	= 0x0004,
+	IPT_ADDRTYPE_LIMIT_IFACE_OUT	= 0x0008,
+};
+
+struct ipt_addrtype_info_v1 {
+	u_int16_t	source;		/* source-type mask */
+	u_int16_t	dest;		/* dest-type mask */
+	u_int32_t	flags;
+};
+
+struct ipt_addrtype_info_v0 {
 	u_int16_t	source;		/* source-type mask */
 	u_int16_t	dest;		/* dest-type mask */
 	u_int32_t	invert_source;
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index 59f01f7..9ac9512 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -22,44 +22,126 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("iptables addrtype match");
 
-static inline bool match_type(__be32 addr, u_int16_t mask)
+static inline bool match_type(__be32 addr,
+			      const struct net_device *in,
+			      u_int16_t mask)
 {
-	return !!(mask & (1 << inet_addr_type(addr)));
+	return !!(mask & (1 << inet_dev_addr_type(addr, in)));
 }
 
-static bool match(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)
+static bool addrtype_match_v0(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 ipt_addrtype_info *info = matchinfo;
+	const struct ipt_addrtype_info_v0 *info = matchinfo;
 	const struct iphdr *iph = ip_hdr(skb);
 	bool ret = true;
 
 	if (info->source)
-		ret &= match_type(iph->saddr, info->source)^info->invert_source;
-	if (info->dest)
-		ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
+		ret &= match_type(iph->saddr, NULL, info->source)^info->invert_source;
+	if (ret && info->dest)
+		ret &= match_type(iph->daddr, NULL, info->dest)^info->invert_dest;
 
 	return ret;
 }
 
-static struct xt_match addrtype_match __read_mostly = {
-	.name		= "addrtype",
-	.family		= AF_INET,
-	.match		= match,
-	.matchsize	= sizeof(struct ipt_addrtype_info),
-	.me		= THIS_MODULE
+static bool addrtype_match_v1(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 ipt_addrtype_info_v1 *info = matchinfo;
+	const struct iphdr *iph = ip_hdr(skb);
+	const struct net_device *limit_dev = NULL;
+	bool ret = true;
+
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
+		limit_dev = in;
+	else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
+		limit_dev = out;
+
+
+	if (info->source)
+		ret &= match_type(iph->saddr, limit_dev, info->source) ^
+			(info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
+	if (ret && info->dest)
+		ret &= match_type(iph->daddr, limit_dev, info->dest) ^
+			(info->flags & IPT_ADDRTYPE_INVERT_DEST);
+
+	return ret;
+}
+
+static bool addrtype_checkentry_v1(const char *tablename,
+				   const void *ip_void,
+				   const struct xt_match *match,
+				   void *matchinfo,
+				   unsigned int hook_mask)
+{
+	struct ipt_addrtype_info_v1 *info = matchinfo;
+
+	if (!(info->flags &
+	      (IPT_ADDRTYPE_LIMIT_IFACE_IN & IPT_ADDRTYPE_LIMIT_IFACE_OUT))) {
+		printk(KERN_ERR "ipt_addrtype: cannot be both incoming and "
+				"outgoing interface limitation selected\n");
+		return false;
+	}
+
+	if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) &&
+	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printk(KERN_ERR "ipt_addrtype: output interface limitation "
+				"not valid in PRE_ROUTING and INPUT\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) &&
+	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+		printk(KERN_ERR "ipt_addrtype: input interface limitation "
+				"not valid in POST_ROUTING and OUTPUT\n");
+		return false;
+	}
+	return true;
+}
+
+
+
+static struct xt_match addrtype_match[] __read_mostly = {
+	{
+		.name		= "addrtype",
+		.family		= AF_INET,
+		.revision	= 0,
+		.match		= addrtype_match_v0,
+		.matchsize	= sizeof(struct ipt_addrtype_info_v0),
+		.me		= THIS_MODULE
+	},
+	{
+		.name		= "addrtype",
+		.family		= AF_INET,
+		.revision	= 1,
+		.match		= addrtype_match_v1,
+		.checkentry	= addrtype_checkentry_v1,
+		.matchsize	= sizeof(struct ipt_addrtype_info_v1),
+		.me		= THIS_MODULE
+	}
 };
 
 static int __init ipt_addrtype_init(void)
 {
-	return xt_register_match(&addrtype_match);
+	return xt_register_matches(addrtype_match,
+			ARRAY_SIZE(addrtype_match));
 }
 
 static void __exit ipt_addrtype_fini(void)
 {
-	xt_unregister_match(&addrtype_match);
+	xt_unregister_matches(addrtype_match,
+			ARRAY_SIZE(addrtype_match));
 }
 
 module_init(ipt_addrtype_init);
-- 
1.5.2.5


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

* [PATCHv3 iptables] Find address type on a specific or on any interface
  2007-11-15 17:14   ` [PATCHv3 2/2] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
@ 2007-11-15 17:14     ` Laszlo Attila Toth
  2007-11-16 14:22     ` [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
  1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-15 17:14 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel, Laszlo Attila Toth

Address type match: limited to incoming or outgoing interface

Address type checking can be limited to the incoming or outgoing interface
depending on the current chain. In the FORWARD chain only one of them is
allowed at the same time.

Older version (revision 0) of address type match is not supported.

The man page is updated to print the address in separate sections insted of
a single paragraph.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 libipt_addrtype.c   |   99 +++++++++++++++++++++++++++++++++++-----------------
 libipt_addrtype.man |   35 ++++++++++++++++++
 2 files changed, 103 insertions(+), 31 deletions(-)

Index: extensions/libipt_addrtype.c
===================================================================
--- extensions/libipt_addrtype.c	(revision 7089)
+++ extensions/libipt_addrtype.c	(working copy)
@@ -42,6 +42,8 @@
 "Address type match v%s options:\n"
 " [!] --src-type type[,...]      Match source address type\n"
 " [!] --dst-type type[,...]      Match destination address type\n"
+"     --limit-iface-in           Match only on the packet's incoming device\n"
+"     --limit-iface-out          Match only on the packet's incoming device\n"
 "\n"
 "Valid types:           \n"
 , IPTABLES_VERSION);
@@ -49,7 +51,7 @@
 }
 
 static int
-parse_type(const char *name, size_t strlen, u_int16_t *mask)
+addrtype_parse_type(const char *name, size_t strlen, u_int16_t *mask)
 {
 	int i;
 
@@ -63,52 +65,68 @@
 	return 0;
 }
 
-static void parse_types(const char *arg, u_int16_t *mask)
+static void addrtype_parse_types(const char *arg, u_int16_t *mask)
 {
 	const char *comma;
 
 	while ((comma = strchr(arg, ',')) != NULL) {
-		if (comma == arg || !parse_type(arg, comma-arg, mask))
+		if (comma == arg || !addrtype_parse_type(arg, comma-arg, mask))
 			exit_error(PARAMETER_PROBLEM,
 			           "addrtype: bad type `%s'", arg);
 		arg = comma + 1;
 	}
 
-	if (strlen(arg) == 0 || !parse_type(arg, strlen(arg), mask))
+	if (strlen(arg) == 0 || !addrtype_parse_type(arg, strlen(arg), mask))
 		exit_error(PARAMETER_PROBLEM, "addrtype: bad type `%s'", arg);
 }
 	
-#define IPT_ADDRTYPE_OPT_SRCTYPE	0x1
-#define IPT_ADDRTYPE_OPT_DSTTYPE	0x2
+#define IPT_ADDRTYPE_OPT_SRCTYPE		0x1
+#define IPT_ADDRTYPE_OPT_DSTTYPE		0x2
+#define IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN		0x4
+#define IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT	0x8
 
 static int
 addrtype_parse(int c, char **argv, int invert, unsigned int *flags,
                const void *entry, struct xt_entry_match **match)
 {
-	struct ipt_addrtype_info *info =
-		(struct ipt_addrtype_info *) (*match)->data;
+	struct ipt_addrtype_info_v1 *info =
+		(struct ipt_addrtype_info_v1 *) (*match)->data;
 
 	switch (c) {
 	case '1':
-		if (*flags&IPT_ADDRTYPE_OPT_SRCTYPE)
+		if (*flags & IPT_ADDRTYPE_OPT_SRCTYPE)
 			exit_error(PARAMETER_PROBLEM,
 			           "addrtype: can't specify src-type twice");
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_types(argv[optind-1], &info->source);
+		addrtype_parse_types(argv[optind-1], &info->source);
 		if (invert)
-			info->invert_source = 1;
+			info->flags |= IPT_ADDRTYPE_INVERT_SOURCE;
 		*flags |= IPT_ADDRTYPE_OPT_SRCTYPE;
 		break;
 	case '2':
-		if (*flags&IPT_ADDRTYPE_OPT_DSTTYPE)
+		if (*flags & IPT_ADDRTYPE_OPT_DSTTYPE)
 			exit_error(PARAMETER_PROBLEM,
 			           "addrtype: can't specify dst-type twice");
 		check_inverse(optarg, &invert, &optind, 0);
-		parse_types(argv[optind-1], &info->dest);
+		addrtype_parse_types(argv[optind-1], &info->dest);
 		if (invert)
-			info->invert_dest = 1;
+			info->flags |= IPT_ADDRTYPE_INVERT_DEST;
 		*flags |= IPT_ADDRTYPE_OPT_DSTTYPE;
 		break;
+	case '3':
+		if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN)
+			exit_error(PARAMETER_PROBLEM,
+			           "addrtype: can't specify limit-iface-in twice");
+		info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_IN;
+		*flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN;
+		break;
+	case '4':
+		if (*flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT)
+			exit_error(PARAMETER_PROBLEM,
+			           "addrtype: can't specify limit-iface-out twice");
+		info->flags |= IPT_ADDRTYPE_LIMIT_IFACE_OUT;
+		*flags |= IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT;
+		break;
 	default:
 		return 0;
 	}
@@ -121,9 +139,14 @@
 	if (!(flags & (IPT_ADDRTYPE_OPT_SRCTYPE|IPT_ADDRTYPE_OPT_DSTTYPE)))
 		exit_error(PARAMETER_PROBLEM,
 			   "addrtype: you must specify --src-type or --dst-type");
+	if (flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_IN &&
+	    flags & IPT_ADDRTYPE_OPT_LIMIT_IFACE_OUT)
+		exit_error(PARAMETER_PROBLEM,
+			   "addrtype: you can't specify both --limit-iface-in "
+			   "and --limit-iface-out");
 }
-
-static void print_types(u_int16_t mask)
+ 
+static void addrtype_print_types(u_int16_t mask)
 {
 	const char *sep = "";
 	int i;
@@ -140,54 +163,69 @@
 static void addrtype_print(const void *ip, const struct xt_entry_match *match,
                            int numeric)
 {
-	const struct ipt_addrtype_info *info = 
-		(struct ipt_addrtype_info *) match->data;
+	const struct ipt_addrtype_info_v1 *info = 
+		(struct ipt_addrtype_info_v1 *) match->data;
 
 	printf("ADDRTYPE match ");
 	if (info->source) {
 		printf("src-type ");
-		if (info->invert_source)
+		if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
 			printf("!");
-		print_types(info->source);
+		addrtype_print_types(info->source);
 	}
 	if (info->dest) {
 		printf("dst-type ");
-		if (info->invert_dest)
+		if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
 			printf("!");
-		print_types(info->dest);
+		addrtype_print_types(info->dest);
 	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+		printf("limit-in ");
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printf("limit-out ");
+	}
 }
 
 static void addrtype_save(const void *ip, const struct xt_entry_match *match)
 {
-	const struct ipt_addrtype_info *info =
-		(struct ipt_addrtype_info *) match->data;
+	const struct ipt_addrtype_info_v1 *info =
+		(struct ipt_addrtype_info_v1 *) match->data;
 
 	if (info->source) {
 		printf("--src-type ");
-		if (info->invert_source)
+		if (info->flags & IPT_ADDRTYPE_INVERT_SOURCE)
 			printf("! ");
-		print_types(info->source);
+		addrtype_print_types(info->source);
 	}
 	if (info->dest) {
 		printf("--dst-type ");
-		if (info->invert_dest)
+		if (info->flags & IPT_ADDRTYPE_INVERT_DEST)
 			printf("! ");
-		print_types(info->dest);
+		addrtype_print_types(info->dest);
 	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+		printf("--limit-iface-in ");
+	}
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printf("--limit-iface-out ");
+	}
 }
 
 static const struct option addrtype_opts[] = {
 	{ "src-type", 1, NULL, '1' },
 	{ "dst-type", 1, NULL, '2' },
+	{ "limit-iface-in", 0, NULL, '3' },
+	{ "limit-iface-out", 0, NULL, '4' },
 	{ }
 };
 
 static struct iptables_match addrtype_match = {
 	.name 		= "addrtype",
 	.version 	= IPTABLES_VERSION,
-	.size 		= IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
-	.userspacesize 	= IPT_ALIGN(sizeof(struct ipt_addrtype_info)),
+	.revision	= 1,
+	.size 		= IPT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
+	.userspacesize 	= IPT_ALIGN(sizeof(struct ipt_addrtype_info_v1)),
 	.help 		= addrtype_help,
 	.parse 		= addrtype_parse,
 	.final_check 	= addrtype_check,
@@ -196,7 +234,6 @@
 	.extra_opts 	= addrtype_opts,
 };
 
-
 void _init(void) 
 {
 	register_match(&addrtype_match);
Index: extensions/libipt_addrtype.man
===================================================================
--- extensions/libipt_addrtype.man	(revision 7089)
+++ extensions/libipt_addrtype.man	(working copy)
@@ -7,31 +7,66 @@
 .TP
 .BI "UNSPEC"
 an unspecified address (i.e. 0.0.0.0)
+.TP
 .BI "UNICAST"
 an unicast address
+.TP
 .BI "LOCAL"
 a local address
+.TP
 .BI "BROADCAST"
 a broadcast address
+.TP
 .BI "ANYCAST"
 an anycast packet
+.TP
 .BI "MULTICAST"
 a multicast address
+.TP
 .BI "BLACKHOLE"
 a blackhole address
+.TP
 .BI "UNREACHABLE"
 an unreachable address
+.TP
 .BI "PROHIBIT"
 a prohibited address
+.TP
 .BI "THROW"
 FIXME
+.TP
 .BI "NAT"
 FIXME
+.TP
 .BI "XRESOLVE"
 FIXME
 .TP
+Options:
+.TP
 .BI "--src-type " "type"
 Matches if the source address is of given type
 .TP
 .BI "--dst-type " "type"
 Matches if the destination address is of given type
+.TP
+.BI "--limit-iface-in"
+The address type checking can be limited to the interface the packet is coming
+in. This option is only valid in the
+.BR PREROUTING ,
+.B INPUT
+and
+.B FORWARD
+chains. It cannot be specified with the
+.B "--limit-iface-out"
+option.
+.TP
+.BI "--limit-iface-out"
+The address type checiking can be limited to the interface the packet is going
+out. This option is only valid in the
+.BR POSTROUTING ,
+.B OUTPUT
+and
+.B FORWARD
+chains. It cannot be specified with the
+.B --limit-iface-in
+option.

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

* [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-15 17:14   ` [PATCHv3 2/2] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
  2007-11-15 17:14     ` [PATCHv3 iptables] Find address type on a specific or on any interface Laszlo Attila Toth
@ 2007-11-16 14:22     ` Laszlo Attila Toth
  2007-11-16 15:06       ` Jan Engelhardt
  1 sibling, 1 reply; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-16 14:22 UTC (permalink / raw)
  To: kaber; +Cc: netfilter-devel, Laszlo Attila Toth

Addrtype match has a new revision (1), which lets address type checking
limited to the interface the current packet belongs to. Either incoming
or outgoing interface can be used depending on the current hook. In the
FORWARD hook two maches should be used if both interfaces have to be checked.

Revision 0 lets older userspace programs use the match as earlier.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/netfilter_ipv4/ipt_addrtype.h |   16 ++++-
 net/ipv4/netfilter/ipt_addrtype.c           |  118 +++++++++++++++++++++++----
 2 files changed, 115 insertions(+), 19 deletions(-)

diff --git a/include/linux/netfilter_ipv4/ipt_addrtype.h b/include/linux/netfilter_ipv4/ipt_addrtype.h
index 166ed01..83062a0 100644
--- a/include/linux/netfilter_ipv4/ipt_addrtype.h
+++ b/include/linux/netfilter_ipv4/ipt_addrtype.h
@@ -1,7 +1,21 @@
 #ifndef _IPT_ADDRTYPE_H
 #define _IPT_ADDRTYPE_H
 
-struct ipt_addrtype_info {
+enum
+{
+	IPT_ADDRTYPE_INVERT_SOURCE	= 0x0001,
+	IPT_ADDRTYPE_INVERT_DEST	= 0x0002,
+	IPT_ADDRTYPE_LIMIT_IFACE_IN	= 0x0004,
+	IPT_ADDRTYPE_LIMIT_IFACE_OUT	= 0x0008,
+};
+
+struct ipt_addrtype_info_v1 {
+	u_int16_t	source;		/* source-type mask */
+	u_int16_t	dest;		/* dest-type mask */
+	u_int32_t	flags;
+};
+
+struct ipt_addrtype_info_v0 {
 	u_int16_t	source;		/* source-type mask */
 	u_int16_t	dest;		/* dest-type mask */
 	u_int32_t	invert_source;
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index 59f01f7..7e6e923 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -22,44 +22,126 @@ MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
 MODULE_DESCRIPTION("iptables addrtype match");
 
-static inline bool match_type(__be32 addr, u_int16_t mask)
+static inline bool match_type(__be32 addr,
+			      const struct net_device *in,
+			      u_int16_t mask)
 {
-	return !!(mask & (1 << inet_addr_type(addr)));
+	return !!(mask & (1 << inet_dev_addr_type(addr, in)));
 }
 
-static bool match(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)
+static bool addrtype_match_v0(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 ipt_addrtype_info *info = matchinfo;
+	const struct ipt_addrtype_info_v0 *info = matchinfo;
 	const struct iphdr *iph = ip_hdr(skb);
 	bool ret = true;
 
 	if (info->source)
-		ret &= match_type(iph->saddr, info->source)^info->invert_source;
-	if (info->dest)
-		ret &= match_type(iph->daddr, info->dest)^info->invert_dest;
+		ret &= match_type(iph->saddr, NULL, info->source)^info->invert_source;
+	if (ret && info->dest)
+		ret &= match_type(iph->daddr, NULL, info->dest)^info->invert_dest;
 
 	return ret;
 }
 
-static struct xt_match addrtype_match __read_mostly = {
-	.name		= "addrtype",
-	.family		= AF_INET,
-	.match		= match,
-	.matchsize	= sizeof(struct ipt_addrtype_info),
-	.me		= THIS_MODULE
+static bool addrtype_match_v1(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 ipt_addrtype_info_v1 *info = matchinfo;
+	const struct iphdr *iph = ip_hdr(skb);
+	const struct net_device *limit_dev = NULL;
+	bool ret = true;
+
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN)
+		limit_dev = in;
+	else if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT)
+		limit_dev = out;
+
+
+	if (info->source)
+		ret &= match_type(iph->saddr, limit_dev, info->source) ^
+			(info->flags & IPT_ADDRTYPE_INVERT_SOURCE);
+	if (ret && info->dest)
+		ret &= match_type(iph->daddr, limit_dev, info->dest) ^
+			(info->flags & IPT_ADDRTYPE_INVERT_DEST);
+
+	return ret;
+}
+
+static bool addrtype_checkentry_v1(const char *tablename,
+				   const void *ip_void,
+				   const struct xt_match *match,
+				   void *matchinfo,
+				   unsigned int hook_mask)
+{
+	struct ipt_addrtype_info_v1 *info = matchinfo;
+
+	if (info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN &&
+	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printk(KERN_ERR "ipt_addrtype: cannot be both incoming and "
+				"outgoing interface limitation selected\n");
+		return false;
+	}
+
+	if (hook_mask & (1 << NF_INET_PRE_ROUTING | 1 << NF_INET_LOCAL_IN) &&
+	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_OUT) {
+		printk(KERN_ERR "ipt_addrtype: output interface limitation "
+				"not valid in PRE_ROUTING and INPUT\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_INET_POST_ROUTING | 1 << NF_INET_LOCAL_OUT) &&
+	    info->flags & IPT_ADDRTYPE_LIMIT_IFACE_IN) {
+		printk(KERN_ERR "ipt_addrtype: input interface limitation "
+				"not valid in POST_ROUTING and OUTPUT\n");
+		return false;
+	}
+	return true;
+}
+
+
+
+static struct xt_match addrtype_match[] __read_mostly = {
+	{
+		.name		= "addrtype",
+		.family		= AF_INET,
+		.revision	= 0,
+		.match		= addrtype_match_v0,
+		.matchsize	= sizeof(struct ipt_addrtype_info_v0),
+		.me		= THIS_MODULE
+	},
+	{
+		.name		= "addrtype",
+		.family		= AF_INET,
+		.revision	= 1,
+		.match		= addrtype_match_v1,
+		.checkentry	= addrtype_checkentry_v1,
+		.matchsize	= sizeof(struct ipt_addrtype_info_v1),
+		.me		= THIS_MODULE
+	}
 };
 
 static int __init ipt_addrtype_init(void)
 {
-	return xt_register_match(&addrtype_match);
+	return xt_register_matches(addrtype_match,
+			ARRAY_SIZE(addrtype_match));
 }
 
 static void __exit ipt_addrtype_fini(void)
 {
-	xt_unregister_match(&addrtype_match);
+	xt_unregister_matches(addrtype_match,
+			ARRAY_SIZE(addrtype_match));
 }
 
 module_init(ipt_addrtype_init);
-- 
1.5.2.5


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

* Re: [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-16 14:22     ` [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
@ 2007-11-16 15:06       ` Jan Engelhardt
  2007-11-16 15:30         ` Laszlo Attila Toth
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Engelhardt @ 2007-11-16 15:06 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: kaber, netfilter-devel


On Nov 16 2007 15:22, Laszlo Attila Toth wrote:
>Addrtype match has a new revision (1), which lets address type checking
>limited to the interface the current packet belongs to. Either incoming
>or outgoing interface can be used depending on the current hook. In the
>FORWARD hook two maches should be used if both interfaces have to be checked.

Hey would not it be cool if this was bumped to xt_addrtype,
using .revision=0 with ipt_addrtype_info (with the old functionality),
and let .revision=1 use xt_addrtype_info (with the new functionality).
Much like the recently posted xt_tos/xt_owner.

>-struct ipt_addrtype_info {
>+enum
>+{
>+	IPT_ADDRTYPE_INVERT_SOURCE	= 0x0001,
>+	IPT_ADDRTYPE_INVERT_DEST	= 0x0002,
>+	IPT_ADDRTYPE_LIMIT_IFACE_IN	= 0x0004,
>+	IPT_ADDRTYPE_LIMIT_IFACE_OUT	= 0x0008,
>+};
>+
>+struct ipt_addrtype_info_v1 {
>+	u_int16_t	source;		/* source-type mask */
>+	u_int16_t	dest;		/* dest-type mask */
>+	u_int32_t	flags;
>+};
>+
>+struct ipt_addrtype_info_v0 {

Is it actually ok to change ipt_addrtype_info into ipt_addrtype_info_v0?
It does not break binary compat, but source-level compat.


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

* Re: [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-16 15:06       ` Jan Engelhardt
@ 2007-11-16 15:30         ` Laszlo Attila Toth
  2007-11-16 16:49           ` Jan Engelhardt
  0 siblings, 1 reply; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-16 15:30 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: kaber, netfilter-devel

Jan Engelhardt írta:
> On Nov 16 2007 15:22, Laszlo Attila Toth wrote:
>> Addrtype match has a new revision (1), which lets address type checking
>> limited to the interface the current packet belongs to. Either incoming
>> or outgoing interface can be used depending on the current hook. In the
>> FORWARD hook two maches should be used if both interfaces have to be checked.
> 
> Hey would not it be cool if this was bumped to xt_addrtype,
> using .revision=0 with ipt_addrtype_info (with the old functionality),
> and let .revision=1 use xt_addrtype_info (with the new functionality).
> Much like the recently posted xt_tos/xt_owner.

xt_addrtype is ok, but the module loading in the userspace part 
(iptables) tries to load the libxt_addrtype.so first and only if it is 
not succeeded try to load libipt_addrtype.so also the latter shared 
object will never be loaded.

Also it may be better if only the xt_addrtype remains and 
ipt_addrtype_info is used for the old one and xt_addrtype_info for the 
new one. But it may be confusing: ipt_* in the xt_* files...

> 
>> -struct ipt_addrtype_info {
>> +enum
>> +{
>> +	IPT_ADDRTYPE_INVERT_SOURCE	= 0x0001,
>> +	IPT_ADDRTYPE_INVERT_DEST	= 0x0002,
>> +	IPT_ADDRTYPE_LIMIT_IFACE_IN	= 0x0004,
>> +	IPT_ADDRTYPE_LIMIT_IFACE_OUT	= 0x0008,
>> +};
>> +
>> +struct ipt_addrtype_info_v1 {
>> +	u_int16_t	source;		/* source-type mask */
>> +	u_int16_t	dest;		/* dest-type mask */
>> +	u_int32_t	flags;
>> +};
>> +
>> +struct ipt_addrtype_info_v0 {
> 
> Is it actually ok to change ipt_addrtype_info into ipt_addrtype_info_v0?
> It does not break binary compat, but source-level compat.
> 
> 

Hm, you are right. I checked this in xt_MARK, it doesn't use the _v0 
suffix for the old _info structure. I'll change this in addrtype.

--
Attila
-
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-16 15:30         ` Laszlo Attila Toth
@ 2007-11-16 16:49           ` Jan Engelhardt
  2007-11-16 17:19             ` Laszlo Attila Toth
  0 siblings, 1 reply; 10+ messages in thread
From: Jan Engelhardt @ 2007-11-16 16:49 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: kaber, netfilter-devel


On Nov 16 2007 16:30, Laszlo Attila Toth wrote:
>
> xt_addrtype is ok, but the module loading in the userspace part (iptables)
> tries to load the libxt_addrtype.so first

Well that should not be a problem if iptables 1.4.x only has libxt_addrtype.

> and only if it is not succeeded try to load libipt_addrtype.so also the
> latter shared object will never be loaded.
>
> Also it may be better if only the xt_addrtype remains and ipt_addrtype_info is
> used for the old one and xt_addrtype_info for the new one. But it may be
> confusing: ipt_* in the xt_* files...

Will be fixed 'one day' when all the compat code is removed :p


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

* Re: [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-16 16:49           ` Jan Engelhardt
@ 2007-11-16 17:19             ` Laszlo Attila Toth
  2007-11-16 17:53               ` Jan Engelhardt
  0 siblings, 1 reply; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-11-16 17:19 UTC (permalink / raw)
  To: Jan Engelhardt; +Cc: kaber, netfilter-devel

Jan Engelhardt wrote:
> On Nov 16 2007 16:30, Laszlo Attila Toth wrote:
>> Also it may be better if only the xt_addrtype remains and ipt_addrtype_info is
>> used for the old one and xt_addrtype_info for the new one. But it may be
>> confusing: ipt_* in the xt_* files...
> 
> Will be fixed 'one day' when all the compat code is removed :p

Not 'one': 'Mon' (Monday) :P

-- 
Panther

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

* Re: [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface
  2007-11-16 17:19             ` Laszlo Attila Toth
@ 2007-11-16 17:53               ` Jan Engelhardt
  0 siblings, 0 replies; 10+ messages in thread
From: Jan Engelhardt @ 2007-11-16 17:53 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: kaber, netfilter-devel


On Nov 16 2007 18:19, Laszlo Attila Toth wrote:
> Jan Engelhardt wrote:
>> On Nov 16 2007 16:30, Laszlo Attila Toth wrote:
>> > Also it may be better if only the xt_addrtype remains and ipt_addrtype_info
>> > is
>> > used for the old one and xt_addrtype_info for the new one. But it may be
>> > confusing: ipt_* in the xt_* files...
>> 
>> Will be fixed 'one day' when all the compat code is removed :p
>
> Not 'one': 'Mon' (Monday) :P

What, there's a flag day for netfilter?

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

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

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-15 17:14 [PATCHv3 0/2+1] Find address type on the packet's interface Laszlo Attila Toth
2007-11-15 17:14 ` [PATCHv3 1/2] Find address type on a specific or on any interface Laszlo Attila Toth
2007-11-15 17:14   ` [PATCHv3 2/2] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
2007-11-15 17:14     ` [PATCHv3 iptables] Find address type on a specific or on any interface Laszlo Attila Toth
2007-11-16 14:22     ` [PATCHv3 2/2][RESEND] Addrtype match extension: limit addrtype check on the packet's interface Laszlo Attila Toth
2007-11-16 15:06       ` Jan Engelhardt
2007-11-16 15:30         ` Laszlo Attila Toth
2007-11-16 16:49           ` Jan Engelhardt
2007-11-16 17:19             ` Laszlo Attila Toth
2007-11-16 17:53               ` 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.