Howto configure a VLAN-aware bridge on x86?

I was/am unable to find documentation how to configure a single VLAN-aware bridge on x86 with dedicated Network Interfaces via /etc/network/config.

What I want to get is:

  • A single one bridge which is vlan aware
  • One or more Ports (dedicated NIC) configured as Trunk-Ports, without an untagged PVID, which are enslaved to the bridge

If I do it manually with iproute2 and bridge it seams as I get the desired result.
The output of bridge vlan looks at least as on my DGS-1210-10 where I was able to configure a single vlan aware bridge on DSA via /etc/config/network.

#!/bin/sh

BRIDGE="br-vlan"

ip link add name ${BRIDGE} type bridge vlan_filtering 1 vlan_default_pvid 0
ip link set ${BRIDGE} up

for NIC in eth2 eth3
do
        ip link set ${NIC} master ${BRIDGE}
        ip link set ${NIC} up
done

for VID in 16 17
do
        bridge vlan add vid ${VID} dev ${BRIDGE} self

        for NIC in eth2 eth3
        do
                bridge vlan add vid ${VID} dev ${NIC}
        done
done

root@OpenWrt:/# sh -x /root/setup_vlan-aware_bridge.sh
+ BRIDGE=br-vlan
+ ip link add name br-vlan type bridge vlan_filtering 1 vlan_default_pvid 0
+ ip link set br-vlan up
+ ip link set eth2 master br-vlan
+ ip link set eth2 up
+ ip link set eth3 master br-vlan
+ ip link set eth3 up
+ bridge vlan add vid 16 dev br-vlan self
+ bridge vlan add vid 16 dev eth2
+ bridge vlan add vid 16 dev eth3
+ bridge vlan add vid 17 dev br-vlan self
+ bridge vlan add vid 17 dev eth2
+ bridge vlan add vid 17 dev eth3

root@OpenWrt:/# ip -br l
lo               DOWN           00:00:00:00:00:00 <LOOPBACK>
eth0             DOWN           20:7c:14:a2:b0:84 <BROADCAST,MULTICAST>
eth1             DOWN           20:7c:14:a2:b0:85 <BROADCAST,MULTICAST>
eth2             DOWN           20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
eth3             DOWN           20:7c:14:a2:b0:87 <NO-CARRIER,BROADCAST,MULTICAST,UP>
br-vlan          DOWN           20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>

root@OpenWrt:/# brctl show
bridge name     bridge id               STP enabled     interfaces
br-vlan         8000.207c14a2b086       no              eth2
                                                        eth3

root@OpenWrt:/# bridge vlan
port              vlan-id
eth2              16
                  17
eth3              16
                  17
br-vlan           16
                  17

Compare with bridge vlan from the DGS-1210-10 where lan8 is the Trunk:

root@sw1:~# bridge vlan
port              vlan-id
lan1              4094 PVID Egress Untagged
lan2              64 PVID Egress Untagged
lan3              64 PVID Egress Untagged
lan4              71 PVID Egress Untagged
lan5              17 PVID Egress Untagged
lan6              24 PVID Egress Untagged
lan7              24 PVID Egress Untagged
lan8              16
                  17
                  24
                  64
                  65
                  71
                  76
                  77
lan9              1 PVID Egress Untagged
lan10             1 PVID Egress Untagged
switch            1
                  16
                  17
                  24
                  64
                  65
                  71
                  76
                  77
                  4094

When I try to configure a single vlan-aware bridge on x86 (via /etc/config/network) it results in ether a total mess or not working at all. (For now I spare us from sharing total misconfigured snippets. Maybe someone has a pointer for me, or even a working example.)


I'm however able to configure multiple bridges, but still: I'm unsure if this is really correct because bridge vlan looks a little bit odd to me, even that ip -d link shows an id on the vlan-subinterfaces. but not on/for the 2 bridge interfaces. But I'm not sure if they even should... However I want to use a single vlan-aware bridge anyway, so configuring multiple bridges and ensalve vlan subinterfaces is not an option for now.

Reference for the multiple bridges with vlan sub interfaces:

config interface 'vlan16'
        option  type    'bridge'
        list    ifname  'eth2.16'
        list    ifname  'eth3.16'
        option  proto   'none'

config interface 'vlan17'
        option  type    'bridge'
        list    ifname  'eth2.17'
        list    ifname  'eth3.17'
        option  proto   'none'
root@OpenWrt:/# ip -br l
lo               UNKNOWN        00:00:00:00:00:00 <LOOPBACK,UP,LOWER_UP>
eth0             DOWN           20:7c:14:a2:b0:84 <BROADCAST,MULTICAST>
eth1             DOWN           20:7c:14:a2:b0:85 <BROADCAST,MULTICAST>
eth2             DOWN           20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
eth3             DOWN           20:7c:14:a2:b0:87 <NO-CARRIER,BROADCAST,MULTICAST,UP>
br-vlan16        DOWN           20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
eth2.16@eth2     LOWERLAYERDOWN 20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
eth3.16@eth3     LOWERLAYERDOWN 20:7c:14:a2:b0:87 <NO-CARRIER,BROADCAST,MULTICAST,UP>
br-vlan17        DOWN           20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
eth2.17@eth2     LOWERLAYERDOWN 20:7c:14:a2:b0:86 <NO-CARRIER,BROADCAST,MULTICAST,UP>
eth3.17@eth3     LOWERLAYERDOWN 20:7c:14:a2:b0:87 <NO-CARRIER,BROADCAST,MULTICAST,UP>

root@OpenWrt:/# brctl show
bridge name     bridge id               STP enabled     interfaces
br-vlan16               7fff.207c14a2b086       no              eth2.16
                                                        eth3.16
br-vlan17               7fff.207c14a2b086       no              eth2.17
                                                        eth3.17

root@OpenWrt:/# bridge vlan
port              vlan-id
br-vlan16         1 PVID Egress Untagged
eth2.16           1 PVID Egress Untagged
eth3.16           1 PVID Egress Untagged
br-vlan17         1 PVID Egress Untagged
eth2.17           1 PVID Egress Untagged
eth3.17           1 PVID Egress Untagged

Do I understand correctly that you are looking for a way to make a br-lan.XX ?
Then doesn't this work?

uci add network device
uci set network.@device[-1].type='8021q'
uci set network.@device[-1].ifname='br-lan'
uci set network.@device[-1].vid='40'
uci set network.@device[-1].name='br-lan.40'
uci set network.@device[-1].ipv6='0'

I asked a few months ago if someone could point me to some initial code so I could create exactly that: a Full VLAN aware bridge. Luci bridge

Unfortunately no replies or suggestions. Ever since OpenWrt made the switch to DSA we are not able to properly configure the bridge.

As you can see from all the replies about VLANs they are all “old style” non-aware suggestions/solutions.

For now: using your own scripts is the only way to “automate” what you want.

@drbrains I think I have found it... At least it "looks good"...
(As always, I have not made any notes what I have tried and what not...)

Maybe @jow could give a hint why the notation on config bridge-vlan supprts list ports '${NIC}:t?

config device
        option  name    'br-vlan'
        option  type    'bridge'
        list    ports   'eth2'
        list    ports   'eth3'

config bridge-vlan
        option  device  'br-vlan'
        option  vlan    '16'
        list    ports   'eth2:t'
        list    ports   'eth3:t'

config bridge-vlan
        option  device  'br-vlan'
        option  vlan    '17'
        list    ports   'eth2:t'
        list    ports   'eth3:t'


config interface 'vlan16'
        option  device  'br-vlan.16'
        option  proto   'static'
        option  ip6class        'local'
        option  ip6assign       '64'


config interface 'vlan17'
        option  device  'br-vlan.17'
        option  proto   'static'
        option  ip6class        'local'
        option  ip6assign       '64'

This results in:

root@OpenWrt:/# ip -d a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0 minmtu 0 maxmtu 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc mq state DOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:84 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 9216 numtxqueues 8 numrxqueues 8 gso_max_size 65536 gso_max_segs 65535
3: eth1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:85 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 9216 numtxqueues 8 numrxqueues 8 gso_max_size 65536 gso_max_segs 65535
4: eth2: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br-vlan state DOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:86 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 9216
    bridge_slave state disabled priority 32 cost 100 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8001 port_no 0x1 designated_port 32769 designated_cost 0 designated_bridge 7fff.20:7C:14:A2:B0:86 designated_root 7fff.20:7C:14:A2:B0:86 hold_timer    0.00 message_age_timer    0.00 forward_delay_timer    0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on mcast_to_unicast off neigh_suppress off group_fwd_mask 0 group_fwd_mask_str 0x0 vlan_tunnel off isolated off numtxqueues 8 numrxqueues 8 gso_max_size 65536 gso_max_segs 65535
5: eth3: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc mq master br-vlan state DOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:87 brd ff:ff:ff:ff:ff:ff promiscuity 1 minmtu 68 maxmtu 9216
    bridge_slave state disabled priority 32 cost 100 hairpin off guard off root_block off fastleave off learning on flood on port_id 0x8002 port_no 0x2 designated_port 32770 designated_cost 0 designated_bridge 7fff.20:7C:14:A2:B0:86 designated_root 7fff.20:7C:14:A2:B0:86 hold_timer    0.00 message_age_timer    0.00 forward_delay_timer    0.00 topology_change_ack 0 config_pending 0 proxy_arp off proxy_arp_wifi off mcast_router 1 mcast_fast_leave off mcast_flood on mcast_to_unicast off neigh_suppress off group_fwd_mask 0 group_fwd_mask_str 0x0 vlan_tunnel off isolated off numtxqueues 8 numrxqueues 8 gso_max_size 65536 gso_max_segs 65535
16: br-vlan: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:86 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 68 maxmtu 65535
    bridge forward_delay 800 hello_time 100 max_age 1000 ageing_time 30000 stp_state 0 priority 32767 vlan_filtering 1 vlan_protocol 802.1Q bridge_id 7fff.20:7C:14:A2:B0:86 designated_root 7fff.20:7C:14:A2:B0:86 root_port 0 root_path_cost 0 topology_change 0 topology_change_detected 0 hello_timer    0.00 tcn_timer    0.00 topology_change_timer    0.00 gc_timer   57.93 vlan_default_pvid 1 vlan_stats_enabled 0 vlan_stats_per_port 0 group_fwd_mask 0 group_address 01:80:c2:00:00:00 mcast_snooping 0 mcast_router 1 mcast_query_use_ifaddr 0 mcast_querier 0 mcast_hash_elasticity 16 mcast_hash_max 512 mcast_last_member_count 2 mcast_startup_query_count 2 mcast_last_member_interval 100 mcast_membership_interval 26000 mcast_querier_interval 25500 mcast_query_interval 12500 mcast_query_response_interval 1000 mcast_startup_query_interval 3125 mcast_stats_enabled 0 mcast_igmp_version 2 mcast_mld_version 1 nf_call_iptables 0 nf_call_ip6tables 0 nf_call_arptables 0 numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
17: br-vlan.16@br-vlan: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:86 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 0 maxmtu 65535
    vlan protocol 802.1Q id 16 <REORDER_HDR> numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet6 fdb3:5cf2:aed4::1/64 scope global tentative noprefixroute
       valid_lft forever preferred_lft forever
18: br-vlan.17@br-vlan: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000
    link/ether 20:7c:14:a2:b0:86 brd ff:ff:ff:ff:ff:ff promiscuity 0 minmtu 0 maxmtu 65535
    vlan protocol 802.1Q id 17 <REORDER_HDR> numtxqueues 1 numrxqueues 1 gso_max_size 65536 gso_max_segs 65535
    inet6 fdb3:5cf2:aed4:1::1/64 scope global tentative noprefixroute
       valid_lft forever preferred_lft forever

Note that on br-vlan: vlan_filtering 1 is set. Yeah cool nice.
And, br-vlan.16@br-vlan and br-vlan.17@br-vlan each has vlan protocol 802.1Q id ${ID} set. Sweet.

brctl and bridge vlan also does look good so far!

root@OpenWrt:/# brctl show
bridge name     bridge id               STP enabled     interfaces
br-vlan         7fff.207c14a2b086       no              eth2
                                                        eth3
root@OpenWrt:/#
root@OpenWrt:/# bridge vlan
port              vlan-id
eth2              16
                  17
eth3              16
                  17
br-vlan           16
                  17

@_bernd - your configuration looks correct and is the canonical way to make a single VLAN-aware bridge acting as "virtual switch".

Personally I additionally call my personal "virtual switch" bridge "switch0" instead of br-whatever to be even more explicit (and because I'm used to the switch0 identifier from swconfig times).

The list ports entries in the config device section itself are redundant - they'll default to the union of all ports mentioned in bridge-vlan sections belonging to the bridge.

1 Like

Yeah naming conventions; an never ending topic for discussion ^^

Still have no opinion on that, I guess. I just wanted to get it working at first, before I move on porting my config from an old ath9k to x86.

PS: But my actual question was why the ${NIC}:t notation works at all. :wink: I was under the impression that its only a feature for DSA capable chips?

Edit: PPS: thanks for confirming that it's correct this way!

No, that's a common misconception to conflate configuration support for bridge VLANs and DSA support.

Bridge VLAN config is DSA agnostic and works on every system while a DSA enabled device requires bridge VLANs to be useful. Very simply speaking "DSA = hardware offloaded bridge VLANs".

2 Likes

Only semi related, but what confuses me is the following config.
I need a single tagged interface for my WAN which is an VDSL2+whatsoever.
The following seams to achieve it, even its using bridge-vlan.

config bridge-vlan
        option  device          'eth0'
        option  vlan            '7'
        list    ports           'eth0:t'

config device
        option  name            'eth0.7'
        option  macaddr         '90:9a:4a:XX:XX:XX'

config interface 'wan'
        option  device          'eth0.7'
        option  proto           'pppoe'
        option  ipv6            'auto'

config interface 'wan6'
        option  device          'eth0.7'
        option  proto           'dhcpv6'
        option  reqaddress      'try'
        option  reqprefix       '56'

And I was unable to make this work:

config device
	option type            '8021q'
	option ifname          'eth0'
	option vid             '7'
	option name            'wan'

This topic was automatically closed 10 days after the last reply. New replies are no longer allowed.