BPI-R1 network configuration on Linux kernel 5.X

How should output of ip link and ip address look on a working BPI-R1?

Should there be vlan information in ip -d link? The -d is option for detailed information.

Context BPI-M1/M1/R1 new image:Debian 10 buster mate desktop with grub support (boot-2019.07 + kernel 5.1.1)

At https://www.kernel.org/doc/html/latest/networking/dsa/configuration.html#configuration-without-tagging-support is documented how it should work.

And I got it, bpi-r1 with Linux kernel 5.1.1, working :slight_smile:

Part of getting it working was sudo systemctl disable network-manager, it prevents NM from interfering with network interfaces it can’t handle.

My version of what is documented in the above ( kernel.org dsa configuration ) URL

# tag traffic on CPU port
ip link add link eth0 name eth0.23 type vlan id 23
ip link add link eth0 name eth0.42 type vlan id 42

# The master interface needs to be brought up before the slave ports.
ip link set eth0 up
ip link set eth0.23 up
ip link set eth0.42 up

# bring up the slave interfaces
ip link set wan up
ip link set lan1 up
ip link set lan2 up
ip link set lan3 up
ip link set lan4 up

# create bridges
ip link add name lan type bridge
ip link add name uplink type bridge

# activate VLAN filtering and set port vlan ID
ip link set dev    lan type bridge vlan_filtering 1 vlan_default_pvid 23
ip link set dev uplink type bridge vlan_filtering 1 vlan_default_pvid 42

# add ports to bridges
ip link set dev eth0.23 master lan
ip link set dev    lan1 master lan
ip link set dev    lan2 master lan
ip link set dev    lan3 master lan
ip link set dev    lan4 master lan
ip link set dev eth0.42 master uplink
ip link set dev     wan master uplink

# tag traffic on ports
## bridge vlan add dev lan1 vid 23 pvid untagged
## bridge vlan add dev lan2 vid 23 pvid untagged
## bridge vlan add dev lan3 vid 23 pvid untagged
## bridge vlan add dev lan4 vid 23 pvid untagged
## bridge vlan add dev  wan vid 42 pvid untagged

# configure the VLANs
ip addr add dev lan
## ip addr add dev uplink

# bring up the bridge devices
ip link set lan up
## ip link set uplink up

dhclient uplink

# l l

So now I have

$ ip -4 a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    inet scope host lo
       valid_lft forever preferred_lft forever
11: lan: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet scope global lan
       valid_lft forever preferred_lft forever
12: uplink: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    inet brd scope global dynamic uplink
       valid_lft 57133sec preferred_lft 57133sec

I hope this is helpfull for others.

Go for this link: Configuration with DSA for b53125, in the Doc

And here, my journey to this document: https://forum.armbian.com/topic/3476-bpi-r1-with-new-b53-switch-driver-dsa/

amendum on the it works

Giving the uplink brigde the same MAC address as eth0 causes trouble.

If you want a presistent MAC address on brigde uplink, put a MAC address in configuration file. I use a MAC address that was once generated by systemd-networkd for that bridge.

For a yet unknown reason does eat my R1 with Linux kernel 5.1.1 dhcp answers.

Workaround is unplugging wan-port when DHCP is happening for another computer. That unplug can be done with ip link set dev wan down.

Parking here a script that does it automated:

    a tcpdump wrapper  and interface bouncer
    (bounce is "down, wait and up again")

 upon seeing a DHCP request
 it disables network interface briefly

 It is workaround for hardware where DHCP-replies get eaten.

 Geert Stappers  2019-12-28   GPLv2

    Copyright (C) 2019  Geert Stappers

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; version 2 of the License.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    GNU General Public License for more details.


import os
import pty
import re
import signal
import subprocess
import sys
import time

currently_hardcoded_parameter = '''
if len(sys.argv) < 2:
    sys.stderr.write("E: Missing interface name\n")
    sys.stderr.write("I: parameter required\n")
ifname = "wan"
mymac = "02:99:04:81:a6:82"
mymac = "aa:d1:1e:25:e2:e7"

proceed = True

lsl = ''  # last seen line
ec = 255  # exit code

debug_output_wanted = True
debug_output_wanted = False

def debug_output(string):
    if debug_output_wanted:

def control_c_handler(sig, frame):
    '''for exit on Control-C'''
    global proceed
    global ec
    if proceed is False:
        # Most likely Control-C has already been pressed
        sys.stderr.write(" I: Doing hasty closure\n")
        # No attempt is done to stop the subprocess
        # or any other cleanup.
        # main loop shall stop the subprocess
        proceed = False
        ec = 130

def control_backslash_handler(sig, frame):
    '''dump last seen line'''
    global lsl

def ip_link_set(ifname, state):
    cmd = "ip link set dev %s %s" % (ifname, state)
    debug_output("DBG link set %s" % cmd)

command = "tcpdump -li eth0.42 port bootps and not ether host " + mymac
debug_output("DBG command %s" % command)

# Now start executing
master_pty, slave_pty = pty.openpty()
process = subprocess.Popen(command.split(),
p_stdout = os.fdopen(master_pty)

time.sleep(1)  # To give process some headstart plus time to fail.
#                So the first process.poll() can see a aborted start.
#           Such as when ping can't resolve a hostname and instantly stops.

signal.signal(signal.SIGINT, control_c_handler)
signal.signal(signal.SIGQUIT, control_backslash_handler)

while proceed and process.poll() is None:
    line = p_stdout.readline()
    # NOTE Waiting (forever) for subprocess output happens in above line ...
    if len(line) > 0:
        lsl = line  # last seen line for CTRL-\ dump
        debug_output("DBG going down")
        ip_link_set(ifname, "down")
        time.sleep(1)  # Tolerant DHCP requests
        ip_link_set(ifname, "up")
        debug_output("DBG iface should be up")

_ = process.poll()  # to update the subprocess returncode

ec = int(str(process.returncode))


# l l


  • My own answer on my own question (that started this topic / thread ) is wrong. Because I have with the setting from above strange errors. Errors that I don’t see with an old configuration.
  • I still like to know how the configuration of a working BPI-R1 with kernel 5.X + DSA looks.
  • Meanwhile I’ll use old configuration.

I tried patching my own kernel with swconfig support and the right b53 config but I had no success. I also would be very interested in knowing how to patch/configure the new kernel.

Was in the begin used from openWRT. Mainline kernel 4.x is using Configuration with DSA for b53125

The idea of DSA is that you don’t need swconfig.

Regards Geert Stappers

Meanwhile I’ll use old configuration.