Ethernet Bridge development
 help / color / mirror / Atom feed
* [Bridge] Ethernet Bridge with VLAN TAG
From: shailesh panchal @ 2010-12-02  5:29 UTC (permalink / raw)
  To: bridge; +Cc: ronak.shah, shailesh.panchal


[-- Attachment #1.1: Type: text/plain, Size: 1559 bytes --]

Requirement: Implement the bridge mode with VLAN TAG in 5VT EVM board

Description:

    5VT EVM board has two ethernet port eth0 and eth1. We want to create the
Ethernet bridge using the eth0 and eth1 port.

    We find bridge util on the 5VT EVM board name is brctl.


    Please see the picture file for more network setup.

    In the network setup we have one swich three PC and 5VT EVM board.

    Eth0 of 5VT is connected with PC1
    Eth1 of 5VT is connected with switch
    PC2 and PC3 is connected with switch

    VLAN Configuration
    Eth0 of 5VT has VLAN 5
    Eth1 of 5VT has VLAN 7
    PC2 has the VLAN 5
    PC3 has the VLAN 7
    PC1 has no VLAN


1)    Now, PC1 want to ping the PC2.

    PC1 generated packet first go to Eth0 of 5VT, Now Eth0 Add the VLAN 5 in
packet and then forward to Eth1 of 5VT because 5VT is working in bridge mode
Now Eth1 of 5VT send the packet to switch and switch forward the packet ot
PC2 and PC3, Now PC2 accept the packet and reply it.

    Simlarly when PC2 ping PC1 it get the reply of it.

2)    5VT want to ping PC3

    5VT generated packet first go to Eth1, Now Eth1 Add the VLAN 7 in packet
and send the packet to switch and switch forward the packet ot PC2 and
PC3,then PC3 accept the packet and reply it.

    Simlarly when PC3 ping 5VT it get the reply of it.


3)    PC2 want to ping 5VT

    It can not get replay because different VLAG TAG
    Simplary PC2 can not ping the PC1


So, please provide the guidence about it how we can achive this
functionality in 5VT EVM board.


Regards,
shailesh

[-- Attachment #1.2: Type: text/html, Size: 1732 bytes --]

[-- Attachment #2: VLAN.jpg --]
[-- Type: image/jpeg, Size: 37597 bytes --]

^ permalink raw reply

* Re: [Bridge] Disable mac address learning
From: matan monitz @ 2010-11-28 13:27 UTC (permalink / raw)
  To: Benjamin Vanheuverzwijn; +Cc: bridge
In-Reply-To: <AANLkTikRhBENKqbvmuYv=jVoMaFM-2EH57977Yt_1Y5j@mail.gmail.com>

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

it works
i use it for transfering a port monitor via bridge
On Sun, Nov 28, 2010 at 12:21 AM, Benjamin Vanheuverzwijn <bvanheu@gmail.com
> wrote:

> Hi,
>
> Yes that's wat i thought but reading
> http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge#Showing_devices_in_a_bridge tells
> me that if i set aging time to 0, it will makes all entry permanent.
>
> The aging time is the number of seconds a MAC address will be
>
> kept in the forwarding database after having received a packet
>
> from this MAC address.
>
> The entries in the forwarding database are periodically timed out
>
> to ensure they won't stay around forever.
>
> Normally there should be no need to modify this parameter,
>
> but it can be changed with (time is in seconds).
>
>
>> # brctl setageing bridgename time
>
>
>> Setting ageing time to zero makes all entries permanent.
>
>
> My bad i did not take time to test it.
>
> Thanks for your answer i will try this!
>
> On Sat, Nov 27, 2010 at 5:16 PM, Stephen Hemminger <
> shemminger@linux-foundation.org> wrote:
>
>> On Sat, 27 Nov 2010 16:46:34 -0500
>> Benjamin Vanheuverzwijn <bvanheu@gmail.com> wrote:
>>
>> > Hi,
>> >
>> > Is there a way to disable the mac address learning in linux using
>> "brctl" or
>> > custom code so any packet sent to the bridge will be flooded in each
>> > interfaces.
>> >
>> > I would like to do something similar as OpenBSD:
>> > $ brconfig <bridge> -learn <iface>
>> > $ man brconfig
>> > ...
>> >      -learn interface
>> >              Mark interface so that the source address of packets
>> received
>> >              from interface are not entered into the address cache.
>> > ...
>> >
>> > I tried to search on google and on the mailing-list without success.
>>
>> Just set ageing time to zero no need for special config option.
>>
>
>
>
> --
> Benjamin Vanheuverzwijn
>
> Google Talk/Jabber - bvanheu@gmail.com
> http://vanheu.ca
>
>
> _______________________________________________
> Bridge mailing list
> Bridge@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/bridge
>

[-- Attachment #2: Type: text/html, Size: 4996 bytes --]

^ permalink raw reply

* Re: [Bridge] Disable mac address learning
From: Benjamin Vanheuverzwijn @ 2010-11-27 22:21 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: bridge
In-Reply-To: <20101127141647.6814f62f@nehalam>

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

Hi,

Yes that's wat i thought but reading
http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge#Showing_devices_in_a_bridge
tells
me that if i set aging time to 0, it will makes all entry permanent.

The aging time is the number of seconds a MAC address will be

kept in the forwarding database after having received a packet

from this MAC address.

The entries in the forwarding database are periodically timed out

to ensure they won't stay around forever.

Normally there should be no need to modify this parameter,

but it can be changed with (time is in seconds).


> # brctl setageing bridgename time


> Setting ageing time to zero makes all entries permanent.


My bad i did not take time to test it.

Thanks for your answer i will try this!

On Sat, Nov 27, 2010 at 5:16 PM, Stephen Hemminger <
shemminger@linux-foundation.org> wrote:

> On Sat, 27 Nov 2010 16:46:34 -0500
> Benjamin Vanheuverzwijn <bvanheu@gmail.com> wrote:
>
> > Hi,
> >
> > Is there a way to disable the mac address learning in linux using "brctl"
> or
> > custom code so any packet sent to the bridge will be flooded in each
> > interfaces.
> >
> > I would like to do something similar as OpenBSD:
> > $ brconfig <bridge> -learn <iface>
> > $ man brconfig
> > ...
> >      -learn interface
> >              Mark interface so that the source address of packets
> received
> >              from interface are not entered into the address cache.
> > ...
> >
> > I tried to search on google and on the mailing-list without success.
>
> Just set ageing time to zero no need for special config option.
>



-- 
Benjamin Vanheuverzwijn

Google Talk/Jabber - bvanheu@gmail.com
http://vanheu.ca

[-- Attachment #2: Type: text/html, Size: 5021 bytes --]

^ permalink raw reply

* Re: [Bridge] Disable mac address learning
From: Stephen Hemminger @ 2010-11-27 22:16 UTC (permalink / raw)
  To: Benjamin Vanheuverzwijn; +Cc: bridge
In-Reply-To: <AANLkTikviZkym71gVp6BZUeiqHjbARhjB-J-mnE_5A6J@mail.gmail.com>

On Sat, 27 Nov 2010 16:46:34 -0500
Benjamin Vanheuverzwijn <bvanheu@gmail.com> wrote:

> Hi,
> 
> Is there a way to disable the mac address learning in linux using "brctl" or
> custom code so any packet sent to the bridge will be flooded in each
> interfaces.
> 
> I would like to do something similar as OpenBSD:
> $ brconfig <bridge> -learn <iface>
> $ man brconfig
> ...
>      -learn interface
>              Mark interface so that the source address of packets received
>              from interface are not entered into the address cache.
> ...
> 
> I tried to search on google and on the mailing-list without success.

Just set ageing time to zero no need for special config option.

^ permalink raw reply

* [Bridge] Disable mac address learning
From: Benjamin Vanheuverzwijn @ 2010-11-27 21:46 UTC (permalink / raw)
  To: bridge

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

Hi,

Is there a way to disable the mac address learning in linux using "brctl" or
custom code so any packet sent to the bridge will be flooded in each
interfaces.

I would like to do something similar as OpenBSD:
$ brconfig <bridge> -learn <iface>
$ man brconfig
...
     -learn interface
             Mark interface so that the source address of packets received
             from interface are not entered into the address cache.
...

I tried to search on google and on the mailing-list without success.

Thanks in advance for your replies,

-- 
Benjamin Vanheuverzwijn

Google Talk/Jabber - bvanheu@gmail.com
http://vanheu.ca

[-- Attachment #2: Type: text/html, Size: 968 bytes --]

^ permalink raw reply

* Re: [Bridge] [PATCH 0/5] bridge: RCU annotation and cleanup
From: Stephen Hemminger @ 2010-11-15 16:19 UTC (permalink / raw)
  To: Tetsuo Handa; +Cc: netdev, bridge, davem, eric.dumazet
In-Reply-To: <201011152123.HHB21896.HFOOVSMFOtLJQF@I-love.SAKURA.ne.jp>

On Mon, 15 Nov 2010 21:23:37 +0900
Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp> wrote:

> > +			rp = rcu_dereference(hlist_next_rcu(rp->next));  
> 
> I think this one is hlist_next_rcu(rp).

Yes, you are correct.

-- 

^ permalink raw reply

* Re: [Bridge] [PATCH 0/5] bridge: RCU annotation and cleanup
From: Eric Dumazet @ 2010-11-15 13:33 UTC (permalink / raw)
  To: Tetsuo Handa; +Cc: netdev, shemminger, bridge, davem
In-Reply-To: <201011152123.HHB21896.HFOOVSMFOtLJQF@I-love.SAKURA.ne.jp>

Le lundi 15 novembre 2010 à 21:23 +0900, Tetsuo Handa a écrit :
> Stephen Hemminger wrote:
> > This is a split up of what Eric did with a couple of small changes and additions.
> Something seems to be wrong with this patchset.
> 
> --- a/net/bridge/br_input.c
> +++ b/net/bridge/br_input.c
> > @@ -173,8 +177,8 @@ forward:
> >  	switch (p->state) {
> >  	case BR_STATE_FORWARDING:
> >  		rhook = rcu_dereference(br_should_route_hook);
> > -		if (rhook != NULL) {
> > -			if (rhook(skb))
> > +		if (rhook) {
> > +			if ((*rhook)(skb))
> 
> Is *rhook != NULL guaranteed when rhook != NULL?

Its the C standard convention, we call function pointed by rhook, not
*rhook.

$ cat func.c
typedef int (*hook_t)(int a1, int a2);

hook_t *hook;

int foo(int a1, int a2)
{
hook_t *handler = hook;

	if (handler)
		return handler(a1, a2);
	return 0;
}
$ gcc -O2 -c func.c
func.c: In function ‘foo’:
func.c:10:17: error: called object ‘handler’ is not a function


Now, if we use (*handler), it works :

$ cat func.c
typedef int (*hook_t)(int a1, int a2);

hook_t *hook;

int foo(int a1, int a2)
{
hook_t *handler = hook;

	if (handler)
		return (*handler)(a1, a2);
	return 0;
}
$ gcc -O2 -c func.c
$




^ permalink raw reply

* Re: [Bridge] [PATCH 0/5] bridge: RCU annotation and cleanup
From: Tetsuo Handa @ 2010-11-15 12:23 UTC (permalink / raw)
  To: shemminger, davem, eric.dumazet; +Cc: netdev, bridge
In-Reply-To: <20101114211201.678755903@vyatta.com>

Stephen Hemminger wrote:
> This is a split up of what Eric did with a couple of small changes and additions.
Something seems to be wrong with this patchset.

--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
> @@ -173,8 +177,8 @@ forward:
>  	switch (p->state) {
>  	case BR_STATE_FORWARDING:
>  		rhook = rcu_dereference(br_should_route_hook);
> -		if (rhook != NULL) {
> -			if (rhook(skb))
> +		if (rhook) {
> +			if ((*rhook)(skb))

Is *rhook != NULL guaranteed when rhook != NULL?

>  				return skb;
>  			dest = eth_hdr(skb)->h_dest;
>  		}

--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
> @@ -242,7 +242,7 @@ static void br_multicast_flood(struct ne
>  		if ((unsigned long)lport >= (unsigned long)port)
>  			p = rcu_dereference(p->next);
>  		if ((unsigned long)rport >= (unsigned long)port)
> -			rp = rcu_dereference(rp->next);
> +			rp = rcu_dereference(hlist_next_rcu(rp->next));

I think this one is hlist_next_rcu(rp).

>  	}
>  
>  	if (!prev)

--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
> @@ -475,11 +475,8 @@ int br_del_if(struct net_bridge *br, str
>  {
>  	struct net_bridge_port *p;
>  
> -	if (!br_port_exists(dev))
> -		return -EINVAL;
> -
>  	p = br_port_get(dev);

Don't you need to use br_port_get_rtnl()?  (I don't know.)

> -	if (p->br != br)
> +	if (!p || p->br != br)
>  		return -EINVAL;
>  
>  	del_nbp(p);

--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
> @@ -169,9 +171,9 @@ static int br_rtm_setlink(struct sk_buff
>  	if (!dev)
>  		return -ENODEV;
>  
> -	if (!br_port_exists(dev))
> -		return -EINVAL;
>  	p = br_port_get(dev);

Don't you need to use br_port_get_rtnl()?  (I don't know.)

> +	if (!p)
> +		return -EINVAL;
>  
>  	/* if kernel STP is running, don't allow changes */
>  	if (p->br->stp_enabled == BR_KERNEL_STP)

--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
> @@ -151,11 +151,21 @@ struct net_bridge_port
>  #endif
>  };
>  
> -#define br_port_get_rcu(dev) \
> -	((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data))
> -#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
>  #define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)
>  
> +static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
> +{
> +	return br_port_exists(dev) ?
> +		rcu_dereference(dev->rx_handler_data) : NULL;
> +}
> +
> +static inline struct net_bridge_port *br_port_get(struct net_device *dev)
> +{
> +	return br_port_exists(dev) ? dev->rx_handler_data : NULL;
> +}
> +
> +#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)

Why are you defining br_port_get() twice, once as macro and once as inlined
function?

^ permalink raw reply

* [Bridge] [PATCH 5/5] bridge: add RCU annotations to bridge port lookup
From: Stephen Hemminger @ 2010-11-14 21:12 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, bridge
In-Reply-To: <20101114211201.678755903@vyatta.com>

[-- Attachment #1: bridgeX.patch --]
[-- Type: text/plain, Size: 2502 bytes --]

From: Eric Dumazet <eric.dumazet@gmail.com>

Add modern __rcu annotations to bridge code, to reduce sparse errors,
and self document code.
(CONFIG_SPARSE_RCU_POINTER=y)

br_port_get() split int br_port_get_rtnl()  and br_port_get_rcu()
to make clear RTNL is held.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 net/bridge/br_if.c      |    2 +-
 net/bridge/br_netlink.c |    4 ++--
 net/bridge/br_notify.c  |    4 ++--
 net/bridge/br_private.h |    9 +++++----
 4 files changed, 10 insertions(+), 9 deletions(-)

--- a/net/bridge/br_netlink.c	2010-11-14 12:24:35.000000000 -0800
+++ b/net/bridge/br_netlink.c	2010-11-14 12:26:47.859892139 -0800
@@ -119,7 +119,7 @@ static int br_dump_ifinfo(struct sk_buff
 
 	idx = 0;
 	for_each_netdev(net, dev) {
-		struct net_bridge_port *port = br_port_get(dev);
+		struct net_bridge_port *port = br_port_get_rtnl(dev);
 
 		/* not a bridge port */
 		if (!port || idx < cb->args[0])
@@ -171,7 +171,7 @@ static int br_rtm_setlink(struct sk_buff
 	if (!dev)
 		return -ENODEV;
 
-	p = br_port_get(dev);
+	p = br_port_get_rtnl(dev);
 	if (!p)
 		return -EINVAL;
 
--- a/net/bridge/br_private.h	2010-11-14 12:25:44.600853008 -0800
+++ b/net/bridge/br_private.h	2010-11-14 12:33:23.880986098 -0800
@@ -159,9 +159,10 @@ static inline struct net_bridge_port *br
 		rcu_dereference(dev->rx_handler_data) : NULL;
 }
 
-static inline struct net_bridge_port *br_port_get(struct net_device *dev)
+static inline struct net_bridge_port *br_port_get_rtnl(struct net_device *dev)
 {
-	return br_port_exists(dev) ? dev->rx_handler_data : NULL;
+	return br_port_exists(dev) ?
+		rtnl_dereference(dev->rx_handler_data) : NULL;
 }
 
 #define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
--- a/net/bridge/br_if.c	2010-11-14 12:23:34.000000000 -0800
+++ b/net/bridge/br_if.c	2010-11-14 12:27:24.267934764 -0800
@@ -475,7 +475,7 @@ int br_del_if(struct net_bridge *br, str
 {
 	struct net_bridge_port *p;
 
-	p = br_port_get(dev);
+	p = br_port_get_rtnl(dev);
 	if (!p || p->br != br)
 		return -EINVAL;
 
--- a/net/bridge/br_notify.c	2010-11-14 12:30:46.250267273 -0800
+++ b/net/bridge/br_notify.c	2010-11-14 12:31:11.749076964 -0800
@@ -37,10 +37,10 @@ static int br_device_event(struct notifi
 	int err;
 
 	/* not a port of a bridge */
-	if (!br_port_exists(dev))
+	p = br_port_get_rtnl(dev);
+	if (!p)
 		return NOTIFY_DONE;
 
-	p = br_port_get(dev);
 	br = p->br;
 
 	switch (event) {



^ permalink raw reply

* [Bridge] [PATCH 4/5] bridge: fix RCU races with bridge port
From: Stephen Hemminger @ 2010-11-14 21:12 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, bridge
In-Reply-To: <20101114211201.678755903@vyatta.com>

[-- Attachment #1: br-port-rcu-race.patch --]
[-- Type: text/plain, Size: 6647 bytes --]

The macro br_port_exists() is not enough protection when only
RCU is being used. There is a tiny race where other CPU has cleared port
handler hook, but is bridge port flag might still be set.


Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 net/bridge/br_fdb.c             |   15 +++++++++------
 net/bridge/br_if.c              |    5 +----
 net/bridge/br_netfilter.c       |   13 +++++++------
 net/bridge/br_netlink.c         |   10 ++++++----
 net/bridge/br_notify.c          |    2 +-
 net/bridge/br_private.h         |   16 +++++++++++++---
 net/bridge/br_stp_bpdu.c        |    8 ++++----
 net/bridge/netfilter/ebtables.c |   11 +++++------
 8 files changed, 46 insertions(+), 34 deletions(-)

--- a/net/bridge/br_netfilter.c	2010-11-14 12:36:22.970441653 -0800
+++ b/net/bridge/br_netfilter.c	2010-11-14 12:44:55.666987357 -0800
@@ -131,17 +131,18 @@ void br_netfilter_rtable_init(struct net
 
 static inline struct rtable *bridge_parent_rtable(const struct net_device *dev)
 {
-	if (!br_port_exists(dev))
-		return NULL;
-	return &br_port_get_rcu(dev)->br->fake_rtable;
+	struct net_bridge_port *port;
+
+	port = br_port_get_rcu(dev);
+	return port ? &port->br->fake_rtable : NULL;
 }
 
 static inline struct net_device *bridge_parent(const struct net_device *dev)
 {
-	if (!br_port_exists(dev))
-		return NULL;
+	struct net_bridge_port *port;
 
-	return br_port_get_rcu(dev)->br->dev;
+	port = br_port_get_rcu(dev);
+	return port ? port->br->dev : NULL;
 }
 
 static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
--- a/net/bridge/br_stp_bpdu.c	2010-11-14 12:36:22.982443121 -0800
+++ b/net/bridge/br_stp_bpdu.c	2010-11-14 12:44:55.666987357 -0800
@@ -141,10 +141,6 @@ void br_stp_rcv(const struct stp_proto *
 	struct net_bridge *br;
 	const unsigned char *buf;
 
-	if (!br_port_exists(dev))
-		goto err;
-	p = br_port_get_rcu(dev);
-
 	if (!pskb_may_pull(skb, 4))
 		goto err;
 
@@ -153,6 +149,10 @@ void br_stp_rcv(const struct stp_proto *
 	if (buf[0] != 0 || buf[1] != 0 || buf[2] != 0)
 		goto err;
 
+	p = br_port_get_rcu(dev);
+	if (!p)
+		goto err;
+
 	br = p->br;
 	spin_lock(&br->lock);
 
--- a/net/bridge/netfilter/ebtables.c	2010-11-14 12:36:22.998445081 -0800
+++ b/net/bridge/netfilter/ebtables.c	2010-11-14 12:45:49.393153060 -0800
@@ -128,6 +128,7 @@ ebt_basic_match(const struct ebt_entry *
                 const struct net_device *in, const struct net_device *out)
 {
 	const struct ethhdr *h = eth_hdr(skb);
+	const struct net_bridge_port *p;
 	__be16 ethproto;
 	int verdict, i;
 
@@ -148,13 +149,11 @@ ebt_basic_match(const struct ebt_entry *
 	if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT))
 		return 1;
 	/* rcu_read_lock()ed by nf_hook_slow */
-	if (in && br_port_exists(in) &&
-	    FWINV2(ebt_dev_check(e->logical_in, br_port_get_rcu(in)->br->dev),
-		   EBT_ILOGICALIN))
+	if (in && (p = br_port_get_rcu(in)) != NULL &&
+	    FWINV2(ebt_dev_check(e->logical_in, p->br->dev), EBT_ILOGICALIN))
 		return 1;
-	if (out && br_port_exists(out) &&
-	    FWINV2(ebt_dev_check(e->logical_out, br_port_get_rcu(out)->br->dev),
-		   EBT_ILOGICALOUT))
+	if (out && (p = br_port_get_rcu(out)) != NULL &&
+	    FWINV2(ebt_dev_check(e->logical_out, p->br->dev), EBT_ILOGICALOUT))
 		return 1;
 
 	if (e->bitmask & EBT_SOURCEMAC) {
--- a/net/bridge/br_fdb.c	2010-11-14 12:36:23.022448019 -0800
+++ b/net/bridge/br_fdb.c	2010-11-14 12:44:55.670987817 -0800
@@ -238,15 +238,18 @@ struct net_bridge_fdb_entry *__br_fdb_ge
 int br_fdb_test_addr(struct net_device *dev, unsigned char *addr)
 {
 	struct net_bridge_fdb_entry *fdb;
+	struct net_bridge_port *port;
 	int ret;
 
-	if (!br_port_exists(dev))
-		return 0;
-
 	rcu_read_lock();
-	fdb = __br_fdb_get(br_port_get_rcu(dev)->br, addr);
-	ret = fdb && fdb->dst->dev != dev &&
-		fdb->dst->state == BR_STATE_FORWARDING;
+	port = br_port_get_rcu(dev);
+	if (!port)
+		ret = 0;
+	else {
+		fdb = __br_fdb_get(port->br, addr);
+		ret = fdb && fdb->dst->dev != dev &&
+			fdb->dst->state == BR_STATE_FORWARDING;
+	}
 	rcu_read_unlock();
 
 	return ret;
--- a/net/bridge/br_notify.c	2010-11-14 12:36:23.034449489 -0800
+++ b/net/bridge/br_notify.c	2010-11-14 12:44:55.670987817 -0800
@@ -32,7 +32,7 @@ struct notifier_block br_device_notifier
 static int br_device_event(struct notifier_block *unused, unsigned long event, void *ptr)
 {
 	struct net_device *dev = ptr;
-	struct net_bridge_port *p = br_port_get(dev);
+	struct net_bridge_port *p;
 	struct net_bridge *br;
 	int err;
 
--- a/net/bridge/br_private.h	2010-11-14 12:44:07.257410977 -0800
+++ b/net/bridge/br_private.h	2010-11-14 12:44:55.670987817 -0800
@@ -151,11 +151,21 @@ struct net_bridge_port
 #endif
 };
 
-#define br_port_get_rcu(dev) \
-	((struct net_bridge_port *) rcu_dereference(dev->rx_handler_data))
-#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
 #define br_port_exists(dev) (dev->priv_flags & IFF_BRIDGE_PORT)
 
+static inline struct net_bridge_port *br_port_get_rcu(const struct net_device *dev)
+{
+	return br_port_exists(dev) ?
+		rcu_dereference(dev->rx_handler_data) : NULL;
+}
+
+static inline struct net_bridge_port *br_port_get(struct net_device *dev)
+{
+	return br_port_exists(dev) ? dev->rx_handler_data : NULL;
+}
+
+#define br_port_get(dev) ((struct net_bridge_port *) dev->rx_handler_data)
+
 struct br_cpu_netstats {
 	u64			rx_packets;
 	u64			rx_bytes;
--- a/net/bridge/br_if.c	2010-11-14 12:36:23.046450958 -0800
+++ b/net/bridge/br_if.c	2010-11-14 12:44:55.670987817 -0800
@@ -475,11 +475,8 @@ int br_del_if(struct net_bridge *br, str
 {
 	struct net_bridge_port *p;
 
-	if (!br_port_exists(dev))
-		return -EINVAL;
-
 	p = br_port_get(dev);
-	if (p->br != br)
+	if (!p || p->br != br)
 		return -EINVAL;
 
 	del_nbp(p);
--- a/net/bridge/br_netlink.c	2010-11-14 12:36:23.062452917 -0800
+++ b/net/bridge/br_netlink.c	2010-11-14 12:44:55.670987817 -0800
@@ -119,11 +119,13 @@ static int br_dump_ifinfo(struct sk_buff
 
 	idx = 0;
 	for_each_netdev(net, dev) {
+		struct net_bridge_port *port = br_port_get(dev);
+
 		/* not a bridge port */
-		if (!br_port_exists(dev) || idx < cb->args[0])
+		if (!port || idx < cb->args[0])
 			goto skip;
 
-		if (br_fill_ifinfo(skb, br_port_get(dev),
+		if (br_fill_ifinfo(skb, port,
 				   NETLINK_CB(cb->skb).pid,
 				   cb->nlh->nlmsg_seq, RTM_NEWLINK,
 				   NLM_F_MULTI) < 0)
@@ -169,9 +171,9 @@ static int br_rtm_setlink(struct sk_buff
 	if (!dev)
 		return -ENODEV;
 
-	if (!br_port_exists(dev))
-		return -EINVAL;
 	p = br_port_get(dev);
+	if (!p)
+		return -EINVAL;
 
 	/* if kernel STP is running, don't allow changes */
 	if (p->br->stp_enabled == BR_KERNEL_STP)



^ permalink raw reply

* [Bridge] [PATCH 3/5] netdev: add rcu annotations to receive handler hook
From: Stephen Hemminger @ 2010-11-14 21:12 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, bridge
In-Reply-To: <20101114211201.678755903@vyatta.com>

[-- Attachment #1: rx_handler_rcu.patch --]
[-- Type: text/plain, Size: 595 bytes --]

Suggested by Eric's bridge RCU changes.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 include/linux/netdevice.h |    4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--- a/include/linux/netdevice.h	2010-11-14 11:41:53.224298362 -0800
+++ b/include/linux/netdevice.h	2010-11-14 11:42:42.546359900 -0800
@@ -995,8 +995,8 @@ struct net_device {
 	unsigned int		real_num_rx_queues;
 #endif
 
-	rx_handler_func_t	*rx_handler;
-	void			*rx_handler_data;
+	rx_handler_func_t __rcu	*rx_handler;
+	void __rcu		*rx_handler_data;
 
 	struct netdev_queue __rcu *ingress_queue;
 



^ permalink raw reply

* [Bridge] [PATCH 2/5] bridge: add proper RCU annotation to should_route_hook
From: Stephen Hemminger @ 2010-11-14 21:12 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, bridge
In-Reply-To: <20101114211201.678755903@vyatta.com>

[-- Attachment #1: bridge-hook-typedef.patch --]
[-- Type: text/plain, Size: 3022 bytes --]

From: Eric Dumazet <eric.dumazet@gmail.com>

Add br_should_route_hook_t typedef, this is the only way we can
get a clean RCU implementation for function pointer.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>

---
 include/linux/if_bridge.h             |    4 +++-
 net/bridge/br.c                       |    4 ----
 net/bridge/br_input.c                 |   10 +++++++---
 net/bridge/netfilter/ebtable_broute.c |    3 ++-
 4 files changed, 12 insertions(+), 9 deletions(-)

--- a/net/bridge/br.c	2010-11-14 11:18:54.048692005 -0800
+++ b/net/bridge/br.c	2010-11-14 11:19:47.347027185 -0800
@@ -22,8 +22,6 @@
 
 #include "br_private.h"
 
-int (*br_should_route_hook)(struct sk_buff *skb);
-
 static const struct stp_proto br_stp_proto = {
 	.rcv	= br_stp_rcv,
 };
@@ -102,8 +100,6 @@ static void __exit br_deinit(void)
 	br_fdb_fini();
 }
 
-EXPORT_SYMBOL(br_should_route_hook);
-
 module_init(br_init)
 module_exit(br_deinit)
 MODULE_LICENSE("GPL");
--- a/net/bridge/br_input.c	2010-11-14 11:18:54.048692005 -0800
+++ b/net/bridge/br_input.c	2010-11-14 11:41:40.558700481 -0800
@@ -21,6 +21,10 @@
 /* Bridge group multicast address 802.1d (pg 51). */
 const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
 
+/* Hook for brouter */
+br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
+EXPORT_SYMBOL(br_should_route_hook);
+
 static int br_pass_frame_up(struct sk_buff *skb)
 {
 	struct net_device *indev, *brdev = BR_INPUT_SKB_CB(skb)->brdev;
@@ -139,7 +143,7 @@ struct sk_buff *br_handle_frame(struct s
 {
 	struct net_bridge_port *p;
 	const unsigned char *dest = eth_hdr(skb)->h_dest;
-	int (*rhook)(struct sk_buff *skb);
+	br_should_route_hook_t *rhook;
 
 	if (unlikely(skb->pkt_type == PACKET_LOOPBACK))
 		return skb;
@@ -173,8 +177,8 @@ forward:
 	switch (p->state) {
 	case BR_STATE_FORWARDING:
 		rhook = rcu_dereference(br_should_route_hook);
-		if (rhook != NULL) {
-			if (rhook(skb))
+		if (rhook) {
+			if ((*rhook)(skb))
 				return skb;
 			dest = eth_hdr(skb)->h_dest;
 		}
--- a/include/linux/if_bridge.h	2010-11-14 11:18:54.048692005 -0800
+++ b/include/linux/if_bridge.h	2010-11-14 11:19:47.351028008 -0800
@@ -102,7 +102,9 @@ struct __fdb_entry {
 #include <linux/netdevice.h>
 
 extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *));
-extern int (*br_should_route_hook)(struct sk_buff *skb);
+
+typedef int (*br_should_route_hook_t)(struct sk_buff *skb);
+extern br_should_route_hook_t __rcu *br_should_route_hook;
 
 #endif
 
--- a/net/bridge/netfilter/ebtable_broute.c	2010-11-14 11:20:39.745149494 -0800
+++ b/net/bridge/netfilter/ebtable_broute.c	2010-11-14 11:21:01.020917528 -0800
@@ -87,7 +87,8 @@ static int __init ebtable_broute_init(vo
 	if (ret < 0)
 		return ret;
 	/* see br_input.c */
-	rcu_assign_pointer(br_should_route_hook, ebt_broute);
+	rcu_assign_pointer(br_should_route_hook,
+			   (br_should_route_hook_t *)ebt_broute);
 	return 0;
 }
 



^ permalink raw reply

* [Bridge] [PATCH 1/5] bridge: add RCU annotation to bridge multicast table
From: Stephen Hemminger @ 2010-11-14 21:12 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, bridge
In-Reply-To: <20101114211201.678755903@vyatta.com>

[-- Attachment #1: bridge-mlock-rcu.patch --]
[-- Type: text/plain, Size: 10144 bytes --]

From: Eric Dumazet <eric.dumazet@gmail.com>

Add modern __rcu annotatations to bridge multicast table.

Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>


---
 net/bridge/br_forward.c   |    4 +-
 net/bridge/br_multicast.c |   78 ++++++++++++++++++++++++++++++----------------
 net/bridge/br_private.h   |    6 +--
 3 files changed, 56 insertions(+), 32 deletions(-)

--- a/net/bridge/br_multicast.c	2010-11-14 12:36:30.383348571 -0800
+++ b/net/bridge/br_multicast.c	2010-11-14 12:36:37.084167303 -0800
@@ -33,6 +33,9 @@
 
 #include "br_private.h"
 
+#define mlock_dereference(X, br) \
+	rcu_dereference_protected(X, lockdep_is_held(&br->multicast_lock))
+
 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 static inline int ipv6_is_local_multicast(const struct in6_addr *addr)
 {
@@ -135,7 +138,7 @@ static struct net_bridge_mdb_entry *br_m
 struct net_bridge_mdb_entry *br_mdb_get(struct net_bridge *br,
 					struct sk_buff *skb)
 {
-	struct net_bridge_mdb_htable *mdb = br->mdb;
+	struct net_bridge_mdb_htable *mdb = rcu_dereference(br->mdb);
 	struct br_ip ip;
 
 	if (br->multicast_disabled)
@@ -235,7 +238,8 @@ static void br_multicast_group_expired(u
 	if (mp->ports)
 		goto out;
 
-	mdb = br->mdb;
+	mdb = mlock_dereference(br->mdb, br);
+
 	hlist_del_rcu(&mp->hlist[mdb->ver]);
 	mdb->size--;
 
@@ -249,16 +253,20 @@ out:
 static void br_multicast_del_pg(struct net_bridge *br,
 				struct net_bridge_port_group *pg)
 {
-	struct net_bridge_mdb_htable *mdb = br->mdb;
+	struct net_bridge_mdb_htable *mdb;
 	struct net_bridge_mdb_entry *mp;
 	struct net_bridge_port_group *p;
-	struct net_bridge_port_group **pp;
+	struct net_bridge_port_group __rcu **pp;
+
+	mdb = mlock_dereference(br->mdb, br);
 
 	mp = br_mdb_ip_get(mdb, &pg->addr);
 	if (WARN_ON(!mp))
 		return;
 
-	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+	for (pp = &mp->ports;
+	     (p = mlock_dereference(*pp, br)) != NULL;
+	     pp = &p->next) {
 		if (p != pg)
 			continue;
 
@@ -294,10 +302,10 @@ out:
 	spin_unlock(&br->multicast_lock);
 }
 
-static int br_mdb_rehash(struct net_bridge_mdb_htable **mdbp, int max,
+static int br_mdb_rehash(struct net_bridge_mdb_htable __rcu **mdbp, int max,
 			 int elasticity)
 {
-	struct net_bridge_mdb_htable *old = *mdbp;
+	struct net_bridge_mdb_htable *old = rcu_dereference_protected(*mdbp, 1);
 	struct net_bridge_mdb_htable *mdb;
 	int err;
 
@@ -569,7 +577,7 @@ static struct net_bridge_mdb_entry *br_m
 	struct net_bridge *br, struct net_bridge_port *port,
 	struct br_ip *group, int hash)
 {
-	struct net_bridge_mdb_htable *mdb = br->mdb;
+	struct net_bridge_mdb_htable *mdb;
 	struct net_bridge_mdb_entry *mp;
 	struct hlist_node *p;
 	unsigned count = 0;
@@ -577,6 +585,7 @@ static struct net_bridge_mdb_entry *br_m
 	int elasticity;
 	int err;
 
+	mdb = rcu_dereference_protected(br->mdb, 1);
 	hlist_for_each_entry(mp, p, &mdb->mhash[hash], hlist[mdb->ver]) {
 		count++;
 		if (unlikely(br_ip_equal(group, &mp->addr)))
@@ -642,10 +651,11 @@ static struct net_bridge_mdb_entry *br_m
 	struct net_bridge *br, struct net_bridge_port *port,
 	struct br_ip *group)
 {
-	struct net_bridge_mdb_htable *mdb = br->mdb;
+	struct net_bridge_mdb_htable *mdb;
 	struct net_bridge_mdb_entry *mp;
 	int hash;
 
+	mdb = rcu_dereference_protected(br->mdb, 1);
 	if (!mdb) {
 		if (br_mdb_rehash(&br->mdb, BR_HASH_SIZE, 0))
 			return NULL;
@@ -660,7 +670,7 @@ static struct net_bridge_mdb_entry *br_m
 
 	case -EAGAIN:
 rehash:
-		mdb = br->mdb;
+		mdb = rcu_dereference_protected(br->mdb, 1);
 		hash = br_ip_hash(mdb, group);
 		break;
 
@@ -692,7 +702,7 @@ static int br_multicast_add_group(struct
 {
 	struct net_bridge_mdb_entry *mp;
 	struct net_bridge_port_group *p;
-	struct net_bridge_port_group **pp;
+	struct net_bridge_port_group __rcu **pp;
 	unsigned long now = jiffies;
 	int err;
 
@@ -712,7 +722,9 @@ static int br_multicast_add_group(struct
 		goto out;
 	}
 
-	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+	for (pp = &mp->ports;
+	     (p = mlock_dereference(*pp, br)) != NULL;
+	     pp = &p->next) {
 		if (p->port == port)
 			goto found;
 		if ((unsigned long)p->port < (unsigned long)port)
@@ -1106,7 +1118,7 @@ static int br_ip4_multicast_query(struct
 	struct net_bridge_mdb_entry *mp;
 	struct igmpv3_query *ih3;
 	struct net_bridge_port_group *p;
-	struct net_bridge_port_group **pp;
+	struct net_bridge_port_group __rcu **pp;
 	unsigned long max_delay;
 	unsigned long now = jiffies;
 	__be32 group;
@@ -1145,7 +1157,7 @@ static int br_ip4_multicast_query(struct
 	if (!group)
 		goto out;
 
-	mp = br_mdb_ip4_get(br->mdb, group);
+	mp = br_mdb_ip4_get(mlock_dereference(br->mdb, br), group);
 	if (!mp)
 		goto out;
 
@@ -1157,7 +1169,9 @@ static int br_ip4_multicast_query(struct
 	     try_to_del_timer_sync(&mp->timer) >= 0))
 		mod_timer(&mp->timer, now + max_delay);
 
-	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+	for (pp = &mp->ports;
+	     (p = mlock_dereference(*pp, br)) != NULL;
+	     pp = &p->next) {
 		if (timer_pending(&p->timer) ?
 		    time_after(p->timer.expires, now + max_delay) :
 		    try_to_del_timer_sync(&p->timer) >= 0)
@@ -1178,7 +1192,8 @@ static int br_ip6_multicast_query(struct
 	struct mld_msg *mld = (struct mld_msg *) icmp6_hdr(skb);
 	struct net_bridge_mdb_entry *mp;
 	struct mld2_query *mld2q;
-	struct net_bridge_port_group *p, **pp;
+	struct net_bridge_port_group *p;
+	struct net_bridge_port_group __rcu **pp;
 	unsigned long max_delay;
 	unsigned long now = jiffies;
 	struct in6_addr *group = NULL;
@@ -1214,7 +1229,7 @@ static int br_ip6_multicast_query(struct
 	if (!group)
 		goto out;
 
-	mp = br_mdb_ip6_get(br->mdb, group);
+	mp = br_mdb_ip6_get(mlock_dereference(br->mdb, br), group);
 	if (!mp)
 		goto out;
 
@@ -1225,7 +1240,9 @@ static int br_ip6_multicast_query(struct
 	     try_to_del_timer_sync(&mp->timer) >= 0))
 		mod_timer(&mp->timer, now + max_delay);
 
-	for (pp = &mp->ports; (p = *pp); pp = &p->next) {
+	for (pp = &mp->ports;
+	     (p = mlock_dereference(*pp, br)) != NULL;
+	     pp = &p->next) {
 		if (timer_pending(&p->timer) ?
 		    time_after(p->timer.expires, now + max_delay) :
 		    try_to_del_timer_sync(&p->timer) >= 0)
@@ -1254,7 +1271,7 @@ static void br_multicast_leave_group(str
 	    timer_pending(&br->multicast_querier_timer))
 		goto out;
 
-	mdb = br->mdb;
+	mdb = mlock_dereference(br->mdb, br);
 	mp = br_mdb_ip_get(mdb, group);
 	if (!mp)
 		goto out;
@@ -1277,7 +1294,9 @@ static void br_multicast_leave_group(str
 		goto out;
 	}
 
-	for (p = mp->ports; p; p = p->next) {
+	for (p = mlock_dereference(mp->ports, br);
+	     p != NULL;
+	     p = mlock_dereference(p->next, br)) {
 		if (p->port != port)
 			continue;
 
@@ -1625,7 +1644,7 @@ void br_multicast_stop(struct net_bridge
 	del_timer_sync(&br->multicast_query_timer);
 
 	spin_lock_bh(&br->multicast_lock);
-	mdb = br->mdb;
+	mdb = mlock_dereference(br->mdb, br);
 	if (!mdb)
 		goto out;
 
@@ -1729,6 +1748,7 @@ int br_multicast_toggle(struct net_bridg
 {
 	struct net_bridge_port *port;
 	int err = 0;
+	struct net_bridge_mdb_htable *mdb;
 
 	spin_lock(&br->multicast_lock);
 	if (br->multicast_disabled == !val)
@@ -1741,15 +1761,16 @@ int br_multicast_toggle(struct net_bridg
 	if (!netif_running(br->dev))
 		goto unlock;
 
-	if (br->mdb) {
-		if (br->mdb->old) {
+	mdb = mlock_dereference(br->mdb, br);
+	if (mdb) {
+		if (mdb->old) {
 			err = -EEXIST;
 rollback:
 			br->multicast_disabled = !!val;
 			goto unlock;
 		}
 
-		err = br_mdb_rehash(&br->mdb, br->mdb->max,
+		err = br_mdb_rehash(&br->mdb, mdb->max,
 				    br->hash_elasticity);
 		if (err)
 			goto rollback;
@@ -1774,6 +1795,7 @@ int br_multicast_set_hash_max(struct net
 {
 	int err = -ENOENT;
 	u32 old;
+	struct net_bridge_mdb_htable *mdb;
 
 	spin_lock(&br->multicast_lock);
 	if (!netif_running(br->dev))
@@ -1782,7 +1804,9 @@ int br_multicast_set_hash_max(struct net
 	err = -EINVAL;
 	if (!is_power_of_2(val))
 		goto unlock;
-	if (br->mdb && val < br->mdb->size)
+
+	mdb = mlock_dereference(br->mdb, br);
+	if (mdb && val < mdb->size)
 		goto unlock;
 
 	err = 0;
@@ -1790,8 +1814,8 @@ int br_multicast_set_hash_max(struct net
 	old = br->hash_max;
 	br->hash_max = val;
 
-	if (br->mdb) {
-		if (br->mdb->old) {
+	if (mdb) {
+		if (mdb->old) {
 			err = -EEXIST;
 rollback:
 			br->hash_max = old;
--- a/net/bridge/br_private.h	2010-11-14 12:36:30.399350527 -0800
+++ b/net/bridge/br_private.h	2010-11-14 12:44:07.257410977 -0800
@@ -72,7 +72,7 @@ struct net_bridge_fdb_entry
 
 struct net_bridge_port_group {
 	struct net_bridge_port		*port;
-	struct net_bridge_port_group	*next;
+	struct net_bridge_port_group __rcu *next;
 	struct hlist_node		mglist;
 	struct rcu_head			rcu;
 	struct timer_list		timer;
@@ -86,7 +86,7 @@ struct net_bridge_mdb_entry
 	struct hlist_node		hlist[2];
 	struct hlist_node		mglist;
 	struct net_bridge		*br;
-	struct net_bridge_port_group	*ports;
+	struct net_bridge_port_group __rcu *ports;
 	struct rcu_head			rcu;
 	struct timer_list		timer;
 	struct timer_list		query_timer;
@@ -227,7 +227,7 @@ struct net_bridge
 	unsigned long			multicast_startup_query_interval;
 
 	spinlock_t			multicast_lock;
-	struct net_bridge_mdb_htable	*mdb;
+	struct net_bridge_mdb_htable __rcu *mdb;
 	struct hlist_head		router_list;
 	struct hlist_head		mglist;
 
--- a/net/bridge/br_forward.c	2010-11-14 12:36:47.833478598 -0800
+++ b/net/bridge/br_forward.c	2010-11-14 12:42:22.001208297 -0800
@@ -223,7 +223,7 @@ static void br_multicast_flood(struct ne
 	struct net_bridge_port_group *p;
 	struct hlist_node *rp;
 
-	rp = rcu_dereference(br->router_list.first);
+	rp = rcu_dereference(hlist_first_rcu(&br->router_list));
 	p = mdst ? rcu_dereference(mdst->ports) : NULL;
 	while (p || rp) {
 		struct net_bridge_port *port, *lport, *rport;
@@ -242,7 +242,7 @@ static void br_multicast_flood(struct ne
 		if ((unsigned long)lport >= (unsigned long)port)
 			p = rcu_dereference(p->next);
 		if ((unsigned long)rport >= (unsigned long)port)
-			rp = rcu_dereference(rp->next);
+			rp = rcu_dereference(hlist_next_rcu(rp->next));
 	}
 
 	if (!prev)



^ permalink raw reply

* [Bridge] [PATCH 0/5] bridge: RCU annotation and cleanup
From: Stephen Hemminger @ 2010-11-14 21:12 UTC (permalink / raw)
  To: David Miller, Eric Dumazet; +Cc: netdev, bridge

This is a split up of what Eric did with a couple of small changes and additions.


^ permalink raw reply

* [Bridge] Testing bridge setup with packet generator and qemu
From: Kfir Lavi @ 2010-11-14 17:45 UTC (permalink / raw)
  To: bridge
In-Reply-To: <AANLkTi=uyEveZf7+XLo0+mV48CFjsuzrTmkTi5Xbn_Dr@mail.gmail.com>

Hi,
I would like to test a simple bridge setup.
br0 have eth0 and eth1
I want to create a fake traffic and see it crossing the bridge.
My main goal is to write a local script that will run tests locally on
the ebtables rules as I change them.
Lets say i'm generating arp packet with nemesis:
nemesis arp -v -d eth0 -S $SRC -D $DST -h $SRC_MAC -m $DST_MAC # request
nemesis arp -v -r -d eth0 -S $DST -D $SRC -h $DST_MAC -m $SRC_MAC # reply

This shows on eth0 tcpdump but not on eth1 tcpdump
Why the bridge doesn't forward to eth1 the arp packets?

I have a gentoo rootfs.
qemu nics are define like this:
 -net nic,model=rtl8139,vlan=0 -net user,vlan=0 \
 -net nic,model=rtl8139,vlan=1

Regards,
Kfir

^ permalink raw reply

* Re: [Bridge] rtnl_lock() imbalance
From: Joakim Tjernlund @ 2010-11-08 15:46 UTC (permalink / raw)
  Cc: bridge
In-Reply-To: <OFAE05463C.86F75967-ONC12577D5.0053E748-C12577D5.005430C9@LocalDomain>

Joakim Tjernlund/Transmode wrote on 2010/11/08 16:19:35:
>
> Trying to hunt down an rtnl_lock bug, br_add_bridge looks funny, it
> takes the rtnl_lock but doesn't release it in case of error. Bug?

ehh, missed that last goto out;
So no imbalance, sorry for the noise

>
> int br_add_bridge(struct net *net, const char *name)
> {
>  struct net_device *dev;
>  int ret;
>
>  dev = new_bridge_dev(net, name);
>  if (!dev)
>   return -ENOMEM;
>
>  rtnl_lock();
>  if (strchr(dev->name, '%')) {
>   ret = dev_alloc_name(dev, dev->name);
>   if (ret < 0)
>    goto out_free;
>  }
>
>  SET_NETDEV_DEVTYPE(dev, &br_type);
>
>  ret = register_netdevice(dev);
>  if (ret)
>   goto out_free;
>
>  ret = br_sysfs_addbr(dev);
>  if (ret)
>   unregister_netdevice(dev);
>  out:
>  rtnl_unlock();
>  return ret;
>
> out_free:
>  free_netdev(dev);
>  goto out;
> }


^ permalink raw reply

* [Bridge] rtnl_lock() imbalance
From: Joakim Tjernlund @ 2010-11-08 15:19 UTC (permalink / raw)
  To: bridge


Trying to hunt down an rtnl_lock bug, br_add_bridge looks funny, it
takes the rtnl_lock but doesn't release it in case of error. Bug?

int br_add_bridge(struct net *net, const char *name)
{
	struct net_device *dev;
	int ret;

	dev = new_bridge_dev(net, name);
	if (!dev)
		return -ENOMEM;

	rtnl_lock();
	if (strchr(dev->name, '%')) {
		ret = dev_alloc_name(dev, dev->name);
		if (ret < 0)
			goto out_free;
	}

	SET_NETDEV_DEVTYPE(dev, &br_type);

	ret = register_netdevice(dev);
	if (ret)
		goto out_free;

	ret = br_sysfs_addbr(dev);
	if (ret)
		unregister_netdevice(dev);
 out:
	rtnl_unlock();
	return ret;

out_free:
	free_netdev(dev);
	goto out;
}


^ permalink raw reply

* Re: [Bridge] DHCP problem on bridge
From: Liew Kian Yang @ 2010-11-08  1:33 UTC (permalink / raw)
  To: 'Stephen Hemminger', 'Kian Yang Liew'; +Cc: bridge
In-Reply-To: <20101106212640.6d88c5d3@nehalam>

Dear Stephen, 


Thank you for your information. I will try and let you know the result :)


Regards,
Kian Yang, Liew

-----Original Message-----
From: Stephen Hemminger [mailto:shemminger@linux-foundation.org] 
Sent: 2010年11月7日 12:27
To: Kian Yang Liew
Cc: bridge@linux-foundation.org; Liew Kian Yang
Subject: Re: [Bridge] DHCP problem on bridge

On Sun, 31 Oct 2010 00:31:11 +0800
Kian Yang Liew <liewkianyang@gmail.com> wrote:

> Dear All,
> 
> 
> 
> I have a network with 500 vlan and I bind all these 500 vlan into 1 bridge
> interface. Then I have run a dhcp server on this bridge interface to
provide
> dhcp to all the computer in the vlan. It look find all the time, but
> sometime, some of the computer on vlan will not able to get the ip from
dhcp
> server but after I remove the vlan and add back to the bridge it will work
> again. The most serious case is sometime there will be a dhcp problem on
> vlan 1 as well, and I need to reboot the server only can make the service
> back to normal.
> 
> 
> 
> The setting is as below
> 
> 
> 
> 
> 
> Vconfig add eth1 2
> 
> Vconfig add eth1 3
> 
> .
> 
> .
> 
> .
> 
> .
> 
> .
> 
> .vconfig add eth1 500
> 
> 
> 
> Then ifconfig eth1.2 up …. Ifconfig eth1.500 up
> 
> Then brctl addbr br1, brctl addif br1 eth1.2 ……. Brctl addif br1
eth1.500
> 
> 
> 
> Does anyone have face this problem before? Your reply is highly
appreciate.
> 

brctl stp br0 off
brctl setfd br0 0


^ permalink raw reply

* Re: [Bridge] DHCP problem on bridge
From: Stephen Hemminger @ 2010-11-07  4:26 UTC (permalink / raw)
  To: Kian Yang Liew; +Cc: Liew Kian Yang, bridge
In-Reply-To: <AANLkTinqo2AXeHMv-p261BJoTGT2Df=zm6uEu+7QYmaH@mail.gmail.com>

On Sun, 31 Oct 2010 00:31:11 +0800
Kian Yang Liew <liewkianyang@gmail.com> wrote:

> Dear All,
> 
> 
> 
> I have a network with 500 vlan and I bind all these 500 vlan into 1 bridge
> interface. Then I have run a dhcp server on this bridge interface to provide
> dhcp to all the computer in the vlan. It look find all the time, but
> sometime, some of the computer on vlan will not able to get the ip from dhcp
> server but after I remove the vlan and add back to the bridge it will work
> again. The most serious case is sometime there will be a dhcp problem on
> vlan 1 as well, and I need to reboot the server only can make the service
> back to normal.
> 
> 
> 
> The setting is as below
> 
> 
> 
> 
> 
> Vconfig add eth1 2
> 
> Vconfig add eth1 3
> 
> .
> 
> .
> 
> .
> 
> .
> 
> .
> 
> .vconfig add eth1 500
> 
> 
> 
> Then ifconfig eth1.2 up …. Ifconfig eth1.500 up
> 
> Then brctl addbr br1, brctl addif br1 eth1.2 ……. Brctl addif br1 eth1.500
> 
> 
> 
> Does anyone have face this problem before? Your reply is highly appreciate.
> 

brctl stp br0 off
brctl setfd br0 0


^ permalink raw reply

* [Bridge] STP timer active even when STP is disabled
From: Jean-Michel Hautbois @ 2010-11-02  7:39 UTC (permalink / raw)
  To: bridge

Hi all,

I am facing some latency issues, mainly due to timer issues.
I have looked at the timer stats and I can see several timers coming
from the bridge.

In fact, I do not understand this piece of code :
In net/bridge/br_if.c in function new_bridge_dev there is an
unconditionnal call to br_stp_timer_init().

In my use case, I do not have STP enabled. Why do we have these timers
activated ? Is this a normal behaviour ?

Thanks in advance for your answer.

Best Regards,
JM

^ permalink raw reply

* Re: [Bridge] Transparent wired/wirless bridge: is it possible?
From: Ryan Whelan @ 2010-11-01 12:49 UTC (permalink / raw)
  To: Mauro Condarelli; +Cc: bridge
In-Reply-To: <4CCC45E9.7070801@mclink.it>

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

hostapd puts the interface into the bridge when it starts up- but you have
to put it in the config. in your hostpad.conf add 'bridge=br0' (making sure
of course you have the correct 'interface= ' set.) search for 'bridge' on
this page: http://wireless.kernel.org/en/users/Documentation/hostapd

once setup, hostapd should put the interface in the bridge at start up and
remove it at shutdown so you take the interface out of the interfaces file.

HTH

On Sat, Oct 30, 2010 at 12:20 PM, Mauro Condarelli <mc5686@mclink.it> wrote:

>  On 26/10/2010 14.36, Ryan Whelan wrote:
>
> Have you looked at hostapd (http://hostap.epitest.fi/hostapd/)?
>
> Sorry,
> I was not clear enough.
>
> I have the wireless card up-and-running in ap-mode using hostapd.
> I *can* connect a laptop to the wireless Access Point.
> I also know how to setup a masquerading router on the linux machine to
> share the landline connection (e.g.: using firestarter).
> This would create a second net for wireless with double natting.
> I would like to avoid this and I'm looking for a "bridge" configuration so
> that all machines (wireless & wired) can share the same subnet (
> 192.68.1.0/24).
>
> I tried something like:
> =====================
> auto lo
> iface lo inet loopback
>
> auto wlan2
> iface wlan2 inet manual
>     up /usr/sbin/service hostapd start
>     up /sbin/ifconfig wlan2 up
>     down /sbin/ifconfig wlan2 down
>     down /usr/sbin/service hostapd stop
>
> auto eth2
> iface eth2 inet manual
>     up /sbin/ifconfig eth2 up
>     down /sbin/ifconfig eth2 down
>
> auto br0
> iface br0 inet dhcp
>     bridge_ports eth2 wlan2
>     bridge_maxwait 0
> =====================
> ... but it does not seem to work as hoped.
>
> Thanks in Advance for *ANY* hint ;)
>
> Regards
> Mauro
>
>
> On Tue, Oct 26, 2010 at 5:24 AM, Mauro Condarelli <mc5686@mclink.it>wrote:
>
>> Hi,
>> I read a lot on the Internet, but didn't find quite what I need.
>> I'm not even sure it's possible.
>>
>> I have a machine with ethernet access and wireless card (in master mode).
>> Both are running ok under ubuntu maverick.
>> I also have a separate firewall (wired) acting as DHCP server for my
>> whole home network.
>> I would like to bind the two interfaces together with no translation (no
>> NAT, SNAT, masquerading, ...) so that the machines connecting to the
>> wireless lan can get their address from the firewall and access the
>> Internet.
>>
>> Is this possible with bridging?
>> If so: can someone point me to the right documentation?
>>
>> TiA
>> Mauro
>> _______________________________________________
>> Bridge mailing list
>> Bridge@lists.linux-foundation.org
>> https://lists.linux-foundation.org/mailman/listinfo/bridge
>>
>
>
>
> _____________________________________
> This e-mail and any attachments from Toyota Boshoku America
> (TBA), TrimMasters Inc. (TMI), or other affiliated companies may
> contain confidential and privileged information.
>
> If you are not the intended recipient, please notify the sender
> immediately by return e-mail, delete this e-mail and destroy any
> copies.
>
> Any dissemination or use of this information by a person other
> than the intended recipient is unauthorized and may be illegal.
>
> _______________________________________________
> Bridge mailing list
> Bridge@lists.linux-foundation.org
> https://lists.linux-foundation.org/mailman/listinfo/bridge
>

[-- Attachment #2: Type: text/html, Size: 5514 bytes --]

^ permalink raw reply

* Re: [Bridge] Transparent wired/wirless bridge: is it possible?
From: Mauro Condarelli @ 2010-11-01 12:40 UTC (permalink / raw)
  To: Nicolas de Pesloüan; +Cc: bridge
In-Reply-To: <4CCC9940.8000700@free.fr>

  Il 31/10/2010 00:16, Nicolas de Pesloüan ha scritto:
> Le 30/10/2010 18:20, Mauro Condarelli a écrit :
>>
>> I tried something like:
>> =====================
>> auto lo
>> iface lo inet loopback
>>
>> auto wlan2
>> iface wlan2 inet manual
>> up /usr/sbin/service hostapd start
>> up /sbin/ifconfig wlan2 up
>> down /sbin/ifconfig wlan2 down
>> down /usr/sbin/service hostapd stop
>>
>> auto eth2
>> iface eth2 inet manual
>> up /sbin/ifconfig eth2 up
>> down /sbin/ifconfig eth2 down
>>
>> auto br0
>> iface br0 inet dhcp
>> bridge_ports eth2 wlan2
>> bridge_maxwait 0
>> =====================
>> ... but it does not seem to work as hoped.
>
> Consider reading 
> http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge, 
> in particular the following sections :
>
> - 7.11 What can be bridged?
> - 7.16 It doesn't work with my Wireless card!
> - 7.17 I still don't understand!!
>
>     Nicolas.
Thanks for the pointer.
I assume the short answer (gleamed from the above link) is: "this can't 
be done (easily)".

I have it working now without bridges using hostapd, dnsmasq and a 
static route in the upstream router (ipfire).

This has the (small) drawback I have a second subnet and a largely 
useless dnsmaq installed.

My setup is with a separate firewall (ipfire) connected to the Internet; 
on the GREEN LAN I have another server with an "Atheros Communications 
Inc. AR928X Wireless Network Adapter (PCI-Express) (rev 01)" managed via 
ath9k and hostapd.
On "server" (ubuntu-workstation 10.10; I had some problems convincing 
NetworkManager not to meddle with the interfaces) I have:
========================
auto wlan2
iface wlan2 inet static
     address 192.168.2.1
     netmask 255.255.255.0
     broadcast 192.168.2.255

auto eth2
iface eth2 inet dhcp # gets address from ipfire in the range 
192.168.1.100-129
========================
IPV4 routing is enabled.
hostapd and dnsmasq are set and configured.

On "ipfire" I have the additional static route
========================
route add -net 192.168.2.0/24 gw server
========================



Any comment?
Can I simplify?
Is this The Right Way to go?

Thanks
Mauro

^ permalink raw reply

* Re: [Bridge] Transparent wired/wirless bridge: is it possible?
From: Nicolas de Pesloüan @ 2010-10-30 22:16 UTC (permalink / raw)
  To: Mauro Condarelli; +Cc: bridge
In-Reply-To: <4CCC45E9.7070801@mclink.it>

Le 30/10/2010 18:20, Mauro Condarelli a écrit :
>
> I tried something like:
> =====================
> auto lo
> iface lo inet loopback
>
> auto wlan2
> iface wlan2 inet manual
> up /usr/sbin/service hostapd start
> up /sbin/ifconfig wlan2 up
> down /sbin/ifconfig wlan2 down
> down /usr/sbin/service hostapd stop
>
> auto eth2
> iface eth2 inet manual
> up /sbin/ifconfig eth2 up
> down /sbin/ifconfig eth2 down
>
> auto br0
> iface br0 inet dhcp
> bridge_ports eth2 wlan2
> bridge_maxwait 0
> =====================
> ... but it does not seem to work as hoped.

Consider reading http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge, in 
particular the following sections :

- 7.11 What can be bridged?
- 7.16 It doesn't work with my Wireless card!
- 7.17 I still don't understand!!

	Nicolas.



^ permalink raw reply

* [Bridge] DHCP problem on bridge
From: Kian Yang Liew @ 2010-10-30 16:31 UTC (permalink / raw)
  To: bridge; +Cc: Liew Kian Yang

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

Dear All,



I have a network with 500 vlan and I bind all these 500 vlan into 1 bridge
interface. Then I have run a dhcp server on this bridge interface to provide
dhcp to all the computer in the vlan. It look find all the time, but
sometime, some of the computer on vlan will not able to get the ip from dhcp
server but after I remove the vlan and add back to the bridge it will work
again. The most serious case is sometime there will be a dhcp problem on
vlan 1 as well, and I need to reboot the server only can make the service
back to normal.



The setting is as below





Vconfig add eth1 2

Vconfig add eth1 3

.

.

.

.

.

.vconfig add eth1 500



Then ifconfig eth1.2 up …. Ifconfig eth1.500 up

Then brctl addbr br1, brctl addif br1 eth1.2 ……. Brctl addif br1 eth1.500



Does anyone have face this problem before? Your reply is highly appreciate.





Thank you.







Regards,

Kian Yang, Liew

[-- Attachment #2: Type: text/html, Size: 2864 bytes --]

^ permalink raw reply

* Re: [Bridge] Transparent wired/wirless bridge: is it possible?
From: Mauro Condarelli @ 2010-10-30 16:20 UTC (permalink / raw)
  To: Ryan Whelan; +Cc: bridge
In-Reply-To: <AANLkTi=xHJyMbMqssrSaPabOp9mddGVv15SboU33h10G@mail.gmail.com>

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

On 26/10/2010 14.36, Ryan Whelan wrote:
> Have you looked at hostapd (http://hostap.epitest.fi/hostapd/)?
Sorry,
I was not clear enough.

I have the wireless card up-and-running in ap-mode using hostapd.
I *can* connect a laptop to the wireless Access Point.
I also know how to setup a masquerading router on the linux machine to 
share the landline connection (e.g.: using firestarter).
This would create a second net for wireless with double natting.
I would like to avoid this and I'm looking for a "bridge" configuration 
so that all machines (wireless & wired) can share the same subnet 
(192.68.1.0/24).

I tried something like:
=====================
auto lo
iface lo inet loopback

auto wlan2
iface wlan2 inet manual
     up /usr/sbin/service hostapd start
     up /sbin/ifconfig wlan2 up
     down /sbin/ifconfig wlan2 down
     down /usr/sbin/service hostapd stop

auto eth2
iface eth2 inet manual
     up /sbin/ifconfig eth2 up
     down /sbin/ifconfig eth2 down

auto br0
iface br0 inet dhcp
     bridge_ports eth2 wlan2
     bridge_maxwait 0
=====================
... but it does not seem to work as hoped.

Thanks in Advance for *ANY* hint ;)

Regards
Mauro
>
> On Tue, Oct 26, 2010 at 5:24 AM, Mauro Condarelli <mc5686@mclink.it 
> <mailto:mc5686@mclink.it>> wrote:
>
>     Hi,
>     I read a lot on the Internet, but didn't find quite what I need.
>     I'm not even sure it's possible.
>
>     I have a machine with ethernet access and wireless card (in master
>     mode).
>     Both are running ok under ubuntu maverick.
>     I also have a separate firewall (wired) acting as DHCP server for my
>     whole home network.
>     I would like to bind the two interfaces together with no
>     translation (no
>     NAT, SNAT, masquerading, ...) so that the machines connecting to the
>     wireless lan can get their address from the firewall and access the
>     Internet.
>
>     Is this possible with bridging?
>     If so: can someone point me to the right documentation?
>
>     TiA
>     Mauro
>     _______________________________________________
>     Bridge mailing list
>     Bridge@lists.linux-foundation.org
>     <mailto:Bridge@lists.linux-foundation.org>
>     https://lists.linux-foundation.org/mailman/listinfo/bridge
>
>


[-- Attachment #2: Type: text/html, Size: 4023 bytes --]

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox