* [RFC] net/bridge: port based vlan filtering for bridges
@ 2012-04-11 15:10 Benjamin LaHaise
2012-04-11 15:30 ` Stephen Hemminger
0 siblings, 1 reply; 4+ messages in thread
From: Benjamin LaHaise @ 2012-04-11 15:10 UTC (permalink / raw)
To: netdev
Hello folks,
Attached is the first stab at a patch to make it possible to filter packets
received from other bridge ports based on the port number. This can be used
to emulate port based VLANs that some switches support.
The justification for this is a bit interesting. Initially, I had been
filtering packets using firewall rules. Unfortunately, the number of
filter rules becomes impossible to manage when trying to filter traffic
between 100 different ports. CPU overhead of the filters is also a major
problem.
The particular use-case I'm dealing with is simulating wireless networks
on a system using LXC containers. Each guest has a veth device that is a
member of the bridge, but the topology of which nodes can "hear" each other
changes at runtime.
Comments/thoughts?
-ben
---
br_forward.c | 3 +++
br_if.c | 3 +--
br_private.h | 4 ++++
br_sysfs_if.c | 20 ++++++++++++++++++++
4 files changed, 28 insertions(+), 2 deletions(-)
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index ee64287..9b106f8 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -30,6 +30,9 @@ static int deliver_clone(const struct net_bridge_port *prev,
static inline int should_deliver(const struct net_bridge_port *p,
const struct sk_buff *skb)
{
+ struct net_bridge_port *from = br_port_get_rcu(skb->dev);
+ if (from && test_bit(from->port_no, p->filter_ports))
+ return 0;
return (((p->flags & BR_HAIRPIN_MODE) || skb->dev != p->dev) &&
p->state == BR_STATE_FORWARDING);
}
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index f603e5b..2f2e595 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -183,8 +183,7 @@ static int find_portno(struct net_bridge *br)
struct net_bridge_port *p;
unsigned long *inuse;
- inuse = kcalloc(BITS_TO_LONGS(BR_MAX_PORTS), sizeof(unsigned long),
- GFP_KERNEL);
+ inuse = kcalloc(BR_PORT_LONGS, sizeof(unsigned long), GFP_KERNEL);
if (!inuse)
return -ENOMEM;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index d7d6fb0..c6fbab0 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -17,6 +17,7 @@
#include <linux/if_bridge.h>
#include <linux/netpoll.h>
#include <linux/u64_stats_sync.h>
+#include <linux/bitops.h>
#include <net/route.h>
#define BR_HASH_BITS 8
@@ -26,6 +27,7 @@
#define BR_PORT_BITS 10
#define BR_MAX_PORTS (1<<BR_PORT_BITS)
+#define BR_PORT_LONGS BITS_TO_LONGS(BR_MAX_PORTS)
#define BR_VERSION "2.3"
@@ -156,6 +158,8 @@ struct net_bridge_port
#ifdef CONFIG_NET_POLL_CONTROLLER
struct netpoll *np;
#endif
+
+ unsigned long filter_ports[BR_PORT_LONGS];
};
#define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)
diff --git a/net/bridge/br_sysfs_if.c b/net/bridge/br_sysfs_if.c
index 6229b62..9d95f6a 100644
--- a/net/bridge/br_sysfs_if.c
+++ b/net/bridge/br_sysfs_if.c
@@ -164,6 +164,24 @@ static BRPORT_ATTR(multicast_router, S_IRUGO | S_IWUSR, show_multicast_router,
store_multicast_router);
#endif
+static int store_add_filter_port(struct net_bridge_port *p, unsigned long v)
+{
+ if (v >= BR_MAX_PORTS)
+ return -EINVAL;
+ set_bit(v, p->filter_ports);
+ return 0;
+}
+static BRPORT_ATTR(add_filter_port, S_IWUSR, NULL, store_add_filter_port);
+
+static int store_remove_filter_port(struct net_bridge_port *p, unsigned long v)
+{
+ if (v >= BR_MAX_PORTS)
+ return -EINVAL;
+ clear_bit(v, p->filter_ports);
+ return 0;
+}
+static BRPORT_ATTR(remove_filter_port, S_IWUSR, NULL, store_remove_filter_port);
+
static struct brport_attribute *brport_attrs[] = {
&brport_attr_path_cost,
&brport_attr_priority,
@@ -184,6 +202,8 @@ static struct brport_attribute *brport_attrs[] = {
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
&brport_attr_multicast_router,
#endif
+ &brport_attr_add_filter_port,
+ &brport_attr_remove_filter_port,
NULL
};
--
"Thought is the essence of where you are now."
^ permalink raw reply related [flat|nested] 4+ messages in thread* Re: [RFC] net/bridge: port based vlan filtering for bridges
2012-04-11 15:10 [RFC] net/bridge: port based vlan filtering for bridges Benjamin LaHaise
@ 2012-04-11 15:30 ` Stephen Hemminger
2012-04-11 15:36 ` Benjamin LaHaise
0 siblings, 1 reply; 4+ messages in thread
From: Stephen Hemminger @ 2012-04-11 15:30 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: netdev
On Wed, 11 Apr 2012 11:10:02 -0400
Benjamin LaHaise <bcrl@kvack.org> wrote:
> Hello folks,
>
> Attached is the first stab at a patch to make it possible to filter packets
> received from other bridge ports based on the port number. This can be used
> to emulate port based VLANs that some switches support.
>
> The justification for this is a bit interesting. Initially, I had been
> filtering packets using firewall rules. Unfortunately, the number of
> filter rules becomes impossible to manage when trying to filter traffic
> between 100 different ports. CPU overhead of the filters is also a major
> problem.
>
> The particular use-case I'm dealing with is simulating wireless networks
> on a system using LXC containers. Each guest has a veth device that is a
> member of the bridge, but the topology of which nodes can "hear" each other
> changes at runtime.
>
> Comments/thoughts?
>
Nak. If firewall doesn't work then implement a better netfilter
module.
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] net/bridge: port based vlan filtering for bridges
2012-04-11 15:30 ` Stephen Hemminger
@ 2012-04-11 15:36 ` Benjamin LaHaise
2012-04-11 15:38 ` Stephen Hemminger
0 siblings, 1 reply; 4+ messages in thread
From: Benjamin LaHaise @ 2012-04-11 15:36 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
On Wed, Apr 11, 2012 at 08:30:52AM -0700, Stephen Hemminger wrote:
> On Wed, 11 Apr 2012 11:10:02 -0400
> Benjamin LaHaise <bcrl@kvack.org> wrote:
>
> > Hello folks,
> >
> > Attached is the first stab at a patch to make it possible to filter packets
> > received from other bridge ports based on the port number. This can be used
> > to emulate port based VLANs that some switches support.
> >
> > The justification for this is a bit interesting. Initially, I had been
> > filtering packets using firewall rules. Unfortunately, the number of
> > filter rules becomes impossible to manage when trying to filter traffic
> > between 100 different ports. CPU overhead of the filters is also a major
> > problem.
> >
> > The particular use-case I'm dealing with is simulating wireless networks
> > on a system using LXC containers. Each guest has a veth device that is a
> > member of the bridge, but the topology of which nodes can "hear" each other
> > changes at runtime.
> >
> > Comments/thoughts?
> >
>
> Nak. If firewall doesn't work then implement a better netfilter
> module.
That still results in the CPU overhead of packet duplication for each and
every bridge port regardless of the port receiving the packet or not.
Hmmmm, would a NF_HOOK in should_deliver be okay?
-ben
--
"Thought is the essence of where you are now."
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [RFC] net/bridge: port based vlan filtering for bridges
2012-04-11 15:36 ` Benjamin LaHaise
@ 2012-04-11 15:38 ` Stephen Hemminger
0 siblings, 0 replies; 4+ messages in thread
From: Stephen Hemminger @ 2012-04-11 15:38 UTC (permalink / raw)
To: Benjamin LaHaise; +Cc: netdev
On Wed, 11 Apr 2012 11:36:29 -0400
Benjamin LaHaise <bcrl@kvack.org> wrote:
> On Wed, Apr 11, 2012 at 08:30:52AM -0700, Stephen Hemminger wrote:
> > On Wed, 11 Apr 2012 11:10:02 -0400
> > Benjamin LaHaise <bcrl@kvack.org> wrote:
> >
> > > Hello folks,
> > >
> > > Attached is the first stab at a patch to make it possible to filter packets
> > > received from other bridge ports based on the port number. This can be used
> > > to emulate port based VLANs that some switches support.
> > >
> > > The justification for this is a bit interesting. Initially, I had been
> > > filtering packets using firewall rules. Unfortunately, the number of
> > > filter rules becomes impossible to manage when trying to filter traffic
> > > between 100 different ports. CPU overhead of the filters is also a major
> > > problem.
> > >
> > > The particular use-case I'm dealing with is simulating wireless networks
> > > on a system using LXC containers. Each guest has a veth device that is a
> > > member of the bridge, but the topology of which nodes can "hear" each other
> > > changes at runtime.
> > >
> > > Comments/thoughts?
> > >
> >
> > Nak. If firewall doesn't work then implement a better netfilter
> > module.
>
> That still results in the CPU overhead of packet duplication for each and
> every bridge port regardless of the port receiving the packet or not.
> Hmmmm, would a NF_HOOK in should_deliver be okay?
Sure. Having better way to do policy would be great. Just don't want
to have implementations of specific policies in generic code.
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2012-04-11 15:38 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-04-11 15:10 [RFC] net/bridge: port based vlan filtering for bridges Benjamin LaHaise
2012-04-11 15:30 ` Stephen Hemminger
2012-04-11 15:36 ` Benjamin LaHaise
2012-04-11 15:38 ` Stephen Hemminger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox