# BPDU problem



## spartacus (Apr 14, 2011)

Why does FreeBSD 8.1 drop BPDU packets when stp is off?


```
FreeBSD A----------------FreeBSD B
|                        |
|                        |
|                        |
FreeBSD C----------------FreeBSD D
```

FreeBSD A and FreeBSD D's stp on.
FreeBSD B and FreeBSD C's stp off.

FreeBSD A cannot receive the BPDU from FreeBSD D, because FreeBSD C and FreeBSD B cannot forward BPDU.

Why?


----------



## SirDice (Apr 15, 2011)

BPDU is sent on layer2. There is no layer 2 connectivity between A and D.


----------



## spartacus (Apr 15, 2011)

The interfaces of all FreeBSDs are all in bridge mode.They are all 2 layer.


----------



## SirDice (Apr 18, 2011)

Please post the complete setup. It's really hard diagnosing something when there's no information.


----------



## spartacus (Apr 18, 2011)

```
FreeBSD A em0 ---------------- em1 FreeBSD B
em1                                 em0
|                                   |
|                                   |
|                                   |
em0                                em1
FreeBSD C em1---------------- em0 FreeBSD D
```
CODE:

```
FreeBSD A:
ifconfig bridge create
ifconfig bridge0 addm em0 addm em1 stp em0 stp em1 12.1.1.1/24 up
ifconfig em0 up
ifconfig em1 up

FreeBSD D:
ifconfig bridge create
ifconfig bridge0 addm em0 addm em1 stp em0 stp em1 12.1.1.2/24 up
ifconfig em0 up
ifconfig em1 up

FreeBSD B:
ifconfig bridge create
ifconfig bridge0 addm em0 addm em1 up
ifconfig em0 up
ifconfig em1 up

FreeBSD C:
ifconfig bridge create
ifconfig bridge0 addm em0 addm em1 up
ifconfig em0 up
ifconfig em1 up
```


----------



## SirDice (Apr 18, 2011)

Packets only get forwarded if the bridge knows the destination MAC is on the other side.



> A bridge works like a switch, forwarding traffic from one interface to another.  Multicast and broadcast packets are always forwarded to all interfaces that are part of the bridge.  For unicast traffic, the bridge learns which MAC addresses are associated with which interfaces and will forward the traffic selectively.



Also:


> ARP and REVARP packets are forwarded without being filtered and others that are not IP nor IPv6 packets are not forwarded when pfil_onlyip is enabled.



From if_bridge(4).


----------



## spartacus (Apr 19, 2011)

Yes, you are right! But STP/RSTP is using multicast.  So they should forward. And, low version, like FreeBSD. 4.8

```
sysctl net.link.ether.bridge=1
sysctl net.link.ether.bridge_cfg=em0,em1
ifconfig em0 up
ifconfig em1 up
```
Do not have this problem.


----------



## spartacus (Apr 26, 2011)

BPDU using multicast address: 01-80-c2-00-00-00. Why does FreeBSD drop it?


----------



## spartacus (Apr 26, 2011)

Is my English too bad or difficult problem?


----------



## spartacus (May 9, 2011)

/sys/net/if_bridge.c:

```
2045         /*
   2046          * At this point, the port either doesn't participate
   2047          * in spanning tree or it is in the forwarding state.
   2048          */
   2049
   2050         /*
   2051          * If the packet is unicast, destined for someone on
   2052          * "this" side of the bridge, drop it.
   2053          */
   2054         if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
   2055                 dst_if = bridge_rtlookup(sc, dst, vlan);
   2056                 if (src_if == dst_if)
   2057                         goto drop;
   2058         } else {
   2059                 /*
   2060                  * Check if its a reserved multicast address, any address
   2061                  * listed in 802.1D section 7.12.6 may not be forwarded by the
   2062                  * bridge.
   2063                  * This is currently 01-80-C2-00-00-00 to 01-80-C2-00-00-0F
   2064                  */
   2065                 if (dst[0] == 0x01 && dst[1] == 0x80 &&
   2066                     dst[2] == 0xc2 && dst[3] == 0x00 &&
   2067                     dst[4] == 0x00 && dst[5] <= 0x0f)
   2068                         goto drop;
   2069
   2070                 /* ...forward it to all interfaces. */
   2071                 ifp->if_imcasts++;
   2072                 dst_if = NULL;
   2073         }
```


----------



## quintessence (May 9, 2011)

Hello,

It is not FreeBSD specific, in other OSes (for example OpenBSD, Linuxes) it is the same behaviour

From mailing lists archive: 



> The change was intentional because the bridge follows the 802 spec
> and doesn't pass link local multicast frames.
> 
> If you are running STP on the network, you need to run STP on
> the bridge.





```
/*
* Reserved destination MAC addresses (01:80:C2:00:00:0x)
* should not be forwarded to bridge members according to
* section 7.12.6 of the 802.1D-2004 specification.  The
* STP destination address (as stored in bstp_etheraddr)
* is the first of these.
*/
```


----------



## spartacus (May 10, 2011)

quintessence said:
			
		

> Hello,
> It is not FreeBSD specific, in other OSes (for example OpenBSD, Linuxes) it is the same behaviour. From mailing lists archive:
> 
> ```
> ...


Demand is such, I need to change FreeBSD source code.
When I commented that piece of code, STP still cannot pass.

```
2045         /*
   2046          * At this point, the port either doesn't participate
   2047          * in spanning tree or it is in the forwarding state.
   2048          */
   2049
   2050         /*
   2051          * If the packet is unicast, destined for someone on
   2052          * "this" side of the bridge, drop it.
   2053          */
   2054         if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) {
   2055                 dst_if = bridge_rtlookup(sc, dst, vlan);
   2056                 if (src_if == dst_if)
   2057                         goto drop;
   2058         } else {
   2059                 /*
   2060                  * Check if its a reserved multicast address, any address
   2061                  * listed in 802.1D section 7.12.6 may not be forwarded by the
   2062                  * bridge.
   2063                  * This is currently 01-80-C2-00-00-00 to 01-80-C2-00-00-0F
   2064                  */
   2065                 /*if (dst[0] == 0x01 && dst[1] == 0x80 &&
   2066                     dst[2] == 0xc2 && dst[3] == 0x00 &&
   2067                     dst[4] == 0x00 && dst[5] <= 0x0f)
   2068                         goto drop;
   2069                 */
   2070                 /* ...forward it to all interfaces. */
   2071                 ifp->if_imcasts++;
   2072                 dst_if = NULL;
   2073         }
```
STP still cannot pass through.


----------

