netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net] bridge: allow receiption on disabled port
@ 2013-10-10 12:52 Felix Fietkau
  2013-10-10 20:36 ` Stephen Hemminger
  0 siblings, 1 reply; 8+ messages in thread
From: Felix Fietkau @ 2013-10-10 12:52 UTC (permalink / raw)
  To: netdev; +Cc: stephen

When an ethernet device is enslaved to a bridge, and the bridge STP
detects loss of carrier (or operational state down), then normally
packet receiption is blocked.

This breaks control applications like WPA which maybe expecting to
receive packets to negotiate to bring link up. The bridge needs to
block forwarding packets from these disabled ports, but there is no
hard requirement to not allow local packet delivery.

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
 net/bridge/br_input.c | 20 +++++++++++++++++---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index a2fd37e..0a8a8cd 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -146,9 +146,11 @@ static int br_handle_local_finish(struct sk_buff *skb)
 	struct net_bridge_port *p = br_port_get_rcu(skb->dev);
 	u16 vid = 0;
 
-	br_vlan_get_tag(skb, &vid);
-	if (p->flags & BR_LEARNING)
-		br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid);
+	if (p->state != BR_STATE_DISABLED) {
+		br_vlan_get_tag(skb, &vid);
+		if (p->flags & BR_LEARNING)
+			br_fdb_update(p->br, p, eth_hdr(skb)->h_source, vid);
+	}
 	return 0;	 /* process further */
 }
 
@@ -218,6 +220,18 @@ rx_handler_result_t br_handle_frame(struct sk_buff **pskb)
 
 forward:
 	switch (p->state) {
+	case BR_STATE_DISABLED:
+		if (ether_addr_equal(p->br->dev->dev_addr, dest))
+			skb->pkt_type = PACKET_HOST;
+
+		if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL,
+			br_handle_local_finish))
+			break;
+
+		BR_INPUT_SKB_CB(skb)->brdev = p->br->dev;
+		br_pass_frame_up(skb);
+		break;
+
 	case BR_STATE_FORWARDING:
 		rhook = rcu_dereference(br_should_route_hook);
 		if (rhook) {
-- 
1.8.0.2

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-10 12:52 [PATCH net] bridge: allow receiption on disabled port Felix Fietkau
@ 2013-10-10 20:36 ` Stephen Hemminger
  2013-10-10 20:56   ` Felix Fietkau
  0 siblings, 1 reply; 8+ messages in thread
From: Stephen Hemminger @ 2013-10-10 20:36 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: netdev

On Thu, 10 Oct 2013 14:52:50 +0200
Felix Fietkau <nbd@openwrt.org> wrote:

> When an ethernet device is enslaved to a bridge, and the bridge STP
> detects loss of carrier (or operational state down), then normally
> packet receiption is blocked.
> 
> This breaks control applications like WPA which maybe expecting to
> receive packets to negotiate to bring link up. The bridge needs to
> block forwarding packets from these disabled ports, but there is no
> hard requirement to not allow local packet delivery.
> 
> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> Signed-off-by: Felix Fietkau <nbd@openwrt.org>

No. This will cause duplicate packets to be delivered.

If doing a link layer protocol like WPA then it should be done directly
on the underlying device, not the bridge itself.

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-10 20:36 ` Stephen Hemminger
@ 2013-10-10 20:56   ` Felix Fietkau
  2013-10-10 21:52     ` Stephen Hemminger
  2013-10-11  2:35     ` Stephen Hemminger
  0 siblings, 2 replies; 8+ messages in thread
From: Felix Fietkau @ 2013-10-10 20:56 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On 2013-10-10 10:36 PM, Stephen Hemminger wrote:
> On Thu, 10 Oct 2013 14:52:50 +0200
> Felix Fietkau <nbd@openwrt.org> wrote:
> 
>> When an ethernet device is enslaved to a bridge, and the bridge STP
>> detects loss of carrier (or operational state down), then normally
>> packet receiption is blocked.
>> 
>> This breaks control applications like WPA which maybe expecting to
>> receive packets to negotiate to bring link up. The bridge needs to
>> block forwarding packets from these disabled ports, but there is no
>> hard requirement to not allow local packet delivery.
>> 
>> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> 
> No. This will cause duplicate packets to be delivered.
How? I haven't observed any duplications in my tests with this patch.

> If doing a link layer protocol like WPA then it should be done directly
> on the underlying device, not the bridge itself.
When the ETH_P_PAE protocol is set for the packet socket inside
wpa_supplicant, the bridge steals all packets before the protocol
handler gets them.
In __netif_receive_skb_core, only ptype_all gets processed before the rx
handler, not ptype_base.


- Felix

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-10 20:56   ` Felix Fietkau
@ 2013-10-10 21:52     ` Stephen Hemminger
  2013-10-10 22:08       ` Felix Fietkau
  2013-10-11  2:35     ` Stephen Hemminger
  1 sibling, 1 reply; 8+ messages in thread
From: Stephen Hemminger @ 2013-10-10 21:52 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: netdev

On Thu, 10 Oct 2013 22:56:33 +0200
Felix Fietkau <nbd@openwrt.org> wrote:

> On 2013-10-10 10:36 PM, Stephen Hemminger wrote:
> > On Thu, 10 Oct 2013 14:52:50 +0200
> > Felix Fietkau <nbd@openwrt.org> wrote:
> > 
> >> When an ethernet device is enslaved to a bridge, and the bridge STP
> >> detects loss of carrier (or operational state down), then normally
> >> packet receiption is blocked.
> >> 
> >> This breaks control applications like WPA which maybe expecting to
> >> receive packets to negotiate to bring link up. The bridge needs to
> >> block forwarding packets from these disabled ports, but there is no
> >> hard requirement to not allow local packet delivery.
> >> 
> >> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
> >> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
> > 
> > No. This will cause duplicate packets to be delivered.
> How? I haven't observed any duplications in my tests with this patch.

The purpose of DISABLED state is to break loops in the bridge tree.
If packet is flooded by another bridge (Broadcast Unknown or Multicast)
then it will go down both paths.

> 
> > If doing a link layer protocol like WPA then it should be done directly
> > on the underlying device, not the bridge itself.
> When the ETH_P_PAE protocol is set for the packet socket inside
> wpa_supplicant, the bridge steals all packets before the protocol
> handler gets them.
> In __netif_receive_skb_core, only ptype_all gets processed before the rx
> handler, not ptype_base.

Thought it was using direct type all. Or at least the link local multicast
address.

Can you revise it to only accept packets directed to link local multicast
address or local address, and go through the local_finish handler.

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-10 21:52     ` Stephen Hemminger
@ 2013-10-10 22:08       ` Felix Fietkau
  0 siblings, 0 replies; 8+ messages in thread
From: Felix Fietkau @ 2013-10-10 22:08 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On 2013-10-10 11:52 PM, Stephen Hemminger wrote:
> On Thu, 10 Oct 2013 22:56:33 +0200
> Felix Fietkau <nbd@openwrt.org> wrote:
> 
>> On 2013-10-10 10:36 PM, Stephen Hemminger wrote:
>> > On Thu, 10 Oct 2013 14:52:50 +0200
>> > Felix Fietkau <nbd@openwrt.org> wrote:
>> > 
>> >> When an ethernet device is enslaved to a bridge, and the bridge STP
>> >> detects loss of carrier (or operational state down), then normally
>> >> packet receiption is blocked.
>> >> 
>> >> This breaks control applications like WPA which maybe expecting to
>> >> receive packets to negotiate to bring link up. The bridge needs to
>> >> block forwarding packets from these disabled ports, but there is no
>> >> hard requirement to not allow local packet delivery.
>> >> 
>> >> Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
>> >> Signed-off-by: Felix Fietkau <nbd@openwrt.org>
>> > 
>> > No. This will cause duplicate packets to be delivered.
>> How? I haven't observed any duplications in my tests with this patch.
> 
> The purpose of DISABLED state is to break loops in the bridge tree.
> If packet is flooded by another bridge (Broadcast Unknown or Multicast)
> then it will go down both paths.
Ah, right.

>> > If doing a link layer protocol like WPA then it should be done directly
>> > on the underlying device, not the bridge itself.
>> When the ETH_P_PAE protocol is set for the packet socket inside
>> wpa_supplicant, the bridge steals all packets before the protocol
>> handler gets them.
>> In __netif_receive_skb_core, only ptype_all gets processed before the rx
>> handler, not ptype_base.
> 
> Thought it was using direct type all. Or at least the link local multicast
> address.
> 
> Can you revise it to only accept packets directed to link local multicast
> address or local address, and go through the local_finish handler.
The destination address in WPA EAPOL packets from the AP is set to the
MAC address of the client, which may not be the same as the one from the
bridge.

- Felix

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-10 20:56   ` Felix Fietkau
  2013-10-10 21:52     ` Stephen Hemminger
@ 2013-10-11  2:35     ` Stephen Hemminger
  2013-10-11 10:18       ` Felix Fietkau
  1 sibling, 1 reply; 8+ messages in thread
From: Stephen Hemminger @ 2013-10-11  2:35 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: netdev

This is what I was thinking would be better.

Don't want these packets leaking into PRE_ROUTEING chain or have
any chance to get flooded out other ports.

Compile tested only...

I could use another goto instead but that becomes spaghetti and
never like to jump back into a block.


--- a/net/bridge/br_input.c	2013-10-06 14:48:24.946450042 -0700
+++ b/net/bridge/br_input.c	2013-10-10 19:32:14.227926344 -0700
@@ -152,6 +152,16 @@ static int br_handle_local_finish(struct
 	return 0;	 /* process further */
 }
 
+/* Deliver packet to local host only */
+static rx_handler_result_t br_local_only(struct sk_buff *skb)
+{
+	if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
+		    NULL, br_handle_local_finish))
+		return RX_HANDLER_CONSUMED; /* consumed by filter */
+	else
+		return RX_HANDLER_PASS;	/* continue processing */
+}
+
 /*
  * Return NULL if skb is handled
  * note: already called with rcu_read_lock
@@ -206,18 +216,20 @@ rx_handler_result_t br_handle_frame(stru
 				goto forward;
 		}
 
-		/* Deliver packet to local host only */
-		if (NF_HOOK(NFPROTO_BRIDGE, NF_BR_LOCAL_IN, skb, skb->dev,
-			    NULL, br_handle_local_finish)) {
-			return RX_HANDLER_CONSUMED; /* consumed by filter */
-		} else {
-			*pskb = skb;
-			return RX_HANDLER_PASS;	/* continue processing */
-		}
+		*pskb = skb;
+		return br_local_only(skb);
 	}
 
 forward:
 	switch (p->state) {
+	case BR_STATE_DISABLED:
+		if (!ether_addr_equal(p->br->dev->dev_addr, dest))
+			goto drop;
+
+		skb->pkt_type = PACKET_HOST;
+		*pskb = skb;
+		return br_local_only(skb);
+
 	case BR_STATE_FORWARDING:
 		rhook = rcu_dereference(br_should_route_hook);
 		if (rhook) {

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-11  2:35     ` Stephen Hemminger
@ 2013-10-11 10:18       ` Felix Fietkau
  2013-10-11 15:10         ` Stephen Hemminger
  0 siblings, 1 reply; 8+ messages in thread
From: Felix Fietkau @ 2013-10-11 10:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

On 2013-10-11 4:35 AM, Stephen Hemminger wrote:
> This is what I was thinking would be better.
> 
> Don't want these packets leaking into PRE_ROUTEING chain or have
> any chance to get flooded out other ports.
> 
> Compile tested only...
> 
> I could use another goto instead but that becomes spaghetti and
> never like to jump back into a block.
[...]
>  forward:
>  	switch (p->state) {
> +	case BR_STATE_DISABLED:
> +		if (!ether_addr_equal(p->br->dev->dev_addr, dest))
> +			goto drop;
Checking against the bridge device address isn't enough, WPA EAPOL
packets are addressed to the wifi device MAC address.

- Felix

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

* Re: [PATCH net] bridge: allow receiption on disabled port
  2013-10-11 10:18       ` Felix Fietkau
@ 2013-10-11 15:10         ` Stephen Hemminger
  0 siblings, 0 replies; 8+ messages in thread
From: Stephen Hemminger @ 2013-10-11 15:10 UTC (permalink / raw)
  To: Felix Fietkau; +Cc: netdev

On Fri, 11 Oct 2013 12:18:15 +0200
Felix Fietkau <nbd@openwrt.org> wrote:

> On 2013-10-11 4:35 AM, Stephen Hemminger wrote:
> > This is what I was thinking would be better.
> > 
> > Don't want these packets leaking into PRE_ROUTEING chain or have
> > any chance to get flooded out other ports.
> > 
> > Compile tested only...
> > 
> > I could use another goto instead but that becomes spaghetti and
> > never like to jump back into a block.
> [...]
> >  forward:
> >  	switch (p->state) {
> > +	case BR_STATE_DISABLED:
> > +		if (!ether_addr_equal(p->br->dev->dev_addr, dest))
> > +			goto drop;
> Checking against the bridge device address isn't enough, WPA EAPOL
> packets are addressed to the wifi device MAC address.

Correct, this should be skb->dev->dev_addr which matchs against
the MAC address that frame arrived on.

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

end of thread, other threads:[~2013-10-11 15:10 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-10-10 12:52 [PATCH net] bridge: allow receiption on disabled port Felix Fietkau
2013-10-10 20:36 ` Stephen Hemminger
2013-10-10 20:56   ` Felix Fietkau
2013-10-10 21:52     ` Stephen Hemminger
2013-10-10 22:08       ` Felix Fietkau
2013-10-11  2:35     ` Stephen Hemminger
2013-10-11 10:18       ` Felix Fietkau
2013-10-11 15:10         ` Stephen Hemminger

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).