* [IFGROUPv3 0/*] Interface groups, round 3
[not found] <20071019-181844-1192810724.panther@balabit.hu>
2007-10-19 16:29 ` [IFGROUPv3 0/*] Interface groups, round 3 Laszlo Attila Toth
@ 2007-10-19 16:29 ` Laszlo Attila Toth
[not found] ` <80da3aa904080a33dd4645a8390c96133268a512.1192810837.git.panther@balabit.hu>
` (4 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:29 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
Hello,
This is the 3rd version of interface group patches.
Each net_device structure has a non-negative ifgroup member indicating
the group it belongs to. In the ip tool it is between 0 and 256 where
0 means it is unset.
Usage:
ip link set eth0 group 4
ip lonk set eth0 group 0 # to unset
ip link set eth0 group intra # named groups
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: single notification, atomic changes
kernel: core part
kernel: netfilter module, ifgroup match
iproute2: showing and set ifgroup value
iptables: ifgroup match
--
Attila
^ permalink raw reply [flat|nested] 10+ messages in thread
* [IFGROUPv3 0/*] Interface groups, round 3
[not found] <20071019-181844-1192810724.panther@balabit.hu>
@ 2007-10-19 16:29 ` Laszlo Attila Toth
2007-10-19 16:29 ` Laszlo Attila Toth
` (5 subsequent siblings)
6 siblings, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:29 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
Hello,
This is the 3rd version of interface group patches.
Each net_device structure has a non-negative ifgroup member indicating
the group it belongs to. In the ip tool it is between 0 and 256 where
0 means it is unset.
Usage:
ip link set eth0 group 4
ip lonk set eth0 group 0 # to unset
ip link set eth0 group intra # named groups
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: single notification, atomic changes
kernel: core part
kernel: netfilter module, ifgroup match
iproute2: showing and set ifgroup value
iptables: ifgroup match
--
Attila
^ permalink raw reply [flat|nested] 10+ messages in thread
* [IFGROUPv3 1/3] rtnetlink: setlink changes atomic with single notification
[not found] ` <80da3aa904080a33dd4645a8390c96133268a512.1192810837.git.panther@balabit.hu>
2007-10-19 16:29 ` [IFGROUPv3 1/3] rtnetlink: setlink changes atomic with single notification Laszlo Attila Toth
@ 2007-10-19 16:29 ` Laszlo Attila Toth
1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:29 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In do_setlink the device changes are atomic and notifications will be sent
at the end of the function once if any modification occured and once if
address has been changed.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
net/core/rtnetlink.c | 23 ++++++++++++++++++++---
1 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..53af13f 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;
}
--
1.5.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [IFGROUPv3 1/3] rtnetlink: setlink changes atomic with single notification
[not found] ` <80da3aa904080a33dd4645a8390c96133268a512.1192810837.git.panther@balabit.hu>
@ 2007-10-19 16:29 ` Laszlo Attila Toth
2007-10-19 16:29 ` Laszlo Attila Toth
1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:29 UTC (permalink / raw)
To: netdev, netfilter-devel; +Cc: Laszlo Attila Toth
In do_setlink the device changes are atomic and notifications will be sent
at the end of the function once if any modification occured and once if
address has been changed.
Signed-off-by: Laszlo Attila Toth <panther@balabit.hu>
---
net/core/rtnetlink.c | 23 ++++++++++++++++++++---
1 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4756d58..53af13f 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;
}
--
1.5.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [IFGROUPv3 2/3] Interface group: core (netlink) part
[not found] ` <b304cea2e4e1659e9e7e58c0303b21a8e03b6688.1192810837.git.panther@balabit.hu>
2007-10-19 16:30 ` [IFGROUPv3 2/3] Interface group: core (netlink) part Laszlo Attila Toth
@ 2007-10-19 16:30 ` Laszlo Attila Toth
1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:30 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 | 11 +++++++++++
3 files changed, 15 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 53af13f..de38c03 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);
@@ -861,6 +865,13 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
modified = 1;
}
+ if (tb[IFLA_IFGROUP]) {
+ write_lock_bh(&dev_base_lock);
+ dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+ write_unlock_bh(&dev_base_lock);
+ modified = 1;
+ }
+
err = 0;
errout:
--
1.5.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [IFGROUPv3 2/3] Interface group: core (netlink) part
[not found] ` <b304cea2e4e1659e9e7e58c0303b21a8e03b6688.1192810837.git.panther@balabit.hu>
@ 2007-10-19 16:30 ` Laszlo Attila Toth
2007-10-19 16:30 ` Laszlo Attila Toth
1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:30 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 | 11 +++++++++++
3 files changed, 15 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 53af13f..de38c03 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);
@@ -861,6 +865,13 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
modified = 1;
}
+ if (tb[IFLA_IFGROUP]) {
+ write_lock_bh(&dev_base_lock);
+ dev->ifgroup = nla_get_u32(tb[IFLA_IFGROUP]);
+ write_unlock_bh(&dev_base_lock);
+ modified = 1;
+ }
+
err = 0;
errout:
--
1.5.2.5
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [IFGROUPv3 3/3] Interface group match
[not found] ` <b90c646084a4f938fb6a0bbce687e428150aedc8.1192810837.git.panther@balabit.hu>
2007-10-19 16:30 ` [IFGROUPv3 3/3] Interface group match Laszlo Attila Toth
@ 2007-10-19 16:30 ` Laszlo Attila Toth
1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:30 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 | 121 ++++++++++++++++++++++++++++++++++
4 files changed, 156 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..2baf772
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,121 @@
+/*
+ * 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/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 inline bool
+ifgroup_match_in(const struct net_device *in,
+ const struct xt_ifgroup_info *info)
+{
+
+ return ((in->ifgroup & info->in_mask) == info->in_group) ^
+ ((info->flags & XT_IFGROUP_INVERT_IN) == XT_IFGROUP_INVERT_IN);
+}
+
+static inline bool
+ifgroup_match_out(const struct net_device *out,
+ const struct xt_ifgroup_info *info)
+{
+ return ((out->ifgroup & info->out_mask) == info->out_group) ^
+ ((info->flags & XT_IFGROUP_INVERT_OUT) == XT_IFGROUP_INVERT_OUT);
+}
+
+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)
+{
+ const struct xt_ifgroup_info *info = matchinfo;
+
+ if (info->flags & XT_IFGROUP_MATCH_IN && !ifgroup_match_in(in, info))
+ return false;
+ if (info->flags & XT_IFGROUP_MATCH_OUT && !ifgroup_match_out(out, info))
+ return false;
+
+ return true;
+}
+
+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] 10+ messages in thread
* [IFGROUPv3 3/3] Interface group match
[not found] ` <b90c646084a4f938fb6a0bbce687e428150aedc8.1192810837.git.panther@balabit.hu>
@ 2007-10-19 16:30 ` Laszlo Attila Toth
2007-10-19 16:30 ` Laszlo Attila Toth
1 sibling, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:30 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 | 121 ++++++++++++++++++++++++++++++++++
4 files changed, 156 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..2baf772
--- /dev/null
+++ b/net/netfilter/xt_ifgroup.c
@@ -0,0 +1,121 @@
+/*
+ * 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/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 inline bool
+ifgroup_match_in(const struct net_device *in,
+ const struct xt_ifgroup_info *info)
+{
+
+ return ((in->ifgroup & info->in_mask) == info->in_group) ^
+ ((info->flags & XT_IFGROUP_INVERT_IN) == XT_IFGROUP_INVERT_IN);
+}
+
+static inline bool
+ifgroup_match_out(const struct net_device *out,
+ const struct xt_ifgroup_info *info)
+{
+ return ((out->ifgroup & info->out_mask) == info->out_group) ^
+ ((info->flags & XT_IFGROUP_INVERT_OUT) == XT_IFGROUP_INVERT_OUT);
+}
+
+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)
+{
+ const struct xt_ifgroup_info *info = matchinfo;
+
+ if (info->flags & XT_IFGROUP_MATCH_IN && !ifgroup_match_in(in, info))
+ return false;
+ if (info->flags & XT_IFGROUP_MATCH_OUT && !ifgroup_match_out(out, info))
+ return false;
+
+ return true;
+}
+
+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] 10+ messages in thread
* [IFGROUPv3 iproute2] Interface group as new ip link option
[not found] <20071019-181844-1192810724.panther@balabit.hu>
` (4 preceding siblings ...)
[not found] ` <b90c646084a4f938fb6a0bbce687e428150aedc8.1192810837.git.panther@balabit.hu>
@ 2007-10-19 16:30 ` Laszlo Attila Toth
2007-10-19 16:30 ` [IFGROUPv3 iptables] Interface group match Laszlo Attila Toth
6 siblings, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:30 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 d1c6620..1ecbe03 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 8e0ed2a..71bd240 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))
+ 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 8fd6d52..0338dab 100644
--- a/man/man8/ip.8
+++ b/man/man8/ip.8
@@ -511,6 +511,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] 10+ messages in thread
* [IFGROUPv3 iptables] Interface group match
[not found] <20071019-181844-1192810724.panther@balabit.hu>
` (5 preceding siblings ...)
2007-10-19 16:30 ` [IFGROUPv3 iproute2] Interface group as new ip link option Laszlo Attila Toth
@ 2007-10-19 16:30 ` Laszlo Attila Toth
6 siblings, 0 replies; 10+ messages in thread
From: Laszlo Attila Toth @ 2007-10-19 16:30 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 | 187 ++++++++++++++++++++++++++++++++++
include/linux/netfilter/xt_ifgroup.h | 18 ++++
5 files changed, 278 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..a4056c9
--- /dev/null
+++ b/extensions/libxt_ifgroup.c
@@ -0,0 +1,187 @@
+/*
+ * Shared library add-on to iptables to match
+ * packets by the incoming interface group.
+ *
+ * (c) 2006, 2007 Balazs Scheidler <bazsi@balabit.hu>,
+ * Laszlo Attila Toth <panther@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] 10+ messages in thread
end of thread, other threads:[~2007-10-19 16:30 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <20071019-181844-1192810724.panther@balabit.hu>
2007-10-19 16:29 ` [IFGROUPv3 0/*] Interface groups, round 3 Laszlo Attila Toth
2007-10-19 16:29 ` Laszlo Attila Toth
[not found] ` <80da3aa904080a33dd4645a8390c96133268a512.1192810837.git.panther@balabit.hu>
2007-10-19 16:29 ` [IFGROUPv3 1/3] rtnetlink: setlink changes atomic with single notification Laszlo Attila Toth
2007-10-19 16:29 ` Laszlo Attila Toth
[not found] ` <b304cea2e4e1659e9e7e58c0303b21a8e03b6688.1192810837.git.panther@balabit.hu>
2007-10-19 16:30 ` [IFGROUPv3 2/3] Interface group: core (netlink) part Laszlo Attila Toth
2007-10-19 16:30 ` Laszlo Attila Toth
[not found] ` <b90c646084a4f938fb6a0bbce687e428150aedc8.1192810837.git.panther@balabit.hu>
2007-10-19 16:30 ` [IFGROUPv3 3/3] Interface group match Laszlo Attila Toth
2007-10-19 16:30 ` Laszlo Attila Toth
2007-10-19 16:30 ` [IFGROUPv3 iproute2] Interface group as new ip link option Laszlo Attila Toth
2007-10-19 16:30 ` [IFGROUPv3 iptables] Interface group match 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).