Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questions about Per-VLAN Spanning Tree (PVST+) #80

Open
kesteve opened this issue Oct 3, 2019 · 13 comments
Open

Questions about Per-VLAN Spanning Tree (PVST+) #80

kesteve opened this issue Oct 3, 2019 · 13 comments

Comments

@kesteve
Copy link

kesteve commented Oct 3, 2019

Hi,

I'm reading the document on this page:
https://github.com/mstpd/mstpd/blob/master/README.VLANs.md

Regarding "Per-VLAN Spanning Tree (PVST+)", is there anyone tried to do this successfully with a Cisco?

The mentioned ebtables setting in the link (http://blog.rackspace.com/vms-vlans-and-bridges-oh-my-part-2) has been dead so I'm not sure if I'm configuring ebtables correctly.

If anyone has experience on setting up mstpd with a Cisco using Rapid-PVST, could you please point me a direction, or just stop me to try anymore if this is not supported?

Thank you so much. Your help is much appreciated.

Best regards,
Steve

@commodo
Copy link
Member

commodo commented Oct 3, 2019

@PaulSD wrote it.
Let's see if he has any input on this.

As for STP/RSTP, I do remember it was running succesfully with Cisco, HP & Dell switches.
But I did not try PVST+

@mg964
Copy link
Contributor

mg964 commented Oct 3, 2019

Early this year I had a play and tried to hookup a Debian-based system (Vyatta router), running MSTPd to a Cisco switch running rapid-pvst. Most of the details have been flushed, but from what I can remember the basics worked. Never bothered with the etables thing, just wanted to see what would happen. In the end the thinking was that having to generate/manage lots of VLAN interfaces may not scale.

Currently have a crude prototype (hack!) that generates internal virtual interfaces, bridges and STP instances based on some VLAN configuration extensions to mstpctl. Early days, trying to see if its a viable solution and may not see the light of day.

Mark

@mg964
Copy link
Contributor

mg964 commented Oct 3, 2019

Have you tried following the README (ignoring the etables bit)?

@kesteve
Copy link
Author

kesteve commented Oct 4, 2019

Thanks guys. This give me hope.

and yea, I have tried to follow the README, but the mstpd doesn't seems to detect the cisco on the VLAN bridge, but tcpdump running on the VLAN bridge is showing the multicast packet coming from cisco.

I'll try to summarize things up and post here.

Hopefully @PaulSD can have time to take a look here :)

@kesteve
Copy link
Author

kesteve commented Oct 4, 2019

So here are my test results.

I have created 2 VLANs, 50 and 639. The trunk interface is eth0, on the cisco side Native VLAN is not allowed to avoid the ebtables stuffs.

As shown below (some MAC addresses are masked):

~ # ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global eth0
       valid_lft forever preferred_lft forever
16: br_vlan639: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.39.1/24 scope global br_vlan639
       valid_lft forever preferred_lft forever
17: eth0.639@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br_vlan639 state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
20: eth0.50@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br_vlan50 state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
21: br_vlan50: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff

~ # brctl show
bridge name     bridge id               STP enabled     interfaces
br_vlan50               8000.xxxxxx0c103c       yes             eth0.50
br_vlan639              8000.xxxxxx0c103c       yes             eth0.639

~ # mstpctl showportdetail br_vlan50
br_vlan50:eth0.50 CIST info
  enabled            yes                     role                 Designated
  port id            8.001                   state                forwarding
  external port cost 20000                   admin external cost  0
  internal port cost 20000                   admin internal cost  0
  designated root    8.000.xx:xx:xx:0C:10:3C dsgn external cost   0
  dsgn regional root 8.000.xx:xx:xx:0C:10:3C dsgn internal cost   0
  designated bridge  8.000.xx:xx:xx:0C:10:3C designated port      8.001
  admin edge port    no                      auto edge port       yes
  oper edge port     yes                     topology change ack  no
  point-to-point     yes                     admin point-to-point auto
  restricted role    no                      restricted TCN       no
  port hello time    2                       disputed             no
  bpdu guard port    no                      bpdu guard error     no
  network port       no                      BA inconsistent      no
  bpdu filter port   no                      Num RX BPDU Filtered 0
  Num TX BPDU        2036                    Num TX TCN           2
  Num RX BPDU        0                       Num RX TCN           0
  Num Transition FWD 1                       Num Transition BLK   1
  Rcvd BPDU          no                      Rcvd STP             no
  Rcvd RSTP          no                      Send RSTP            yes
  Rcvd TC Ack        no                      Rcvd TCN             no

~ # mstpctl showportdetail br_vlan639
br_vlan639:eth0.639 CIST info
  enabled            yes                     role                 Designated
  port id            8.002                   state                forwarding
  external port cost 20000                   admin external cost  0
  internal port cost 20000                   admin internal cost  0
  designated root    8.000.xx:xx:xx:0C:10:3C dsgn external cost   0
  dsgn regional root 8.000.xx:xx:xx:0C:10:3C dsgn internal cost   0
  designated bridge  8.000.xx:xx:xx:0C:10:3C designated port      8.002
  admin edge port    no                      auto edge port       yes
  oper edge port     yes                     topology change ack  no
  point-to-point     yes                     admin point-to-point auto
  restricted role    no                      restricted TCN       no
  port hello time    2                       disputed             no
  bpdu guard port    no                      bpdu guard error     no
  network port       no                      BA inconsistent      no
  bpdu filter port   no                      Num RX BPDU Filtered 0
  Num TX BPDU        3212                    Num TX TCN           0
  Num RX BPDU        0                       Num RX TCN           0
  Num Transition FWD 2                       Num Transition BLK   2
  Rcvd BPDU          no                      Rcvd STP             no
  Rcvd RSTP          no                      Send RSTP            yes
  Rcvd TC Ack        no                      Rcvd TCN             no

You can see "Rcvd BPDU" is "no" for both VLAN.

If I run tcpdump on eth0:

~ # tcpdump -i eth0 -n -e
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
05:45:04.145144 xx:xx:xx:0c:10:3c > 01:80:c2:00:00:00, ethertype 802.1Q (0x8100), length 57: vlan 50, p 0, LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1w, Rapid STP, Flags [Proposal, Learn, Forward, Agreement], bridge-id 8000.xx:xx:xx:0c:10:3c.8001, length 36
05:45:05.145143 xx:xx:xx:0c:10:3c > 01:80:c2:00:00:00, ethertype 802.1Q (0x8100), length 57: vlan 639, p 0, LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1w, Rapid STP, Flags [Proposal, Learn, Forward, Agreement], bridge-id 8000.xx:xx:xx:0c:10:3c.8002, length 36
05:45:05.181243 88:xx:xx:xx:xx:81 > 01:00:0c:cc:cc:cd, ethertype 802.1Q (0x8100), length 68: vlan 50, p 7, LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid PVST (0x010b): STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 8032.88:xx:xx:xx:xx:80.8001, length 42
05:45:05.182901 88:xx:xx:xx:xx:81 > 01:00:0c:cc:cc:cd, ethertype 802.1Q (0x8100), length 68: vlan 639, p 7, LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid PVST (0x010b): STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 827f.88:xx:xx:xx:xx:80.8001, length 42
^C
4 packets captured
4 packets received by filter
0 packets dropped by kernel

The cisco is sending their proprietary BPDU on both VLANs, I'm wondering mstpd may not understand the multicast MAC 01:00:0c:cc:cc:cd.

@PaulSD
Copy link
Member

PaulSD commented Oct 5, 2019

I did have PVST+ successfully working back when I wrote README.VLANs.md, but I haven't used it recently. I'm currently using RSTP instead, with my Cisco switches configured in 'mst' mode, as described in the first section of README.VLANs.md.

A copy of the rackspace blog post can be found here:
https://web.archive.org/web/20150502184754/http://www.rackspace.com/blog/vms-vlans-and-bridges-oh-my-part-2/
Basically, if you create a bridge for the native VLAN directly on top of eth0 while also having the VLAN interfaces on top of eth0, then you need to add an ebtables rule to keep the native VLAN bridge from swallowing the tagged packets before they hit the VLAN interfaces:

ebtables -t broute -A BROUTING -i eth0 -p 802_1Q -j DROP

I'll update README.VLANs.md with this.

@PaulSD
Copy link
Member

PaulSD commented Oct 5, 2019

Unfortunately, I don't have any switches I can flip to PVST+ mode right now for testing without breaking other things... (In theory it should be possible to get a Cisco switch in 'mst' mode to emulate PVST+ on a single port, but mstpd doesn't send the right packets to trigger that.) I might be able to try it later this week.

Maybe try running mstpd -d -v -v -v? That should at least tell us whether mstpd is receiving the packets, which will tell us whether the problem is in the kernel or mstpd.

@mg964
Copy link
Contributor

mg964 commented Oct 7, 2019

Surely since mstpd uses a BPF that simply matches the IEEE link-local address, its never going to see the PVST frames (1:0:c:cc:cc:cd + SNAP, etc)?

@kesteve
Copy link
Author

kesteve commented Oct 8, 2019

OK, here are the logs printed by mstpd and some other information:

~ # brctl show
bridge name     bridge id               STP enabled     interfaces
br_vlan50               8000.xxxxxx0c103c       yes             eth0.50
br_vlan639              8000.xxxxxx0c103c       yes             eth0.639
~ #
~ # ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.1.1/24 scope global eth0
       valid_lft forever preferred_lft forever
16: br_vlan639: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
    inet 192.168.39.1/24 scope global br_vlan639
       valid_lft forever preferred_lft forever
17: eth0.639@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br_vlan639 state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
20: eth0.50@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master br_vlan50 state UP group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
21: br_vlan50: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether xx:xx:xx:0c:10:3c brd ff:ff:ff:ff:ff:ff
~ #
~ # mstpd -d -v 3
2019-10-08 04:48:52 main: Version - 0.0.8-786d965

2019-10-08 04:48:52 sanity_check: Sanity checks succeeded
2019-10-08 04:48:52 dump_msg: 3: eth1
2019-10-08 04:48:52 dump_msg: Down
2019-10-08 04:48:52 dump_msg: mtu 1500
2019-10-08 04:48:52 dump_msg: master br0
2019-10-08 04:48:52 bridge_notify: br_index 14, if_index 3, newlink 1, up 1, running 0
2019-10-08 04:48:52 dump_msg: 4: eth2
2019-10-08 04:48:52 dump_msg: Down
2019-10-08 04:48:52 dump_msg: mtu 1500
2019-10-08 04:48:52 dump_msg: master br0
2019-10-08 04:48:52 bridge_notify: br_index 14, if_index 4, newlink 1, up 1, running 0
2019-10-08 04:48:52 dump_msg: 17: eth0.639
2019-10-08 04:48:52 dump_msg: Up
2019-10-08 04:48:52 dump_msg: mtu 1500
2019-10-08 04:48:52 dump_msg: master br_vlan639
2019-10-08 04:48:52 bridge_notify: br_index 16, if_index 17, newlink 1, up 1, running 1
2019-10-08 04:48:52 dump_msg: 20: eth0.50
2019-10-08 04:48:52 dump_msg: Up
2019-10-08 04:48:52 dump_msg: mtu 1500
2019-10-08 04:48:52 dump_msg: master br_vlan50
2019-10-08 04:48:52 bridge_notify: br_index 21, if_index 20, newlink 1, up 1, running 1
^Z[1] + Stopped                    mstpd -d -v 3
~ # bg
[1] mstpd -d -v 3
~ #

I made mstpd run in background above and now tried tcpdump to make sure Cisco is sending out packets:

~ #
~ # tcpdump -i eth0.50 -n -e
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0.50, link-type EN10MB (Ethernet), capture size 262144 bytes
04:49:20.263819 88:xx:xx:xx:xx:81 > 01:00:0c:cc:cc:cd, 802.3, length 64: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid PVST (0x010b): STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 8032.88:xx:xx:xx:xx:80.8001, length 42
^C
1 packet captured
1 packet received by filter
0 packets dropped by kernel
~ #

Then using mstpctl to add br_vlan50:

~ # mstpctl addbridge br_vlan50
2019-10-08 04:49:40 create_br: Add bridge br_vlan50
2019-10-08 04:49:40 set_br_up: br_vlan50 was down. Set up
2019-10-08 04:49:40 create_if: Add iface eth0.50 as port#1 to bridge br_vlan50
2019-10-08 04:49:40 MSTP_OUT_set_state: br_vlan50:eth0.50:0 entering blocking state
2019-10-08 04:49:40 MSTP_OUT_flush_all_fids: br_vlan50:eth0.50:0 Flushing forwarding database
2019-10-08 04:49:40 set_if_up: Port eth0.50 : up
2019-10-08 04:49:40 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:40 dump_msg: 20: eth0.50
2019-10-08 04:49:40 dump_msg: Up
2019-10-08 04:49:40 dump_msg: mtu 1500
2019-10-08 04:49:40 dump_msg: master br_vlan50
2019-10-08 04:49:40 bridge_notify: br_index 21, if_index 20, newlink 1, up 1, running 1
2019-10-08 04:49:40 set_if_up: Port eth0.50 : up
2019-10-08 04:49:40 dump_msg: 20: eth0.50
2019-10-08 04:49:40 dump_msg: Up
2019-10-08 04:49:40 dump_msg: mtu 1500
2019-10-08 04:49:40 dump_msg: master br_vlan50
2019-10-08 04:49:40 bridge_notify: br_index 21, if_index 20, newlink 1, up 1, running 1
2019-10-08 04:49:40 set_if_up: Port eth0.50 : up
2019-10-08 04:49:41 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:42 MSTP_OUT_set_state: br_vlan50:eth0.50:0 entering learning state
2019-10-08 04:49:42 MSTP_OUT_set_state: br_vlan50:eth0.50:0 entering forwarding state
2019-10-08 04:49:42 dump_msg: 20: eth0.50
2019-10-08 04:49:42 dump_msg: Up
2019-10-08 04:49:42 dump_msg: mtu 1500
2019-10-08 04:49:42 dump_msg: master br_vlan50
2019-10-08 04:49:42 bridge_notify: br_index 21, if_index 20, newlink 1, up 1, running 1
2019-10-08 04:49:42 set_if_up: Port eth0.50 : up
2019-10-08 04:49:42 dump_msg: 20: eth0.50
2019-10-08 04:49:42 dump_msg: Up
2019-10-08 04:49:42 dump_msg: mtu 1500
2019-10-08 04:49:42 dump_msg: master br_vlan50
2019-10-08 04:49:42 bridge_notify: br_index 21, if_index 20, newlink 1, up 1, running 1
2019-10-08 04:49:42 set_if_up: Port eth0.50 : up
2019-10-08 04:49:42 dump_msg: 21: br_vlan50
2019-10-08 04:49:42 dump_msg: Up
2019-10-08 04:49:42 dump_msg: mtu 1500
2019-10-08 04:49:42 bridge_notify: br_index 21, if_index 21, newlink 1, up 1, running 1
2019-10-08 04:49:43 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:45 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:47 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:49 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:51 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
2019-10-08 04:49:53 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
~ # 

And tcpdump again you can see mstpd is sending out BPDU, and Cisco as well, the log "MSTP_OUT_tx_bpdu" is mixing in between because mstpd is running in background:

~ # 
~ # tcpdump -i eth0.50 -n -e
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0.50, link-type EN10MB (Ethernet), capture size 262144 bytes
2019-10-08 04:49:55 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
04:49:55.765244 xx:xx:xx:0c:10:3c > 01:80:c2:00:00:00, 802.3, length 53: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1w, Rapid STP, Flags [Proposal, Learn, Forward, Agreement], bridge-id 8000.xx:xx:xx:0c:10:3c.8001, length 36
2019-10-08 04:49:57 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
04:49:57.765238 xx:xx:xx:0c:10:3c > 01:80:c2:00:00:00, 802.3, length 53: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1w, Rapid STP, Flags [Proposal, Learn, Forward, Agreement], bridge-id 8000.xx:xx:xx:0c:10:3c.8001, length 36
04:49:57.839216 88:xx:xx:xx:xx:81 > 01:00:0c:cc:cc:cd, 802.3, length 64: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid PVST (0x010b): STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 8032.88:xx:xx:xx:xx:80.8001, length 42
2019-10-08 04:49:59 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
04:49:59.765249 xx:xx:xx:0c:10:3c > 01:80:c2:00:00:00, 802.3, length 53: LLC, dsap STP (0x42) Individual, ssap STP (0x42) Command, ctrl 0x03: STP 802.1w, Rapid STP, Flags [Proposal, Learn, Forward, Agreement], bridge-id 8000.xx:xx:xx:0c:10:3c.8001, length 36
04:50:00.255562 88:xx:xx:xx:xx:81 > 01:00:0c:cc:cc:cd, 802.3, length 64: LLC, dsap SNAP (0xaa) Individual, ssap SNAP (0xaa) Command, ctrl 0x03: oui Cisco (0x00000c), pid PVST (0x010b): STP 802.1w, Rapid STP, Flags [Learn, Forward], bridge-id 8032.88:xx:xx:xx:xx:80.8001, length 42
^C
5 packets captured
5 packets received by filter
0 packets dropped by kernel
~ #
~ #
2019-10-08 04:50:01 MSTP_OUT_tx_bpdu: br_vlan50:eth0.50 sending RST BPDU
~ #
~ # fg
mstpd -d -v 3
^C
2019-10-08 04:50:02 bridge_track_fini: Stopping all bridges
2019-10-08 04:50:02 set_br_up: br_vlan50 was up. Set down
2019-10-08 04:50:02 MSTP_OUT_set_state: br_vlan50:eth0.50:0 entering disabled state
~ #

Unfortunately there is no Cisco packet received by mstpd at all, but tcpdump shows the Cisco packet is on the correct interface. Any ideas? Later today I'll check the source code hopefully I'll have more idea on this.

@PaulSD
Copy link
Member

PaulSD commented Oct 8, 2019

Yeah, as @mg964 mentioned, it is likely that the packet filter simply isn't matching the PVST+ frames.

My old notes on this aren't particularly detailed ... It is likely I tested this using old CatOS switches, not IOS or Nexus, so I wouldn't be surprised if the PVST+ frame format is slightly different on current switches than it was on old switches.

For reference, the packet filter is defined here:
https://github.com/mstpd/mstpd/blob/master/packet.c#L138

@kesteve
Copy link
Author

kesteve commented Oct 9, 2019

Thanks for the information.

Unfortunately I failed again, here are the details.

This is the patch that I have modified in order to get pass bridge_bpdu_rcv():

diff --git a/bridge_track.c b/bridge_track.c
index 968e15b..efbea65 100644
--- a/bridge_track.c
+++ b/bridge_track.c
@@ -380,8 +380,10 @@ void bridge_bpdu_rcv(int if_index, const unsigned char *data, int len)
         if((prt = find_if(br, if_index)))
             break;
     }
-    if(!prt)
+    if(!prt) {
+    LOG("ifindex %d, len %d, !prt", if_index, len);
         return;
+    }

     /* sanity checks */
     TSTM(br == prt->bridge,, "Bridge mismatch. This bridge is '%s' but port "
@@ -395,15 +397,17 @@ void bridge_bpdu_rcv(int if_index, const unsigned char *data, int len)
     unsigned int l;
     TST(len > sizeof(struct llc_header),);
     h = (struct llc_header *)data;
+    /*
     TST(0 == memcmp(h->dest_addr, bridge_group_address, ETH_ALEN),
              INFO("ifindex %d, len %d, %02hhX%02hhX%02hhX%02hhX%02hhX%02hhX",
                   if_index, len,
                   h->dest_addr[0], h->dest_addr[1], h->dest_addr[2],
                   h->dest_addr[3], h->dest_addr[4], h->dest_addr[5])
        );
+       */
     l = __be16_to_cpu(h->len8023);
     TST(l <= ETH_DATA_LEN && l <= len - ETH_HLEN && l >= LLC_PDU_LEN_U, );
-    TST(h->d_sap == LLC_SAP_BSPAN && h->s_sap == LLC_SAP_BSPAN && (h->llc_ctrl & 0x3) == LLC_PDU_TYPE_U,);
+    //TST(h->d_sap == LLC_SAP_BSPAN && h->s_sap == LLC_SAP_BSPAN && (h->llc_ctrl & 0x3) == LLC_PDU_TYPE_U,);

     MSTP_IN_rx_bpdu(prt,
                     /* Don't include LLC header */
diff --git a/packet.c b/packet.c
index c1d4ff5..30ce4b4 100644
--- a/packet.c
+++ b/packet.c
@@ -139,12 +139,20 @@ static void packet_rcv(uint32_t events, struct epoll_event_handler *h)
    from tcpdump -s 1152 -dd stp
  */
 static struct sock_filter stp_filter[] = {
-    { 0x28, 0, 0, 0x0000000c },
-    { 0x25, 3, 0, 0x000005dc },
-    { 0x30, 0, 0, 0x0000000e },
-    { 0x15, 0, 1, 0x00000042 },
-    { 0x6, 0, 0, 0x00000480 },
-    { 0x6, 0, 0, 0x00000000 },
+{ 0x20, 0, 0, 0x00000008 },
+{ 0x15, 0, 2, 0x0ccccccd },
+{ 0x28, 0, 0, 0x00000006 },
+{ 0x15, 8, 0, 0x00000100 },
+{ 0x20, 0, 0, 0x00000002 },
+{ 0x15, 0, 2, 0x0ccccccd },
+{ 0x28, 0, 0, 0x00000000 },
+{ 0x15, 4, 0, 0x00000100 },
+{ 0x28, 0, 0, 0x0000000c },
+{ 0x25, 3, 0, 0x000005dc },
+{ 0x30, 0, 0, 0x0000000e },
+{ 0x15, 0, 1, 0x00000042 },
+{ 0x6, 0, 0, 0x00040000 },
+{ 0x6, 0, 0, 0x00000000 },
 };

With the above patch, mstpd received the Cisco BPDU on br_vlan50 (interface name refer to my reply above) instead of the bridge port interface eth0.50, and printing the following line from the patch above:
"2019-10-09 05:02:44 bridge_bpdu_rcv: ifindex 21, len 64, !prt"

Then I added a ebtables rule to drop this packet in BROUTING so it will appear on eth0.50 instead of br_vlan50:

# ebtables -t broute -L BROUTING
Bridge table: broute

Bridge chain: BROUTING, entries: 2, policy: ACCEPT
-d 1:0:c:cc:cc:cd -i eth0.50 -j DROP

However, although mstpd now successfully see the Cisco BPDU packets, but is now printing:

2019-10-09 05:41:01 MSTP_IN_rx_bpdu: br_vlan50:eth0.50 BPDU validation failed

Looks like the mstpd doesn't like Cisco BPDU format and failed to parse the content.

@commodo
Copy link
Member

commodo commented Oct 9, 2019

Looks like the mstpd doesn't like Cisco BPDU format and failed to parse the content.

Looks like there may be plenty of places where this could happen.
There are 2 things you could do:

  1. Install Wireshark on a computer/laptop and connect to the switch; if it helps, maybe add a filter for MAC 01:00:0c:cc:cc:cd (typically filter looks like this ether.addr == 01:00:0c:cc:cc:cd.). Wireshark has some really good packet dissectors and it should be able to tell information about these Cisco BPDUs in a more structured way [than tcpdump].
  2. in mstpd, you could add some prints to all places where there is goto bpdu_validation_failed; that way we can identify easier which BPDU information is wrong

@mg964
Copy link
Contributor

mg964 commented Oct 9, 2019

The PVST frame has a SNAP (rather than LLC) header on the front; don't think the above change will work as its not properly snipping off the L2 header. Once you do that the actual frame content is the same as an IEEE frame (except for the trailing VLAN ID option, which just gets ignored).

FWIW, I have a quilt patch used to allow filtering of PVST frames. This captures the frames and operates in a similar fashion to the current bpdu-filter & bpdu-guard options. As such it may not be of much value to you, but it'll give you the bare bones on how to process PVST frames.

Mark

0020-pvst-filter.patch.txt

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants