netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/2] Interface group: core (netlink) part
       [not found]   ` <1824b3d462b1d85aaf33941cf082c4e018d5bff7.1192460167.git.panther@balabit.hu>
@ 2007-10-16  8:01     ` Laszlo Attila Toth
  2007-10-16  8:34       ` Patrick McHardy
  2007-10-16  8:01     ` Laszlo Attila Toth
  1 sibling, 1 reply; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-16  8:01 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

 Interface groups let handle different interfaces with one (netfilter) rule.
 Modified net device structure and netlink interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h   |    2 ++
 include/linux/netdevice.h |    2 ++
 net/core/rtnetlink.c      |    8 ++++++++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..4cfc697 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
 	/* Interface index. Unique device identifier	*/
 	int			ifindex;
 	int			iflink;
+	/* interface group this interface belongs to */
+	int			ifgroup;
 
 
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..18ff3c5 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -646,6 +646,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 	if (dev->master)
 		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
 
+	if (dev->ifgroup)
+		NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
 	if (dev->qdisc_sleeping)
 		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
 
@@ -846,6 +849,11 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		write_unlock_bh(&dev_base_lock);
 	}
 
+	if (tb[IFLA_IFGROUP]) {
+		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP ]);
+		rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
+	}
+
 	err = 0;
 
 errout:
-- 
1.5.2.5


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

* [PATCH 1/2] Interface group: core (netlink) part
       [not found]   ` <1824b3d462b1d85aaf33941cf082c4e018d5bff7.1192460167.git.panther@balabit.hu>
  2007-10-16  8:01     ` [PATCH 1/2] Interface group: core (netlink) part Laszlo Attila Toth
@ 2007-10-16  8:01     ` Laszlo Attila Toth
  1 sibling, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-16  8:01 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

 Interface groups let handle different interfaces with one (netfilter) rule.
 Modified net device structure and netlink interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h   |    2 ++
 include/linux/netdevice.h |    2 ++
 net/core/rtnetlink.c      |    8 ++++++++
 3 files changed, 12 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..4cfc697 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
 	/* Interface index. Unique device identifier	*/
 	int			ifindex;
 	int			iflink;
+	/* interface group this interface belongs to */
+	int			ifgroup;
 
 
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..18ff3c5 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -646,6 +646,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 	if (dev->master)
 		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
 
+	if (dev->ifgroup)
+		NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
 	if (dev->qdisc_sleeping)
 		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
 
@@ -846,6 +849,11 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		write_unlock_bh(&dev_base_lock);
 	}
 
+	if (tb[IFLA_IFGROUP]) {
+		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP ]);
+		rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
+	}
+
 	err = 0;
 
 errout:
-- 
1.5.2.5


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

* Re: [PATCH 1/2] Interface group: core (netlink) part
  2007-10-16  8:01     ` [PATCH 1/2] Interface group: core (netlink) part Laszlo Attila Toth
@ 2007-10-16  8:34       ` Patrick McHardy
  0 siblings, 0 replies; 22+ messages in thread
From: Patrick McHardy @ 2007-10-16  8:34 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel

Laszlo Attila Toth wrote:
> diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
> index 4756d58..18ff3c5 100644
> --- a/net/core/rtnetlink.c
> +++ b/net/core/rtnetlink.c
> @@ -646,6 +646,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
>  	if (dev->master)
>  		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
>  
> +	if (dev->ifgroup)
> +		NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
> +

You need to adjust if_nlmsg_size() to account for this.

>  	if (dev->qdisc_sleeping)
>  		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
>  
> @@ -846,6 +849,11 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
>  		write_unlock_bh(&dev_base_lock);
>  	}
>  
> +	if (tb[IFLA_IFGROUP]) {
> +		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP ]);
> +		rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
> +	}


Notifcations should be atomic, not one for every single change. I know
thats not the case currently, but it seems we're missing a notifcation
for some of the attributes anyway (like tx_queue_len, operstate,
linkmode), please consolidate all these and send a single notifcation.

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

* [PATCH 0/2] Interface groups, round two
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
@ 2007-10-18 10:13 ` Laszlo Attila Toth
       [not found] ` <4e88bea1c0065fada9181e9b668a91c6c3fd8796.1192695706.git.panther@balabit.hu>
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:13 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Hello,

Here is the new version of ifgroup patches.

The interface group value is u_int32_t in net_device which should be enough.
Previously it was an int.

Usage:
   ip link set eth0 group 4
but currently it cannot be unset, only changed to another value.

In /etc/iproute2/rt_ifgroup each value may have a symbolic name.

Netfilter part: xt_ifgroup module for both IPv4 and IPv6. Iptables usage:
   iptables -A INPUT -m ifgroup --in-ifgroup 4/0xf -j ACCEPT
   iptables -A FORWARD -m ifgroup --in-ifgroup 4 --out-ifgroup 5 -j ACCEPT
   ...

in the FORWARD chain both input and output interface group value should be matched
(with optional masks).

The following patches are:
  kernel: core part
  kernel: netfilter module, ifgroup match
  iproute2: showing and set ifgroup value
  iptables: ifgroup match
--
Laszlo Attila Toth

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

* [PATCH 1/2] Interface group: core (netlink) part
       [not found] ` <4e88bea1c0065fada9181e9b668a91c6c3fd8796.1192695706.git.panther@balabit.hu>
@ 2007-10-18 10:13   ` Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
  2 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:13 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interface groups let handle different interfaces together
especially in netfilter modules.
Modified net device structure and netlink interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h   |    2 ++
 include/linux/netdevice.h |    2 ++
 net/core/rtnetlink.c      |   10 ++++++++++
 3 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..c489a20 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
 	/* Interface index. Unique device identifier	*/
 	int			ifindex;
 	int			iflink;
+	/* interface group this interface belongs to */
+	u_int32_t		ifgroup;
 
 
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..bbe4a98 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -608,6 +608,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
 	       + nla_total_size(4) /* IFLA_MTU */
 	       + nla_total_size(4) /* IFLA_LINK */
 	       + nla_total_size(4) /* IFLA_MASTER */
+	       + nla_total_size(4) /* IFLA_IFGROUP */
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
 	       + nla_total_size(1) /* IFLA_LINKMODE */
 	       + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
@@ -646,6 +647,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 	if (dev->master)
 		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
 
+	if (dev->ifgroup)
+		NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
 	if (dev->qdisc_sleeping)
 		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
 
@@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		write_unlock_bh(&dev_base_lock);
 	}
 
+	if (tb[IFLA_IFGROUP]) {
+		write_lock_bh(&dev_base_lock);
+		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+		write_unlock_bh(&dev_base_lock);
+	}
+
 	err = 0;
 
 errout:
-- 
1.5.2.5


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

* [PATCH 2/2] Interface group match
       [not found] ` <7336085b0c4f969c323966058b20836a331b65a1.1192695707.git.panther@balabit.hu>
@ 2007-10-18 10:13   ` Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
  2 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:13 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interface group values can be checked on both input and output interfaces.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/netfilter/xt_ifgroup.h |   18 ++++++
 net/netfilter/Kconfig                |   16 +++++
 net/netfilter/Makefile               |    1 +
 net/netfilter/xt_ifgroup.c           |  108 ++++++++++++++++++++++++++++++++++
 4 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN	0x01
+#define XT_IFGROUP_INVERT_OUT	0x02
+#define XT_IFGROUP_MATCH_IN	0x04
+#define XT_IFGROUP_MATCH_OUT	0x08		
+
+struct xt_ifgroup_info {
+	u_int32_t in_group;
+	u_int32_t in_mask;
+	u_int32_t out_group;
+	u_int32_t out_mask;
+	u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3599770..0864e19 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
 	  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_IFGROUP
+	tristate '"ifgroup" interface group match support'
+	depends on NETFILTER_XTABLES
+	help
+	  Interface group matching allows you to match a packet by
+	  its incoming interface "group", settable using ip link set
+	  group
+
+	  Typical usage is to assign dynamic interfaces to a group
+	  when they come up using "ip link set group" and then match
+	  incoming packets with a rule like this:
+
+	    iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_REALM
 	tristate  '"realm" match support'
 	depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0c054bf..da9ab07 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
new file mode 100644
index 0000000..07c3acc
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,108 @@
+/*
+ * An x_tables match module to match interface groups
+ *
+ * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
+ *   Laszlo Attila Toth <panther@balabit.hu>
+ *
+ * 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/if_ether.h>
+#include <linux/if_packet.h>
+
+#include <linux/netfilter/xt_ifgroup.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
+MODULE_DESCRIPTION("Xtables interface group matching module");
+MODULE_ALIAS("ipt_ifgroup");
+MODULE_ALIAS("ip6t_ifgroup");
+
+static bool ifgroup_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)
+{
+#define FLAG_IS_SET(a,b)  ((a & b) == b)
+#define MATCH_IN  (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
+#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))
+
+	const struct xt_ifgroup_info *info = matchinfo;
+	bool verdict = false;
+	
+	if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
+		verdict = MATCH_IN && MATCH_OUT;
+	else if (info->flags & XT_IFGROUP_MATCH_IN)
+		verdict = MATCH_IN;
+	else if (info->flags & XT_IFGROUP_MATCH_OUT)
+		verdict = MATCH_OUT;
+	return verdict;
+}
+
+static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
+			       const struct xt_match *match,
+			       void *matchinfo, unsigned int hook_mask)
+{
+	struct xt_ifgroup_info *info = matchinfo;
+
+	if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
+		printk(KERN_ERR "xt_ifgroup: neither incoming nor "
+				"outgoing device selected\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+	    && info->flags & XT_IFGROUP_MATCH_OUT) {
+		printk(KERN_ERR "xt_ifgroup: output device not valid in "
+				"PRE_ROUTING and INPUT\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+	    && info->flags & XT_IFGROUP_MATCH_IN) {
+		printk(KERN_ERR "xt_ifgroup: input device not valid in "
+				"POST_ROUTING and OUTPUT\n");
+		return false;
+	}
+	return true;
+}
+
+static struct xt_match xt_ifgroup_match[] __read_mostly  = {
+        {
+		.name		= "ifgroup",
+		.match		= ifgroup_match,
+		.checkentry	= ifgroup_checkentry,
+		.matchsize	= sizeof(struct xt_ifgroup_info),
+		.family		= AF_INET,
+		.me		= THIS_MODULE,
+	
+	},
+	{
+		.name		= "ifgroup",
+		.match		= ifgroup_match,
+		.checkentry	= ifgroup_checkentry,
+		.matchsize	= sizeof(struct xt_ifgroup_info),
+		.family		= AF_INET6,
+		.me		= THIS_MODULE,
+	},
+};
+
+static int __init xt_ifgroup_init(void)
+{
+	return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+static void __exit xt_ifgroup_fini(void)
+{
+	xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+module_init(xt_ifgroup_init);
+module_exit(xt_ifgroup_fini);
-- 
1.5.2.5


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

* [IPROUTE PATCH] Interface group as new ip link option
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
  2007-10-18 10:13 ` [PATCH 0/2] Interface groups, round two Laszlo Attila Toth
       [not found] ` <4e88bea1c0065fada9181e9b668a91c6c3fd8796.1192695706.git.panther@balabit.hu>
@ 2007-10-18 10:13 ` Laszlo Attila Toth
  2007-10-18 10:13 ` [IPTABLES PATCH] Interface group match Laszlo Attila Toth
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:13 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interfaces can be grouped and each group has an unique positive integer ID.
It can be set via ip link. Symbolic names can be specified in
/etc/iproute2/rt_ifgroup.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h |    2 +
 include/rt_names.h      |    2 +
 ip/ipaddress.c          |    4 +++
 ip/iplink.c             |   11 ++++++++
 lib/rt_names.c          |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/ip.8           |    5 ++++
 6 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 23b3a8e..2dfb0b7 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define	IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/rt_names.h b/include/rt_names.h
index 07a10e0..72c5247 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -8,11 +8,13 @@ char* rtnl_rtscope_n2a(int id, char *buf, int len);
 char* rtnl_rttable_n2a(__u32 id, char *buf, int len);
 char* rtnl_rtrealm_n2a(int id, char *buf, int len);
 char* rtnl_dsfield_n2a(int id, char *buf, int len);
+char* rtnl_ifgroup_n2a(int id, char *buf, int len);
 int rtnl_rtprot_a2n(__u32 *id, char *arg);
 int rtnl_rtscope_a2n(__u32 *id, char *arg);
 int rtnl_rttable_a2n(__u32 *id, char *arg);
 int rtnl_rtrealm_a2n(__u32 *id, char *arg);
 int rtnl_dsfield_a2n(__u32 *id, char *arg);
+int rtnl_ifgroup_a2n(__u32 *id, char *arg);
 
 const char *inet_proto_n2a(int proto, char *buf, int len);
 int inet_proto_a2n(char *buf);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 518d8cd..405e85c 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -227,6 +227,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
 		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
 	if (tb[IFLA_QDISC])
 		fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
+	if (tb[IFLA_IFGROUP]) {
+		SPRINT_BUF(b1);
+		fprintf(fp, "group %s ", rtnl_ifgroup_n2a(*(int*)RTA_DATA(tb[IFLA_IFGROUP]), b1, sizeof(b1)));
+	}
 #ifdef IFLA_MASTER
 	if (tb[IFLA_MASTER]) {
 		SPRINT_BUF(b1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 4060845..bebb2fe 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <linux/sockios.h>
+#include <linux/rtnetlink.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -46,6 +47,7 @@ void iplink_usage(void)
 	fprintf(stderr, "	                     promisc { on | off } |\n");
 	fprintf(stderr, "	                     trailers { on | off } |\n");
 	fprintf(stderr, "	                     txqueuelen PACKETS |\n");
+	fprintf(stderr, "	                     group GROUP |\n");
 	fprintf(stderr, "	                     name NEWNAME |\n");
 	fprintf(stderr, "	                     address LLADDR | broadcast LLADDR |\n");
 	fprintf(stderr, "	                     mtu MTU }\n");
@@ -145,6 +147,7 @@ static int iplink_have_newlink(void)
 static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 {
 	int qlen = -1;
+	__u32 group = 0;
 	int mtu = -1;
 	int len;
 	char abuf[32];
@@ -197,6 +200,14 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 			if (get_integer(&qlen,  *argv, 0))
 				invarg("Invalid \"txqueuelen\" value\n", *argv);
 			addattr_l(&req.n, sizeof(req), IFLA_TXQLEN, &qlen, 4);
+		} else if (matches(*argv, "group") == 0) {
+			NEXT_ARG();
+			if (group != 0)
+				duparg("group", *argv);
+
+			if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
+				invarg("\"group\" value is invalid\n", *argv);
+			addattr_l(&req.n, sizeof(req), IFLA_IFGROUP, &group, sizeof(group));
 		} else if (strcmp(*argv, "mtu") == 0) {
 			NEXT_ARG();
 			if (mtu != -1)
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 8d019a0..a067e74 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -446,3 +446,65 @@ int rtnl_dsfield_a2n(__u32 *id, char *arg)
 	return 0;
 }
 
+static char * rtnl_rtifgroup_tab[256] = {
+	"0",
+};
+
+static int rtnl_rtifgroup_init;
+
+static void rtnl_rtifgroup_initialize(void)
+{
+	rtnl_rtifgroup_init = 1;
+	rtnl_tab_initialize("/etc/iproute2/rt_ifgroup",
+			    rtnl_rtifgroup_tab, 256);
+}
+
+char * rtnl_ifgroup_n2a(int id, char *buf, int len)
+{
+	if (id<0 || id>=256) {
+		snprintf(buf, len, "%d", id);
+		return buf;
+	}
+	if (!rtnl_rtifgroup_tab[id]) {
+		if (!rtnl_rtifgroup_init)
+			rtnl_rtifgroup_initialize();
+	}
+	if (rtnl_rtifgroup_tab[id])
+		return rtnl_rtifgroup_tab[id];
+	snprintf(buf, len, "0x%02x", id);
+	return buf;
+}
+
+
+int rtnl_ifgroup_a2n(__u32 *id, char *arg)
+{
+	static char *cache = NULL;
+	static unsigned long res;
+	char *end;
+	int i;
+
+	if (cache && strcmp(cache, arg) == 0) {
+		*id = res;
+		return 0;
+	}
+
+	if (!rtnl_rtifgroup_init)
+		rtnl_rtifgroup_initialize();
+
+	for (i=0; i<256; i++) {
+		if (rtnl_rtifgroup_tab[i] &&
+		    strcmp(rtnl_rtifgroup_tab[i], arg) == 0) {
+			cache = rtnl_rtifgroup_tab[i];
+			res = i;
+			*id = res;
+			return 0;
+		}
+	}
+
+	res = strtoul(arg, &end, 16);
+	if (!end || end == arg || *end || res > 255)
+		return -1;
+	*id = res;
+	return 0;
+}
+
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index a9132da..92bc59e 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -506,6 +506,11 @@ already configured.
 change the transmit queue length of the device.
 
 .TP
+.BI group " GROUP"
+.TP 
+change the interface group identifier of the device.
+
+.TP
 .BI mtu " NUMBER"
 change the 
 .I MTU
-- 
1.5.2.5


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

* [IPTABLES PATCH] Interface group match
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
                   ` (2 preceding siblings ...)
  2007-10-18 10:13 ` [IPROUTE PATCH] Interface group as new ip link option Laszlo Attila Toth
@ 2007-10-18 10:13 ` Laszlo Attila Toth
  2007-10-18 10:15 ` [PATCH 0/2] Interface groups, round two Laszlo Attila Toth
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:13 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Matching ifgroup value of incoming and/or outgoing interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 extensions/Makefile                  |    2 +-
 extensions/libip6t_ifgroup.man       |   36 +++++++
 extensions/libipt_ifgroup.man        |   36 +++++++
 extensions/libxt_ifgroup.c           |  178 ++++++++++++++++++++++++++++++++++
 include/linux/netfilter/xt_ifgroup.h |   18 ++++
 5 files changed, 269 insertions(+), 1 deletions(-)

diff --git a/extensions/Makefile b/extensions/Makefile
index 5af234e..938cf0b 100644
--- a/extensions/Makefile
+++ b/extensions/Makefile
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper ifgroup length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
diff --git a/extensions/libip6t_ifgroup.man b/extensions/libip6t_ifgroup.man
new file mode 100644
index 0000000..a96ec91
--- /dev/null
+++ b/extensions/libip6t_ifgroup.man
@@ -0,0 +1,36 @@
+Maches packets on an interface if it is in the same interface group
+as specified by the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter. If a mask is also specified, the masked value of
+the inteface's group must be equal to the given value of the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter to match. This match is available in all tables.
+.TP
+.BR "--in-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of input interface and the optional mask.
+Valid only in the in the
+.B PREROUTING
+and
+.B INPUT
+and
+.B FORWARD
+chains, and user-defined chains which are only called from those
+chains. 
+.TP
+.BR "--out-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of out interface and the optional mask.
+Valid only in the in the
+.B FORWARD
+and
+.B OUTPUT
+and
+.B POSTROUTING
+chains, and user-defined chains which are only called from those
+chains. 
+.RS
+.PP
+
diff --git a/extensions/libipt_ifgroup.man b/extensions/libipt_ifgroup.man
new file mode 100644
index 0000000..a96ec91
--- /dev/null
+++ b/extensions/libipt_ifgroup.man
@@ -0,0 +1,36 @@
+Maches packets on an interface if it is in the same interface group
+as specified by the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter. If a mask is also specified, the masked value of
+the inteface's group must be equal to the given value of the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter to match. This match is available in all tables.
+.TP
+.BR "--in-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of input interface and the optional mask.
+Valid only in the in the
+.B PREROUTING
+and
+.B INPUT
+and
+.B FORWARD
+chains, and user-defined chains which are only called from those
+chains. 
+.TP
+.BR "--out-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of out interface and the optional mask.
+Valid only in the in the
+.B FORWARD
+and
+.B OUTPUT
+and
+.B POSTROUTING
+chains, and user-defined chains which are only called from those
+chains. 
+.RS
+.PP
+
diff --git a/extensions/libxt_ifgroup.c b/extensions/libxt_ifgroup.c
new file mode 100644
index 0000000..d7f982c
--- /dev/null
+++ b/extensions/libxt_ifgroup.c
@@ -0,0 +1,178 @@
+/* 
+ * Shared library add-on to iptables to match 
+ * packets by the incoming interface group.
+ *
+ * Balazs Scheidler <bazsi@balabit.hu>
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <linux/netfilter/xt_ifgroup.h>
+
+static void
+ifgroup_help(void)
+{
+	printf(
+"ifgroup v%s options:\n"
+"  --in-ifgroup  [!] group[/mask]  incoming interface group and its mask\n"
+"  --out-ifgroup [!] group[/mask]  outgoing interface group and its mask\n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{"in-ifgroup", 1, 0, '1'},
+	{"out-ifgroup", 1, 0, '2'},
+	{ }
+};
+
+#define PARAM_MATCH_IN   0x01
+#define PARAM_MATCH_OUT  0x02
+
+static int
+ifgroup_parse(int c, char **argv, int invert, unsigned int *flags,
+      const void *entry, struct xt_entry_match **match)
+{
+	struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) (*match)->data;
+	char *end;
+	
+	switch (c)
+	{
+		case '1':
+			if (*flags & PARAM_MATCH_IN)
+				exit_error(PARAMETER_PROBLEM,
+					  "ifgroup match: Can't specify --in-ifgroup twice");
+											         
+			check_inverse(optarg, &invert, &optind, 0);
+			
+			info->in_group = strtoul(optarg, &end, 0);
+			info->in_mask = 0xffffffffUL;
+			
+			if (*end == '/')
+				info->in_mask = strtoul(end+1, &end, 0);
+
+			if (*end != '\0' || end == optarg)
+				exit_error(PARAMETER_PROBLEM, "ifgroup match: Bad ifgroup value `%s'", optarg);
+			
+			if (invert)
+				info->flags |= XT_IFGROUP_INVERT_IN;
+
+			*flags |= PARAM_MATCH_IN;
+			info->flags |= XT_IFGROUP_MATCH_IN;			
+			break;
+		case '2':
+			if (*flags & PARAM_MATCH_OUT)
+				exit_error(PARAMETER_PROBLEM,
+					  "ifgroup match: Can't specify --out-ifgroup twice");
+											         
+			check_inverse(optarg, &invert, &optind, 0);
+			
+			info->out_group = strtoul(optarg, &end, 0);
+			info->out_mask = 0xffffffffUL;
+			
+			if (*end == '/')
+				info->out_mask = strtoul(end+1, &end, 0);
+
+			if (*end != '\0' || end == optarg)
+				exit_error(PARAMETER_PROBLEM, "ifgroup match: Bad ifgroup value `%s'", optarg);
+			
+			if (invert)
+				info->flags |= XT_IFGROUP_INVERT_OUT;
+
+			*flags |= PARAM_MATCH_OUT;
+			info->flags |= XT_IFGROUP_MATCH_OUT;			
+			break;
+		default: 
+			return 0;
+	}
+
+	return 1;
+}
+
+static void
+ifgroup_final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, "You must specify `--in-ifgroup' or `--out-ifgroup'");
+}
+
+static void
+ifgroup_print_value_in(struct xt_ifgroup_info *info)
+{
+	printf("0x%x/0x%x ", info->in_group, info->in_mask);
+}
+
+static void
+ifgroup_print_value_out(struct xt_ifgroup_info *info)
+{
+	printf("0x%x/0x%x ", info->out_group, info->out_mask);
+}
+
+static void
+ifgroup_print(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+	struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) match->data;
+	
+	printf("ifgroup ");
+	
+	if (info->flags & XT_IFGROUP_MATCH_IN) {
+		printf("in %s", info->flags & XT_IFGROUP_INVERT_IN ? "! " : "");
+		ifgroup_print_value_in(info);
+	}
+	if (info->flags & XT_IFGROUP_MATCH_OUT) {
+		printf("out %s", info->flags & XT_IFGROUP_INVERT_OUT ? "! " : "");
+		ifgroup_print_value_out(info);
+	}
+}
+
+static void
+ifgroup_save(const void *ip, const struct xt_entry_match *match)
+{
+	struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) match->data;
+	
+	if (info->flags & XT_IFGROUP_MATCH_IN) {
+		printf("--in-ifgroup %s", info->flags & XT_IFGROUP_INVERT_IN ? "! " : "");
+		ifgroup_print_value_in(info);
+	}
+	if (info->flags & XT_IFGROUP_MATCH_OUT) {
+		printf("--out-ifgroup %s", info->flags & XT_IFGROUP_INVERT_OUT ? "! " : "");
+		ifgroup_print_value_out(info);
+	}
+}
+
+static struct xtables_match ifgroup_match = {
+	.family		= AF_INET,
+	.name		= "ifgroup",
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.help		= ifgroup_help,
+	.parse		= ifgroup_parse, 
+	.final_check	= ifgroup_final_check, 
+	.print		= ifgroup_print,
+	.save		= ifgroup_save, 
+	.extra_opts	= opts
+};
+
+static struct xtables_match ifgroup_match6 = {
+	.family		= AF_INET6,
+	.name		= "ifgroup",
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.help		= ifgroup_help,
+	.parse		= ifgroup_parse, 
+	.final_check	= ifgroup_final_check, 
+	.print		= ifgroup_print,
+	.save		= ifgroup_save, 
+	.extra_opts	= opts
+};
+
+void _init(void)
+{
+	xtables_register_match(&ifgroup_match);
+	xtables_register_match(&ifgroup_match6);
+}
+
diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN	0x01
+#define XT_IFGROUP_INVERT_OUT	0x02
+#define XT_IFGROUP_MATCH_IN	0x04
+#define XT_IFGROUP_MATCH_OUT	0x08		
+
+struct xt_ifgroup_info {
+	u_int32_t in_group;
+	u_int32_t in_mask;
+	u_int32_t out_group;
+	u_int32_t out_mask;
+	u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
-- 
1.5.2.5


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

* [PATCH 0/2] Interface groups, round two
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
                   ` (4 preceding siblings ...)
  2007-10-18 10:15 ` [PATCH 0/2] Interface groups, round two Laszlo Attila Toth
@ 2007-10-18 10:15 ` Laszlo Attila Toth
  2007-10-18 10:20   ` Patrick McHardy
       [not found] ` <7336085b0c4f969c323966058b20836a331b65a1.1192695707.git.panther@balabit.hu>
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Hello,

Here is the new version of ifgroup patches.

The interface group value is u_int32_t in net_device which should be enough.
Previously it was an int.

Usage:
   ip link set eth0 group 4
but currently it cannot be unset, only changed to another value.

In /etc/iproute2/rt_ifgroup each value may have a symbolic name.

Netfilter part: xt_ifgroup module for both IPv4 and IPv6. Iptables usage:
   iptables -A INPUT -m ifgroup --in-ifgroup 4/0xf -j ACCEPT
   iptables -A FORWARD -m ifgroup --in-ifgroup 4 --out-ifgroup 5 -j ACCEPT
   ...

in the FORWARD chain both input and output interface group value should be matched
(with optional masks).

The following patches are:
  kernel: core part
  kernel: netfilter module, ifgroup match
  iproute2: showing and set ifgroup value
  iptables: ifgroup match
--
Laszlo Attila Toth

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

* [PATCH 0/2] Interface groups, round two
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
                   ` (3 preceding siblings ...)
  2007-10-18 10:13 ` [IPTABLES PATCH] Interface group match Laszlo Attila Toth
@ 2007-10-18 10:15 ` Laszlo Attila Toth
  2007-10-18 10:15 ` Laszlo Attila Toth
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Hello,

Here is the new version of ifgroup patches.

The interface group value is u_int32_t in net_device which should be enough.
Previously it was an int.

Usage:
   ip link set eth0 group 4
but currently it cannot be unset, only changed to another value.

In /etc/iproute2/rt_ifgroup each value may have a symbolic name.

Netfilter part: xt_ifgroup module for both IPv4 and IPv6. Iptables usage:
   iptables -A INPUT -m ifgroup --in-ifgroup 4/0xf -j ACCEPT
   iptables -A FORWARD -m ifgroup --in-ifgroup 4 --out-ifgroup 5 -j ACCEPT
   ...

in the FORWARD chain both input and output interface group value should be matched
(with optional masks).

The following patches are:
  kernel: core part
  kernel: netfilter module, ifgroup match
  iproute2: showing and set ifgroup value
  iptables: ifgroup match
--
Laszlo Attila Toth

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

* [PATCH 1/2] Interface group: core (netlink) part
       [not found] ` <4e88bea1c0065fada9181e9b668a91c6c3fd8796.1192695706.git.panther@balabit.hu>
  2007-10-18 10:13   ` [PATCH 1/2] Interface group: core (netlink) part Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
@ 2007-10-18 10:15   ` Laszlo Attila Toth
  2007-10-18 10:22     ` Patrick McHardy
  2 siblings, 1 reply; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interface groups let handle different interfaces together
especially in netfilter modules.
Modified net device structure and netlink interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h   |    2 ++
 include/linux/netdevice.h |    2 ++
 net/core/rtnetlink.c      |   10 ++++++++++
 3 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..c489a20 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
 	/* Interface index. Unique device identifier	*/
 	int			ifindex;
 	int			iflink;
+	/* interface group this interface belongs to */
+	u_int32_t		ifgroup;
 
 
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..bbe4a98 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -608,6 +608,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
 	       + nla_total_size(4) /* IFLA_MTU */
 	       + nla_total_size(4) /* IFLA_LINK */
 	       + nla_total_size(4) /* IFLA_MASTER */
+	       + nla_total_size(4) /* IFLA_IFGROUP */
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
 	       + nla_total_size(1) /* IFLA_LINKMODE */
 	       + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
@@ -646,6 +647,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 	if (dev->master)
 		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
 
+	if (dev->ifgroup)
+		NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
 	if (dev->qdisc_sleeping)
 		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
 
@@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		write_unlock_bh(&dev_base_lock);
 	}
 
+	if (tb[IFLA_IFGROUP]) {
+		write_lock_bh(&dev_base_lock);
+		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+		write_unlock_bh(&dev_base_lock);
+	}
+
 	err = 0;
 
 errout:
-- 
1.5.2.5


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

* [PATCH 1/2] Interface group: core (netlink) part
       [not found] ` <4e88bea1c0065fada9181e9b668a91c6c3fd8796.1192695706.git.panther@balabit.hu>
  2007-10-18 10:13   ` [PATCH 1/2] Interface group: core (netlink) part Laszlo Attila Toth
@ 2007-10-18 10:15   ` Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
  2 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interface groups let handle different interfaces together
especially in netfilter modules.
Modified net device structure and netlink interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h   |    2 ++
 include/linux/netdevice.h |    2 ++
 net/core/rtnetlink.c      |   10 ++++++++++
 3 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 422084d..d9f1726 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e679b27..c489a20 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -365,6 +365,8 @@ struct net_device
 	/* Interface index. Unique device identifier	*/
 	int			ifindex;
 	int			iflink;
+	/* interface group this interface belongs to */
+	u_int32_t		ifgroup;
 
 
 	struct net_device_stats* (*get_stats)(struct net_device *dev);
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..bbe4a98 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -608,6 +608,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
 	       + nla_total_size(4) /* IFLA_MTU */
 	       + nla_total_size(4) /* IFLA_LINK */
 	       + nla_total_size(4) /* IFLA_MASTER */
+	       + nla_total_size(4) /* IFLA_IFGROUP */
 	       + nla_total_size(1) /* IFLA_OPERSTATE */
 	       + nla_total_size(1) /* IFLA_LINKMODE */
 	       + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
@@ -646,6 +647,9 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
 	if (dev->master)
 		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
 
+	if (dev->ifgroup)
+		NLA_PUT_U32(skb, IFLA_IFGROUP, dev->ifgroup);
+
 	if (dev->qdisc_sleeping)
 		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
 
@@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
 		write_unlock_bh(&dev_base_lock);
 	}
 
+	if (tb[IFLA_IFGROUP]) {
+		write_lock_bh(&dev_base_lock);
+		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+		write_unlock_bh(&dev_base_lock);
+	}
+
 	err = 0;
 
 errout:
-- 
1.5.2.5


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

* [PATCH 2/2] Interface group match
       [not found] ` <7336085b0c4f969c323966058b20836a331b65a1.1192695707.git.panther@balabit.hu>
  2007-10-18 10:13   ` [PATCH 2/2] Interface group match Laszlo Attila Toth
@ 2007-10-18 10:15   ` Laszlo Attila Toth
  2007-10-18 10:27     ` Patrick McHardy
  2007-10-18 10:15   ` Laszlo Attila Toth
  2 siblings, 1 reply; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interface group values can be checked on both input and output interfaces.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/netfilter/xt_ifgroup.h |   18 ++++++
 net/netfilter/Kconfig                |   16 +++++
 net/netfilter/Makefile               |    1 +
 net/netfilter/xt_ifgroup.c           |  108 ++++++++++++++++++++++++++++++++++
 4 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN	0x01
+#define XT_IFGROUP_INVERT_OUT	0x02
+#define XT_IFGROUP_MATCH_IN	0x04
+#define XT_IFGROUP_MATCH_OUT	0x08		
+
+struct xt_ifgroup_info {
+	u_int32_t in_group;
+	u_int32_t in_mask;
+	u_int32_t out_group;
+	u_int32_t out_mask;
+	u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3599770..0864e19 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
 	  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_IFGROUP
+	tristate '"ifgroup" interface group match support'
+	depends on NETFILTER_XTABLES
+	help
+	  Interface group matching allows you to match a packet by
+	  its incoming interface "group", settable using ip link set
+	  group
+
+	  Typical usage is to assign dynamic interfaces to a group
+	  when they come up using "ip link set group" and then match
+	  incoming packets with a rule like this:
+
+	    iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_REALM
 	tristate  '"realm" match support'
 	depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0c054bf..da9ab07 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
new file mode 100644
index 0000000..07c3acc
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,108 @@
+/*
+ * An x_tables match module to match interface groups
+ *
+ * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
+ *   Laszlo Attila Toth <panther@balabit.hu>
+ *
+ * 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/if_ether.h>
+#include <linux/if_packet.h>
+
+#include <linux/netfilter/xt_ifgroup.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
+MODULE_DESCRIPTION("Xtables interface group matching module");
+MODULE_ALIAS("ipt_ifgroup");
+MODULE_ALIAS("ip6t_ifgroup");
+
+static bool ifgroup_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)
+{
+#define FLAG_IS_SET(a,b)  ((a & b) == b)
+#define MATCH_IN  (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
+#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))
+
+	const struct xt_ifgroup_info *info = matchinfo;
+	bool verdict = false;
+	
+	if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
+		verdict = MATCH_IN && MATCH_OUT;
+	else if (info->flags & XT_IFGROUP_MATCH_IN)
+		verdict = MATCH_IN;
+	else if (info->flags & XT_IFGROUP_MATCH_OUT)
+		verdict = MATCH_OUT;
+	return verdict;
+}
+
+static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
+			       const struct xt_match *match,
+			       void *matchinfo, unsigned int hook_mask)
+{
+	struct xt_ifgroup_info *info = matchinfo;
+
+	if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
+		printk(KERN_ERR "xt_ifgroup: neither incoming nor "
+				"outgoing device selected\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+	    && info->flags & XT_IFGROUP_MATCH_OUT) {
+		printk(KERN_ERR "xt_ifgroup: output device not valid in "
+				"PRE_ROUTING and INPUT\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+	    && info->flags & XT_IFGROUP_MATCH_IN) {
+		printk(KERN_ERR "xt_ifgroup: input device not valid in "
+				"POST_ROUTING and OUTPUT\n");
+		return false;
+	}
+	return true;
+}
+
+static struct xt_match xt_ifgroup_match[] __read_mostly  = {
+        {
+		.name		= "ifgroup",
+		.match		= ifgroup_match,
+		.checkentry	= ifgroup_checkentry,
+		.matchsize	= sizeof(struct xt_ifgroup_info),
+		.family		= AF_INET,
+		.me		= THIS_MODULE,
+	
+	},
+	{
+		.name		= "ifgroup",
+		.match		= ifgroup_match,
+		.checkentry	= ifgroup_checkentry,
+		.matchsize	= sizeof(struct xt_ifgroup_info),
+		.family		= AF_INET6,
+		.me		= THIS_MODULE,
+	},
+};
+
+static int __init xt_ifgroup_init(void)
+{
+	return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+static void __exit xt_ifgroup_fini(void)
+{
+	xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+module_init(xt_ifgroup_init);
+module_exit(xt_ifgroup_fini);
-- 
1.5.2.5


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

* [PATCH 2/2] Interface group match
       [not found] ` <7336085b0c4f969c323966058b20836a331b65a1.1192695707.git.panther@balabit.hu>
  2007-10-18 10:13   ` [PATCH 2/2] Interface group match Laszlo Attila Toth
  2007-10-18 10:15   ` Laszlo Attila Toth
@ 2007-10-18 10:15   ` Laszlo Attila Toth
  2 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interface group values can be checked on both input and output interfaces.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/netfilter/xt_ifgroup.h |   18 ++++++
 net/netfilter/Kconfig                |   16 +++++
 net/netfilter/Makefile               |    1 +
 net/netfilter/xt_ifgroup.c           |  108 ++++++++++++++++++++++++++++++++++
 4 files changed, 143 insertions(+), 0 deletions(-)

diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN	0x01
+#define XT_IFGROUP_INVERT_OUT	0x02
+#define XT_IFGROUP_MATCH_IN	0x04
+#define XT_IFGROUP_MATCH_OUT	0x08		
+
+struct xt_ifgroup_info {
+	u_int32_t in_group;
+	u_int32_t in_mask;
+	u_int32_t out_group;
+	u_int32_t out_mask;
+	u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 3599770..0864e19 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
 	  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_IFGROUP
+	tristate '"ifgroup" interface group match support'
+	depends on NETFILTER_XTABLES
+	help
+	  Interface group matching allows you to match a packet by
+	  its incoming interface "group", settable using ip link set
+	  group
+
+	  Typical usage is to assign dynamic interfaces to a group
+	  when they come up using "ip link set group" and then match
+	  incoming packets with a rule like this:
+
+	    iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
+
+	  To compile it as a module, choose M here.  If unsure, say N.
+
 config NETFILTER_XT_MATCH_REALM
 	tristate  '"realm" match support'
 	depends on NETFILTER_XTABLES
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 0c054bf..da9ab07 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
 obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
+obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
new file mode 100644
index 0000000..07c3acc
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,108 @@
+/*
+ * An x_tables match module to match interface groups
+ *
+ * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
+ *   Laszlo Attila Toth <panther@balabit.hu>
+ *
+ * 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/if_ether.h>
+#include <linux/if_packet.h>
+
+#include <linux/netfilter/xt_ifgroup.h>
+#include <linux/netfilter/x_tables.h>
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
+MODULE_DESCRIPTION("Xtables interface group matching module");
+MODULE_ALIAS("ipt_ifgroup");
+MODULE_ALIAS("ip6t_ifgroup");
+
+static bool ifgroup_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)
+{
+#define FLAG_IS_SET(a,b)  ((a & b) == b)
+#define MATCH_IN  (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
+#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))
+
+	const struct xt_ifgroup_info *info = matchinfo;
+	bool verdict = false;
+	
+	if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
+		verdict = MATCH_IN && MATCH_OUT;
+	else if (info->flags & XT_IFGROUP_MATCH_IN)
+		verdict = MATCH_IN;
+	else if (info->flags & XT_IFGROUP_MATCH_OUT)
+		verdict = MATCH_OUT;
+	return verdict;
+}
+
+static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
+			       const struct xt_match *match,
+			       void *matchinfo, unsigned int hook_mask)
+{
+	struct xt_ifgroup_info *info = matchinfo;
+
+	if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
+		printk(KERN_ERR "xt_ifgroup: neither incoming nor "
+				"outgoing device selected\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
+	    && info->flags & XT_IFGROUP_MATCH_OUT) {
+		printk(KERN_ERR "xt_ifgroup: output device not valid in "
+				"PRE_ROUTING and INPUT\n");
+		return false;
+	}
+	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
+	    && info->flags & XT_IFGROUP_MATCH_IN) {
+		printk(KERN_ERR "xt_ifgroup: input device not valid in "
+				"POST_ROUTING and OUTPUT\n");
+		return false;
+	}
+	return true;
+}
+
+static struct xt_match xt_ifgroup_match[] __read_mostly  = {
+        {
+		.name		= "ifgroup",
+		.match		= ifgroup_match,
+		.checkentry	= ifgroup_checkentry,
+		.matchsize	= sizeof(struct xt_ifgroup_info),
+		.family		= AF_INET,
+		.me		= THIS_MODULE,
+	
+	},
+	{
+		.name		= "ifgroup",
+		.match		= ifgroup_match,
+		.checkentry	= ifgroup_checkentry,
+		.matchsize	= sizeof(struct xt_ifgroup_info),
+		.family		= AF_INET6,
+		.me		= THIS_MODULE,
+	},
+};
+
+static int __init xt_ifgroup_init(void)
+{
+	return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+static void __exit xt_ifgroup_fini(void)
+{
+	xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
+}
+
+module_init(xt_ifgroup_init);
+module_exit(xt_ifgroup_fini);
-- 
1.5.2.5


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

* [IPROUTE PATCH] Interface group as new ip link option
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
                   ` (6 preceding siblings ...)
       [not found] ` <7336085b0c4f969c323966058b20836a331b65a1.1192695707.git.panther@balabit.hu>
@ 2007-10-18 10:15 ` Laszlo Attila Toth
  2007-10-18 10:15 ` [IPTABLES PATCH] Interface group match Laszlo Attila Toth
  8 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Interfaces can be grouped and each group has an unique positive integer ID.
It can be set via ip link. Symbolic names can be specified in
/etc/iproute2/rt_ifgroup.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 include/linux/if_link.h |    2 +
 include/rt_names.h      |    2 +
 ip/ipaddress.c          |    4 +++
 ip/iplink.c             |   11 ++++++++
 lib/rt_names.c          |   62 +++++++++++++++++++++++++++++++++++++++++++++++
 man/man8/ip.8           |    5 ++++
 6 files changed, 86 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 23b3a8e..2dfb0b7 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -78,6 +78,8 @@ enum
 	IFLA_LINKMODE,
 	IFLA_LINKINFO,
 #define IFLA_LINKINFO IFLA_LINKINFO
+	IFLA_IFGROUP,
+#define	IFLA_IFGROUP IFLA_IFGROUP
 	__IFLA_MAX
 };
 
diff --git a/include/rt_names.h b/include/rt_names.h
index 07a10e0..72c5247 100644
--- a/include/rt_names.h
+++ b/include/rt_names.h
@@ -8,11 +8,13 @@ char* rtnl_rtscope_n2a(int id, char *buf, int len);
 char* rtnl_rttable_n2a(__u32 id, char *buf, int len);
 char* rtnl_rtrealm_n2a(int id, char *buf, int len);
 char* rtnl_dsfield_n2a(int id, char *buf, int len);
+char* rtnl_ifgroup_n2a(int id, char *buf, int len);
 int rtnl_rtprot_a2n(__u32 *id, char *arg);
 int rtnl_rtscope_a2n(__u32 *id, char *arg);
 int rtnl_rttable_a2n(__u32 *id, char *arg);
 int rtnl_rtrealm_a2n(__u32 *id, char *arg);
 int rtnl_dsfield_a2n(__u32 *id, char *arg);
+int rtnl_ifgroup_a2n(__u32 *id, char *arg);
 
 const char *inet_proto_n2a(int proto, char *buf, int len);
 int inet_proto_a2n(char *buf);
diff --git a/ip/ipaddress.c b/ip/ipaddress.c
index 518d8cd..405e85c 100644
--- a/ip/ipaddress.c
+++ b/ip/ipaddress.c
@@ -227,6 +227,10 @@ int print_linkinfo(const struct sockaddr_nl *who,
 		fprintf(fp, "mtu %u ", *(int*)RTA_DATA(tb[IFLA_MTU]));
 	if (tb[IFLA_QDISC])
 		fprintf(fp, "qdisc %s ", (char*)RTA_DATA(tb[IFLA_QDISC]));
+	if (tb[IFLA_IFGROUP]) {
+		SPRINT_BUF(b1);
+		fprintf(fp, "group %s ", rtnl_ifgroup_n2a(*(int*)RTA_DATA(tb[IFLA_IFGROUP]), b1, sizeof(b1)));
+	}
 #ifdef IFLA_MASTER
 	if (tb[IFLA_MASTER]) {
 		SPRINT_BUF(b1);
diff --git a/ip/iplink.c b/ip/iplink.c
index 4060845..bebb2fe 100644
--- a/ip/iplink.c
+++ b/ip/iplink.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include <sys/ioctl.h>
 #include <linux/sockios.h>
+#include <linux/rtnetlink.h>
 
 #include "rt_names.h"
 #include "utils.h"
@@ -46,6 +47,7 @@ void iplink_usage(void)
 	fprintf(stderr, "	                     promisc { on | off } |\n");
 	fprintf(stderr, "	                     trailers { on | off } |\n");
 	fprintf(stderr, "	                     txqueuelen PACKETS |\n");
+	fprintf(stderr, "	                     group GROUP |\n");
 	fprintf(stderr, "	                     name NEWNAME |\n");
 	fprintf(stderr, "	                     address LLADDR | broadcast LLADDR |\n");
 	fprintf(stderr, "	                     mtu MTU }\n");
@@ -145,6 +147,7 @@ static int iplink_have_newlink(void)
 static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 {
 	int qlen = -1;
+	__u32 group = 0;
 	int mtu = -1;
 	int len;
 	char abuf[32];
@@ -197,6 +200,14 @@ static int iplink_modify(int cmd, unsigned int flags, int argc, char **argv)
 			if (get_integer(&qlen,  *argv, 0))
 				invarg("Invalid \"txqueuelen\" value\n", *argv);
 			addattr_l(&req.n, sizeof(req), IFLA_TXQLEN, &qlen, 4);
+		} else if (matches(*argv, "group") == 0) {
+			NEXT_ARG();
+			if (group != 0)
+				duparg("group", *argv);
+
+			if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
+				invarg("\"group\" value is invalid\n", *argv);
+			addattr_l(&req.n, sizeof(req), IFLA_IFGROUP, &group, sizeof(group));
 		} else if (strcmp(*argv, "mtu") == 0) {
 			NEXT_ARG();
 			if (mtu != -1)
diff --git a/lib/rt_names.c b/lib/rt_names.c
index 8d019a0..a067e74 100644
--- a/lib/rt_names.c
+++ b/lib/rt_names.c
@@ -446,3 +446,65 @@ int rtnl_dsfield_a2n(__u32 *id, char *arg)
 	return 0;
 }
 
+static char * rtnl_rtifgroup_tab[256] = {
+	"0",
+};
+
+static int rtnl_rtifgroup_init;
+
+static void rtnl_rtifgroup_initialize(void)
+{
+	rtnl_rtifgroup_init = 1;
+	rtnl_tab_initialize("/etc/iproute2/rt_ifgroup",
+			    rtnl_rtifgroup_tab, 256);
+}
+
+char * rtnl_ifgroup_n2a(int id, char *buf, int len)
+{
+	if (id<0 || id>=256) {
+		snprintf(buf, len, "%d", id);
+		return buf;
+	}
+	if (!rtnl_rtifgroup_tab[id]) {
+		if (!rtnl_rtifgroup_init)
+			rtnl_rtifgroup_initialize();
+	}
+	if (rtnl_rtifgroup_tab[id])
+		return rtnl_rtifgroup_tab[id];
+	snprintf(buf, len, "0x%02x", id);
+	return buf;
+}
+
+
+int rtnl_ifgroup_a2n(__u32 *id, char *arg)
+{
+	static char *cache = NULL;
+	static unsigned long res;
+	char *end;
+	int i;
+
+	if (cache && strcmp(cache, arg) == 0) {
+		*id = res;
+		return 0;
+	}
+
+	if (!rtnl_rtifgroup_init)
+		rtnl_rtifgroup_initialize();
+
+	for (i=0; i<256; i++) {
+		if (rtnl_rtifgroup_tab[i] &&
+		    strcmp(rtnl_rtifgroup_tab[i], arg) == 0) {
+			cache = rtnl_rtifgroup_tab[i];
+			res = i;
+			*id = res;
+			return 0;
+		}
+	}
+
+	res = strtoul(arg, &end, 16);
+	if (!end || end == arg || *end || res > 255)
+		return -1;
+	*id = res;
+	return 0;
+}
+
diff --git a/man/man8/ip.8 b/man/man8/ip.8
index a9132da..92bc59e 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -506,6 +506,11 @@ already configured.
 change the transmit queue length of the device.
 
 .TP
+.BI group " GROUP"
+.TP 
+change the interface group identifier of the device.
+
+.TP
 .BI mtu " NUMBER"
 change the 
 .I MTU
-- 
1.5.2.5


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

* [IPTABLES PATCH] Interface group match
       [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
                   ` (7 preceding siblings ...)
  2007-10-18 10:15 ` [IPROUTE PATCH] Interface group as new ip link option Laszlo Attila Toth
@ 2007-10-18 10:15 ` Laszlo Attila Toth
  8 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 10:15 UTC (permalink / raw)
  To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth

Matching ifgroup value of incoming and/or outgoing interface.

Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
 extensions/Makefile                  |    2 +-
 extensions/libip6t_ifgroup.man       |   36 +++++++
 extensions/libipt_ifgroup.man        |   36 +++++++
 extensions/libxt_ifgroup.c           |  178 ++++++++++++++++++++++++++++++++++
 include/linux/netfilter/xt_ifgroup.h |   18 ++++
 5 files changed, 269 insertions(+), 1 deletions(-)

diff --git a/extensions/Makefile b/extensions/Makefile
index 5af234e..938cf0b 100644
--- a/extensions/Makefile
+++ b/extensions/Makefile
@@ -7,7 +7,7 @@
 #
 PF_EXT_SLIB:=ah addrtype conntrack ecn icmp iprange owner policy realm recent tos ttl unclean CLUSTERIP DNAT ECN LOG MASQUERADE MIRROR NETMAP REDIRECT REJECT SAME SNAT TOS TTL ULOG
 PF6_EXT_SLIB:=ah dst eui64 frag hbh hl icmp6 ipv6header mh owner policy rt HL LOG REJECT
-PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
+PFX_EXT_SLIB:=connbytes connmark connlimit comment dccp dscp esp hashlimit helper ifgroup length limit mac mark multiport physdev pkttype quota sctp state statistic standard string tcp tcpmss time u32 udp CLASSIFY CONNMARK DSCP MARK NFLOG NFQUEUE NOTRACK TCPMSS TRACE
 
 PF_EXT_SELINUX_SLIB:=
 PF6_EXT_SELINUX_SLIB:=
diff --git a/extensions/libip6t_ifgroup.man b/extensions/libip6t_ifgroup.man
new file mode 100644
index 0000000..a96ec91
--- /dev/null
+++ b/extensions/libip6t_ifgroup.man
@@ -0,0 +1,36 @@
+Maches packets on an interface if it is in the same interface group
+as specified by the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter. If a mask is also specified, the masked value of
+the inteface's group must be equal to the given value of the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter to match. This match is available in all tables.
+.TP
+.BR "--in-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of input interface and the optional mask.
+Valid only in the in the
+.B PREROUTING
+and
+.B INPUT
+and
+.B FORWARD
+chains, and user-defined chains which are only called from those
+chains. 
+.TP
+.BR "--out-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of out interface and the optional mask.
+Valid only in the in the
+.B FORWARD
+and
+.B OUTPUT
+and
+.B POSTROUTING
+chains, and user-defined chains which are only called from those
+chains. 
+.RS
+.PP
+
diff --git a/extensions/libipt_ifgroup.man b/extensions/libipt_ifgroup.man
new file mode 100644
index 0000000..a96ec91
--- /dev/null
+++ b/extensions/libipt_ifgroup.man
@@ -0,0 +1,36 @@
+Maches packets on an interface if it is in the same interface group
+as specified by the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter. If a mask is also specified, the masked value of
+the inteface's group must be equal to the given value of the
+.B "--in-ifgroup"
+or
+.B "--out-ifgroup"
+parameter to match. This match is available in all tables.
+.TP
+.BR "--in-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of input interface and the optional mask.
+Valid only in the in the
+.B PREROUTING
+and
+.B INPUT
+and
+.B FORWARD
+chains, and user-defined chains which are only called from those
+chains. 
+.TP
+.BR "--out-ifgroup \fIgroup[/mask]\fR"
+This specifies the interface group of out interface and the optional mask.
+Valid only in the in the
+.B FORWARD
+and
+.B OUTPUT
+and
+.B POSTROUTING
+chains, and user-defined chains which are only called from those
+chains. 
+.RS
+.PP
+
diff --git a/extensions/libxt_ifgroup.c b/extensions/libxt_ifgroup.c
new file mode 100644
index 0000000..d7f982c
--- /dev/null
+++ b/extensions/libxt_ifgroup.c
@@ -0,0 +1,178 @@
+/* 
+ * Shared library add-on to iptables to match 
+ * packets by the incoming interface group.
+ *
+ * Balazs Scheidler <bazsi@balabit.hu>
+ */
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <xtables.h>
+#include <linux/netfilter/xt_ifgroup.h>
+
+static void
+ifgroup_help(void)
+{
+	printf(
+"ifgroup v%s options:\n"
+"  --in-ifgroup  [!] group[/mask]  incoming interface group and its mask\n"
+"  --out-ifgroup [!] group[/mask]  outgoing interface group and its mask\n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{"in-ifgroup", 1, 0, '1'},
+	{"out-ifgroup", 1, 0, '2'},
+	{ }
+};
+
+#define PARAM_MATCH_IN   0x01
+#define PARAM_MATCH_OUT  0x02
+
+static int
+ifgroup_parse(int c, char **argv, int invert, unsigned int *flags,
+      const void *entry, struct xt_entry_match **match)
+{
+	struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) (*match)->data;
+	char *end;
+	
+	switch (c)
+	{
+		case '1':
+			if (*flags & PARAM_MATCH_IN)
+				exit_error(PARAMETER_PROBLEM,
+					  "ifgroup match: Can't specify --in-ifgroup twice");
+											         
+			check_inverse(optarg, &invert, &optind, 0);
+			
+			info->in_group = strtoul(optarg, &end, 0);
+			info->in_mask = 0xffffffffUL;
+			
+			if (*end == '/')
+				info->in_mask = strtoul(end+1, &end, 0);
+
+			if (*end != '\0' || end == optarg)
+				exit_error(PARAMETER_PROBLEM, "ifgroup match: Bad ifgroup value `%s'", optarg);
+			
+			if (invert)
+				info->flags |= XT_IFGROUP_INVERT_IN;
+
+			*flags |= PARAM_MATCH_IN;
+			info->flags |= XT_IFGROUP_MATCH_IN;			
+			break;
+		case '2':
+			if (*flags & PARAM_MATCH_OUT)
+				exit_error(PARAMETER_PROBLEM,
+					  "ifgroup match: Can't specify --out-ifgroup twice");
+											         
+			check_inverse(optarg, &invert, &optind, 0);
+			
+			info->out_group = strtoul(optarg, &end, 0);
+			info->out_mask = 0xffffffffUL;
+			
+			if (*end == '/')
+				info->out_mask = strtoul(end+1, &end, 0);
+
+			if (*end != '\0' || end == optarg)
+				exit_error(PARAMETER_PROBLEM, "ifgroup match: Bad ifgroup value `%s'", optarg);
+			
+			if (invert)
+				info->flags |= XT_IFGROUP_INVERT_OUT;
+
+			*flags |= PARAM_MATCH_OUT;
+			info->flags |= XT_IFGROUP_MATCH_OUT;			
+			break;
+		default: 
+			return 0;
+	}
+
+	return 1;
+}
+
+static void
+ifgroup_final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, "You must specify `--in-ifgroup' or `--out-ifgroup'");
+}
+
+static void
+ifgroup_print_value_in(struct xt_ifgroup_info *info)
+{
+	printf("0x%x/0x%x ", info->in_group, info->in_mask);
+}
+
+static void
+ifgroup_print_value_out(struct xt_ifgroup_info *info)
+{
+	printf("0x%x/0x%x ", info->out_group, info->out_mask);
+}
+
+static void
+ifgroup_print(const void *ip, const struct xt_entry_match *match, int numeric)
+{
+	struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) match->data;
+	
+	printf("ifgroup ");
+	
+	if (info->flags & XT_IFGROUP_MATCH_IN) {
+		printf("in %s", info->flags & XT_IFGROUP_INVERT_IN ? "! " : "");
+		ifgroup_print_value_in(info);
+	}
+	if (info->flags & XT_IFGROUP_MATCH_OUT) {
+		printf("out %s", info->flags & XT_IFGROUP_INVERT_OUT ? "! " : "");
+		ifgroup_print_value_out(info);
+	}
+}
+
+static void
+ifgroup_save(const void *ip, const struct xt_entry_match *match)
+{
+	struct xt_ifgroup_info *info = (struct xt_ifgroup_info *) match->data;
+	
+	if (info->flags & XT_IFGROUP_MATCH_IN) {
+		printf("--in-ifgroup %s", info->flags & XT_IFGROUP_INVERT_IN ? "! " : "");
+		ifgroup_print_value_in(info);
+	}
+	if (info->flags & XT_IFGROUP_MATCH_OUT) {
+		printf("--out-ifgroup %s", info->flags & XT_IFGROUP_INVERT_OUT ? "! " : "");
+		ifgroup_print_value_out(info);
+	}
+}
+
+static struct xtables_match ifgroup_match = {
+	.family		= AF_INET,
+	.name		= "ifgroup",
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.help		= ifgroup_help,
+	.parse		= ifgroup_parse, 
+	.final_check	= ifgroup_final_check, 
+	.print		= ifgroup_print,
+	.save		= ifgroup_save, 
+	.extra_opts	= opts
+};
+
+static struct xtables_match ifgroup_match6 = {
+	.family		= AF_INET6,
+	.name		= "ifgroup",
+	.version	= IPTABLES_VERSION,
+	.size		= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.userspacesize	= XT_ALIGN(sizeof(struct xt_ifgroup_info)),
+	.help		= ifgroup_help,
+	.parse		= ifgroup_parse, 
+	.final_check	= ifgroup_final_check, 
+	.print		= ifgroup_print,
+	.save		= ifgroup_save, 
+	.extra_opts	= opts
+};
+
+void _init(void)
+{
+	xtables_register_match(&ifgroup_match);
+	xtables_register_match(&ifgroup_match6);
+}
+
diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
new file mode 100644
index 0000000..9ac75de
--- /dev/null
+++ b/include/linux/netfilter/xt_ifgroup.h
@@ -0,0 +1,18 @@
+#ifndef _XT_IFGROUP_H
+#define _XT_IFGROUP_H
+
+#define XT_IFGROUP_INVERT_IN	0x01
+#define XT_IFGROUP_INVERT_OUT	0x02
+#define XT_IFGROUP_MATCH_IN	0x04
+#define XT_IFGROUP_MATCH_OUT	0x08		
+
+struct xt_ifgroup_info {
+	u_int32_t in_group;
+	u_int32_t in_mask;
+	u_int32_t out_group;
+	u_int32_t out_mask;
+	u_int8_t flags;
+};
+
+#endif /*_XT_IFGROUP_H*/
+
-- 
1.5.2.5


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

* Re: [PATCH 0/2] Interface groups, round two
  2007-10-18 10:15 ` Laszlo Attila Toth
@ 2007-10-18 10:20   ` Patrick McHardy
  2007-10-18 11:34     ` Laszlo Attila Toth
  0 siblings, 1 reply; 22+ messages in thread
From: Patrick McHardy @ 2007-10-18 10:20 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel

Laszlo Attila Toth wrote:
> Hello,
> 
> Here is the new version of ifgroup patches.
> 
> The interface group value is u_int32_t in net_device which should be enough.
> Previously it was an int.
> 
> Usage:
>    ip link set eth0 group 4
> but currently it cannot be unset, only changed to another value.


The only reason why it can't be set to zero again seems to
be this part from the iproute patch:

+			if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)

Why don't you allow a value of zero?

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

* Re: [PATCH 1/2] Interface group: core (netlink) part
  2007-10-18 10:15   ` Laszlo Attila Toth
@ 2007-10-18 10:22     ` Patrick McHardy
  2007-10-19  8:57       ` Laszlo Attila Toth
  0 siblings, 1 reply; 22+ messages in thread
From: Patrick McHardy @ 2007-10-18 10:22 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel

Laszlo Attila Toth wrote:
> @@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
>  		write_unlock_bh(&dev_base_lock);
>  	}
>  
> +	if (tb[IFLA_IFGROUP]) {
> +		write_lock_bh(&dev_base_lock);
> +		dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
> +		write_unlock_bh(&dev_base_lock);
> +	}


So no notifications at all? Mhh .. I guess its OK for now, this stuff
needs to be fixed to notify once for all changes anyway.

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

* Re: [PATCH 2/2] Interface group match
  2007-10-18 10:15   ` Laszlo Attila Toth
@ 2007-10-18 10:27     ` Patrick McHardy
  0 siblings, 0 replies; 22+ messages in thread
From: Patrick McHardy @ 2007-10-18 10:27 UTC (permalink / raw)
  To: Laszlo Attila Toth; +Cc: netdev, netfilter-devel

Laszlo Attila Toth wrote:
> Interface group values can be checked on both input and output interfaces.
> 
> Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
> ---
>  include/linux/netfilter/xt_ifgroup.h |   18 ++++++
>  net/netfilter/Kconfig                |   16 +++++
>  net/netfilter/Makefile               |    1 +
>  net/netfilter/xt_ifgroup.c           |  108 ++++++++++++++++++++++++++++++++++
>  4 files changed, 143 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/netfilter/xt_ifgroup.h b/include/linux/netfilter/xt_ifgroup.h
> new file mode 100644
> index 0000000..9ac75de
> --- /dev/null
> +++ b/include/linux/netfilter/xt_ifgroup.h
> @@ -0,0 +1,18 @@
> +#ifndef _XT_IFGROUP_H
> +#define _XT_IFGROUP_H
> +
> +#define XT_IFGROUP_INVERT_IN	0x01
> +#define XT_IFGROUP_INVERT_OUT	0x02
> +#define XT_IFGROUP_MATCH_IN	0x04
> +#define XT_IFGROUP_MATCH_OUT	0x08		
> +
> +struct xt_ifgroup_info {
> +	u_int32_t in_group;
> +	u_int32_t in_mask;
> +	u_int32_t out_group;
> +	u_int32_t out_mask;
> +	u_int8_t flags;
> +};
> +
> +#endif /*_XT_IFGROUP_H*/
> +
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index 3599770..0864e19 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -597,6 +597,22 @@ config NETFILTER_XT_MATCH_QUOTA
>  	  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_IFGROUP
> +	tristate '"ifgroup" interface group match support'
> +	depends on NETFILTER_XTABLES
> +	help
> +	  Interface group matching allows you to match a packet by
> +	  its incoming interface "group", settable using ip link set
> +	  group
> +
> +	  Typical usage is to assign dynamic interfaces to a group
> +	  when they come up using "ip link set group" and then match
> +	  incoming packets with a rule like this:
> +
> +	    iptables -A INPUT -m ifgroup --if-group openvpn-rw1 -j LOG
> +
> +	  To compile it as a module, choose M here.  If unsure, say N.
> +
>  config NETFILTER_XT_MATCH_REALM
>  	tristate  '"realm" match support'
>  	depends on NETFILTER_XTABLES
> diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
> index 0c054bf..da9ab07 100644
> --- a/net/netfilter/Makefile
> +++ b/net/netfilter/Makefile
> @@ -77,3 +77,4 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_TCPMSS) += xt_tcpmss.o
>  obj-$(CONFIG_NETFILTER_XT_MATCH_PHYSDEV) += xt_physdev.o
>  obj-$(CONFIG_NETFILTER_XT_MATCH_U32) += xt_u32.o
>  obj-$(CONFIG_NETFILTER_XT_MATCH_HASHLIMIT) += xt_hashlimit.o
> +obj-$(CONFIG_NETFILTER_XT_MATCH_IFGROUP) += xt_ifgroup.o
> diff --git a/net/netfilter/xt_ifgroup.c b/net/netfilter/xt_ifgroup.c
> new file mode 100644
> index 0000000..07c3acc
> --- /dev/null
> +++ b/net/netfilter/xt_ifgroup.c
> @@ -0,0 +1,108 @@
> +/*
> + * An x_tables match module to match interface groups
> + *
> + * (C) 2006,2007 Balazs Scheidler <bazsi@balabit.hu>,
> + *   Laszlo Attila Toth <panther@balabit.hu>
> + *
> + * 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/if_ether.h>
> +#include <linux/if_packet.h>

These two look unnecessary.

> +
> +#include <linux/netfilter/xt_ifgroup.h>
> +#include <linux/netfilter/x_tables.h>
> +
> +MODULE_LICENSE("GPL");
> +MODULE_AUTHOR("Laszlo Attila Toth <panther@balabit.hu>");
> +MODULE_DESCRIPTION("Xtables interface group matching module");
> +MODULE_ALIAS("ipt_ifgroup");
> +MODULE_ALIAS("ip6t_ifgroup");
> +
> +static bool ifgroup_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)
> +{
> +#define FLAG_IS_SET(a,b)  ((a & b) == b)
> +#define MATCH_IN  (((in->ifgroup & info->in_mask) == info->in_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_IN))
> +#define MATCH_OUT (((out->ifgroup & info->out_mask) == info->out_group) ^ FLAG_IS_SET(info->flags, XT_IFGROUP_INVERT_OUT))


Exceeds 80 characters and looks pretty obfuscating. Please open
code this or use an inline function.

> +
> +	const struct xt_ifgroup_info *info = matchinfo;
> +	bool verdict = false;
> +	
> +	if ((info->flags & XT_IFGROUP_MATCH_IN) && (info->flags & XT_IFGROUP_MATCH_OUT))
> +		verdict = MATCH_IN && MATCH_OUT;
> +	else if (info->flags & XT_IFGROUP_MATCH_IN)
> +		verdict = MATCH_IN;
> +	else if (info->flags & XT_IFGROUP_MATCH_OUT)
> +		verdict = MATCH_OUT;

How about:

if (info->flags & XT_IFGROUP_MATCH_IN && !MATCH_IN)
	return false;
if (info->flags & XT_IFGROUP_MATCH_OUT && !MATCH_OUT)
	return false;

instead of having each match twice?


> +	return verdict;
> +}
> +
> +static bool ifgroup_checkentry(const char *tablename, const void *ip_void,
> +			       const struct xt_match *match,
> +			       void *matchinfo, unsigned int hook_mask)
> +{
> +	struct xt_ifgroup_info *info = matchinfo;
> +
> +	if (!(info->flags & (XT_IFGROUP_MATCH_IN|XT_IFGROUP_MATCH_OUT))) {
> +		printk(KERN_ERR "xt_ifgroup: neither incoming nor "
> +				"outgoing device selected\n");
> +		return false;
> +	}
> +	if (hook_mask & (1 << NF_IP_PRE_ROUTING | 1 << NF_IP_LOCAL_IN)
> +	    && info->flags & XT_IFGROUP_MATCH_OUT) {
> +		printk(KERN_ERR "xt_ifgroup: output device not valid in "
> +				"PRE_ROUTING and INPUT\n");
> +		return false;
> +	}
> +	if (hook_mask & (1 << NF_IP_POST_ROUTING | 1 << NF_IP_LOCAL_OUT)
> +	    && info->flags & XT_IFGROUP_MATCH_IN) {
> +		printk(KERN_ERR "xt_ifgroup: input device not valid in "
> +				"POST_ROUTING and OUTPUT\n");
> +		return false;
> +	}
> +	return true;
> +}
> +
> +static struct xt_match xt_ifgroup_match[] __read_mostly  = {
> +        {
> +		.name		= "ifgroup",
> +		.match		= ifgroup_match,
> +		.checkentry	= ifgroup_checkentry,
> +		.matchsize	= sizeof(struct xt_ifgroup_info),
> +		.family		= AF_INET,
> +		.me		= THIS_MODULE,
> +	
> +	},
> +	{
> +		.name		= "ifgroup",
> +		.match		= ifgroup_match,
> +		.checkentry	= ifgroup_checkentry,
> +		.matchsize	= sizeof(struct xt_ifgroup_info),
> +		.family		= AF_INET6,
> +		.me		= THIS_MODULE,
> +	},
> +};
> +
> +static int __init xt_ifgroup_init(void)
> +{
> +	return xt_register_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));

Also exceeds 80 characters.

> +}
> +
> +static void __exit xt_ifgroup_fini(void)
> +{
> +	xt_unregister_matches(xt_ifgroup_match, ARRAY_SIZE(xt_ifgroup_match));
> +}
> +
> +module_init(xt_ifgroup_init);
> +module_exit(xt_ifgroup_fini);


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

* Re: [PATCH 0/2] Interface groups, round two
  2007-10-18 10:20   ` Patrick McHardy
@ 2007-10-18 11:34     ` Laszlo Attila Toth
  2007-10-18 11:42       ` Patrick McHardy
  0 siblings, 1 reply; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-18 11:34 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev, netfilter-devel

Patrick McHardy írta:
> Laszlo Attila Toth wrote:
>> Hello,
>>
>> Here is the new version of ifgroup patches.
>>
>> The interface group value is u_int32_t in net_device which should be 
>> enough.
>> Previously it was an int.
>>
>> Usage:
>>    ip link set eth0 group 4
>> but currently it cannot be unset, only changed to another value.
> 
> 
> The only reason why it can't be set to zero again seems to
> be this part from the iproute patch:
> 
> +            if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
> 
> Why don't you allow a value of zero?
> 

It has historical reason. The original version which didn't use netlink 
(at kernel 2.6.17) used zero to indicate that group was not set. You 
wrote previously that this part is useless for new kernels. I'll fix 
this (with type of "group" variable to unsigned int32 to be consistent 
with the kernel part).

-- 
Attila

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

* Re: [PATCH 0/2] Interface groups, round two
  2007-10-18 11:34     ` Laszlo Attila Toth
@ 2007-10-18 11:42       ` Patrick McHardy
  0 siblings, 0 replies; 22+ messages in thread
From: Patrick McHardy @ 2007-10-18 11:42 UTC (permalink / raw)
  To: panther; +Cc: netdev, netfilter-devel

Laszlo Attila Toth wrote:
> Patrick McHardy írta:
>> Laszlo Attila Toth wrote:
>
>> The only reason why it can't be set to zero again seems to
>> be this part from the iproute patch:
>>
>> +            if (rtnl_ifgroup_a2n(&group, *argv) || group == 0)
>>
>> Why don't you allow a value of zero?
>>
> 
> It has historical reason. The original version which didn't use netlink 
> (at kernel 2.6.17) used zero to indicate that group was not set. You 
> wrote previously that this part is useless for new kernels. I'll fix 
> this (with type of "group" variable to unsigned int32 to be consistent 
> with the kernel part).

Support for ifgroups in the ioctl part is useless since that will
never be used with kernel supporting this feature. Setting it to
zero is not useless.



-
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] 22+ messages in thread

* Re: [PATCH 1/2] Interface group: core (netlink) part
  2007-10-18 10:22     ` Patrick McHardy
@ 2007-10-19  8:57       ` Laszlo Attila Toth
  0 siblings, 0 replies; 22+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19  8:57 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netdev, netfilter-devel

Patrick McHardy írta:
> Laszlo Attila Toth wrote:
>> @@ -846,6 +850,12 @@ static int do_setlink(struct net_device *dev, 
>> struct ifinfomsg *ifm,
>>          write_unlock_bh(&dev_base_lock);
>>      }
>>  
>> +    if (tb[IFLA_IFGROUP]) {
>> +        write_lock_bh(&dev_base_lock);
>> +        dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
>> +        write_unlock_bh(&dev_base_lock);
>> +    }
> 
> 
> So no notifications at all? Mhh .. I guess its OK for now, this stuff
> needs to be fixed to notify once for all changes anyway.
> 

I'll resend the following patch with the new ifgroup patches. The 
current changes: changes are now atomic and a notification will be send 
later at the end of the function. If an address was changed, a 
notification will be send and after that another which is always sent 
when anyi modification happened.

This patch may not be complete.


diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..87ab3ff 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -819,6 +819,7 @@ static int do_setlink(struct net_device *dev, struct 
ifinfomsg *ifm,
         if (tb[IFLA_BROADCAST]) {
                 nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], 
dev->addr_len);
                 send_addr_notify = 1;
+               modified = 1;
         }

         if (ifm->ifi_flags || ifm->ifi_change) {
@@ -829,21 +830,35 @@ static int do_setlink(struct net_device *dev, 
struct ifinfomsg *ifm,
                         flags = (flags & ifm->ifi_change) |
                                 (dev->flags & ~ifm->ifi_change);
                 dev_change_flags(dev, flags);
+               modified = 1;
         }

-       if (tb[IFLA_TXQLEN])
+       if (tb[IFLA_TXQLEN]) {
+               write_lock_bh(&dev_base_lock);
                 dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
+               write_unlock_bh(&dev_base_lock);
+               modified = 1;
+       }

-       if (tb[IFLA_WEIGHT])
+       if (tb[IFLA_WEIGHT]) {
+               write_lock_bh(&dev_base_lock);
                 dev->weight = nla_get_u32(tb[IFLA_WEIGHT]);
+               write_unlock_bh(&dev_base_lock);
+               modified = 1;
+       }

-       if (tb[IFLA_OPERSTATE])
+       if (tb[IFLA_OPERSTATE]) {
+               write_lock_bh(&dev_base_lock);
                 set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
+               write_unlock_bh(&dev_base_lock);
+               modified = 1;
+       }

         if (tb[IFLA_LINKMODE]) {
                 write_lock_bh(&dev_base_lock);
                 dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
                 write_unlock_bh(&dev_base_lock);
+               modified = 1;
         }

         err = 0;
@@ -857,6 +872,8 @@ errout:

         if (send_addr_notify)
                 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
+       if (modified)
+               rtmsg_ifinfo(RTM_NEWLINK, dev, 0)
         return err;
  }

-
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 related	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2007-10-19  8:57 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <ifgroup-20071018-120757-1192702077-panther@balabit.hu>
2007-10-18 10:13 ` [PATCH 0/2] Interface groups, round two Laszlo Attila Toth
     [not found] ` <4e88bea1c0065fada9181e9b668a91c6c3fd8796.1192695706.git.panther@balabit.hu>
2007-10-18 10:13   ` [PATCH 1/2] Interface group: core (netlink) part Laszlo Attila Toth
2007-10-18 10:15   ` Laszlo Attila Toth
2007-10-18 10:15   ` Laszlo Attila Toth
2007-10-18 10:22     ` Patrick McHardy
2007-10-19  8:57       ` Laszlo Attila Toth
2007-10-18 10:13 ` [IPROUTE PATCH] Interface group as new ip link option Laszlo Attila Toth
2007-10-18 10:13 ` [IPTABLES PATCH] Interface group match Laszlo Attila Toth
2007-10-18 10:15 ` [PATCH 0/2] Interface groups, round two Laszlo Attila Toth
2007-10-18 10:15 ` Laszlo Attila Toth
2007-10-18 10:20   ` Patrick McHardy
2007-10-18 11:34     ` Laszlo Attila Toth
2007-10-18 11:42       ` Patrick McHardy
     [not found] ` <7336085b0c4f969c323966058b20836a331b65a1.1192695707.git.panther@balabit.hu>
2007-10-18 10:13   ` [PATCH 2/2] Interface group match Laszlo Attila Toth
2007-10-18 10:15   ` Laszlo Attila Toth
2007-10-18 10:27     ` Patrick McHardy
2007-10-18 10:15   ` Laszlo Attila Toth
2007-10-18 10:15 ` [IPROUTE PATCH] Interface group as new ip link option Laszlo Attila Toth
2007-10-18 10:15 ` [IPTABLES PATCH] Interface group match Laszlo Attila Toth
2007-10-16  8:01 [PATCH 0/2] Interface groups Laszlo Attila Toth
     [not found] ` <ifgroup.20071015.1192520046.panther@balabit.hu>
     [not found]   ` <1824b3d462b1d85aaf33941cf082c4e018d5bff7.1192460167.git.panther@balabit.hu>
2007-10-16  8:01     ` [PATCH 1/2] Interface group: core (netlink) part Laszlo Attila Toth
2007-10-16  8:34       ` Patrick McHardy
2007-10-16  8:01     ` Laszlo Attila Toth

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