1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter.git synced 2025-02-14 12:21:53 +00:00

Added swconfig-wrapper to take control about DSA switch configuration

This commit is contained in:
Olli 2021-03-10 00:53:42 +01:00
parent 8228dbbbde
commit 75e5ee2fdd
4 changed files with 406 additions and 142 deletions

View file

@ -255,8 +255,11 @@ if [ "$OMR_TARGET" = "bpi-r1" ]; then
done
echo "done"
# Mark as DSA
touch "$OMR_TARGET/source/target/linux/sunxi/base-files/etc/.lamobo-r1.dsa"
# Create DSA port map file (will be filled on first boot, by uci-defaults and tells the system, that it is in DSA mode)
touch "$OMR_TARGET/source/target/linux/sunxi/base-files/etc/dsa.map"
# Remove the b53 hack in preinit
rm -f "$OMR_TARGET/source/target/linux/sunxi/base-files/lib/preinit/03_b53_hack.sh"
else
# Remove ip-bridge
echo -n "Removing ip-bridge support from openwrt config..."
@ -272,9 +275,6 @@ if [ "$OMR_TARGET" = "bpi-r1" ]; then
sed -i "s/CONFIG_${i}/# CONFIG_${i} is not set/" "$OMR_TARGET/source/target/linux/sunxi/cortexa7/config-$OMR_KERNEL"
done
echo "done"
# Mark as PHY
touch "$OMR_TARGET/source/target/linux/sunxi/base-files/etc/.lamobo-r1.phy"
fi
# Add led support

View file

@ -1,56 +1,54 @@
if [ -f "/etc/.lamobo-r1.dsa" ]; then
uci delete network.@switch_vlan[1]
uci delete network.@switch_vlan[0]
uci delete network.@switch[0]
uci set network.lan.ifname="wan eth0"
uci set network.lan.type="bridge"
uci set network.wan1.ifname="lan1 eth0.11"
uci set network.wan1.type="bridge"
uci set network.wan2.ifname="lan2 eth0.12"
uci set network.wan2.type="bridge"
uci set network.wan3.ifname="lan3 eth0.13"
uci set network.wan3.type="bridge"
uci set network.wan4.ifname="lan4 eth0.14"
uci set network.wan4.type="bridge"
else
uci delete network.@switch_vlan[0]
uci delete network.@switch_vlan[1]
uci add network switch_vlan
uci set network.@switch_vlan[0].vlan=5
uci set network.@switch_vlan[0].ports="8 3"
uci set network.@switch_vlan[0].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[1].vlan=1
uci set network.@switch_vlan[1].ports="8t 4"
uci set network.@switch_vlan[1].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[2].vlan=2
uci set network.@switch_vlan[2].ports="8t 0"
uci set network.@switch_vlan[2].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[3].vlan=3
uci set network.@switch_vlan[3].ports="8t 1"
uci set network.@switch_vlan[3].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[4].vlan=4
uci set network.@switch_vlan[4].ports="8t 2"
uci set network.@switch_vlan[4].device="switch0"
uci set network.lan.ifname="eth0"
uci set network.wan1.ifname="eth0.1"
uci set network.wan2.ifname="eth0.2"
uci set network.wan3.ifname="eth0.3"
uci set network.wan4.ifname="eth0.4"
if [ -f "/etc/dsa.map" ]; then
echo 'ports="0 1 2 3 4 8"
port_3="wan"
port_4="lan1"
port_0="lan2"
port_1="lan3"
port_2="lan4"
port_8="eth0"
port_3_name="lan"
port_4_name="wan1"
port_0_name="wan2"
port_1_name="wan3"
port_2_name="wan4"
port_8_name="cpu"
port_cpu="8"
' > /etc/dsa.map
fi
uci delete network.@switch_vlan[0]
uci delete network.@switch_vlan[1]
uci add network switch_vlan
uci set network.@switch_vlan[0].vlan=10
uci set network.@switch_vlan[0].ports="8t 3"
uci set network.@switch_vlan[0].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[1].vlan=11
uci set network.@switch_vlan[1].ports="8t 4"
uci set network.@switch_vlan[1].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[2].vlan=12
uci set network.@switch_vlan[2].ports="8t 0"
uci set network.@switch_vlan[2].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[3].vlan=13
uci set network.@switch_vlan[3].ports="8t 1"
uci set network.@switch_vlan[3].device="switch0"
uci add network switch_vlan
uci set network.@switch_vlan[4].vlan=14
uci set network.@switch_vlan[4].ports="8t 2"
uci set network.@switch_vlan[4].device="switch0"
uci set network.lan.ifname="eth0.10"
uci set network.wan1.ifname="eth0.11"
uci set network.wan2.ifname="eth0.12"
uci set network.wan3.ifname="eth0.13"
uci set network.wan4.ifname="eth0.14"
uci commit
exit 0

View file

@ -1,84 +0,0 @@
#!/bin/sh
# Copyright (C) 2009 OpenWrt.org
# Copyright (c) 2021 Oliver Welter
setup_switch_dsa() {
local tries=15
/bin/sleep 10
local bridge_names=`/sbin/uci show network | /bin/grep type | /bin/grep bridge | /usr/bin/cut -d . -f2`
for name in $bridge_names; do
local bridge_interface=`/sbin/uci get network.$name.ifname`
local trycount=1
while true; do
local my_interface=""
for intf in $bridge_interface; do
local eth=`/bin/echo $intf | /bin/grep -v eth`
if [ "$eth" != "" ]; then
my_interface="$eth"
fi
done
if [ "$my_interface" = "" ]; then
break
fi
local has_interface=`/sbin/ifconfig $my_interface >/dev/null 2>&1 && echo 1`
if [ "$has_interface" = "" ]; then
/bin/sleep 1
trycount=$(($trycount+1))
if [ $trycount -gt $tries ]; then
break
fi
else
break
fi
done
if [ "$has_interface" = "1" -a "$bridge_interface" != "" ]; then
for iface in $bridge_interface; do
local eth=`/bin/echo $iface | /bin/grep eth`
if [ "$eth" != "" ]; then
local vlan=`/bin/echo $iface | /usr/bin/cut -d . -f2`
if [ "$vlan" != "" ]; then
if [ "$vlan" = "$eth" ]; then
/usr/bin/logger -t switch.sh "Found interface $my_interface for alias $iface in bridge $name - adding to master"
/usr/sbin/bridge vlan add dev $my_interface vid 1 master
else
/usr/bin/logger -t switch.sh "Found interface $my_interface for alias $iface in bridge $name - adding to VLAN $vlan"
/usr/sbin/bridge vlan add dev $my_interface vid $vlan pvid untagged
fi
fi
fi
done
fi
done
}
setup_switch_dev() {
local name
config_get name "$1" name
name="${name:-$1}"
[ -d "/sys/class/net/$name" ] && ip link set dev "$name" up
swconfig dev "$name" load network
}
setup_switch() {
config_load network
if [ -f "/etc/.lamobo-r1.dsa" ]; then
setup_switch_dsa & return
else
config_foreach setup_switch_dev switch
fi
}

View file

@ -0,0 +1,350 @@
#!/bin/sh
# swconfig wrapper for BPI-R1 switch in DSA enabled environment
# Copyright (c) 2021 Oliver Welter <oliver@welter.rocks>
SWCONFIG="/sbin/swconfig"
SWCONFIG_REAL="$SWCONFIG.real"
SWCONFIG_DSA="$SWCONFIG.dsa"
SWCONFIG_WRAPPER="$SWCONFIG-wrapper.sh"
SWCONFIG_LINK=`readlink $SWCONFIG`
DSA_MAP="/etc/dsa.map"
DSA_MODE=0
UCI="/sbin/uci"
GREP="/bin/grep"
CUT="/usr/bin/cut"
AWK="/usr/bin/awk"
IP="/sbin/ip"
SWITCHNULL="switch0"
[ -f "$DSA_MAP" ] && DSA_MODE=1
if [ "$1" = "setup-wrapper" ]; then
if [ "$SWCONFIG_LINK" = "$SWCONFIG_WRAPPER" ]; then
echo "Already linked to wrapper" >/dev/stderr
exit 1
elif [ -x "$SWCONFIG" ]; then
mv $SWCONFIG $SWCONFIG_REAL && \
ln -sf $SWCONFIG_WRAPPER $SWCONFIG && \
exit 0 || exit $?
else
echo "Unable to find swconfig binary" >/dev/stderr
exit 2
fi
elif [ "$DSA_MODE" = 0 ]; then
if [ "$1" = "" ]; then
$SWCONFIG_REAL && exit 0 || exit $?
elif [ "$2" = "" ]; then
$SWCONFIG_REAL $1 && exit 0 || exit $?
elif [ "$3" = "" ]; then
$SWCONFIG_REAL $1 $2 && exit 0 || exit $?
elif [ "$4" = "" ]; then
$SWCONFIG_REAL $1 $2 $3 && exit 0 || exit $?
elif [ "$5" = "" ]; then
$SWCONFIG_REAL $1 $2 $3 $4 && exit 0 || exit $?
elif [ "$6" = "" ]; then
$SWCONFIG_REAL $1 $2 $3 $4 $5 && exit 0 || exit $?
elif [ "$7" = "" ]; then
$SWCONFIG_REAL $1 $2 $3 $4 $5 $6 && exit 0 || exit $?
else
exit 255
fi
fi
. $DSA_MAP
get_interface_by_portlist() {
local ports="$1"
for port in $ports; do
port_id=`echo $port | $CUT -d "t" -f1`
port_tagged=`echo $port | $GREP "t" >/dev/null 2>&1 && echo 1 || echo 0`
interface=`eval echo "\${port_$port_id}"`
name=`eval echo "\${port_name_$port_id}"`
echo "$port_id:$port_tagged:$interface:$name"
done
}
swconfig_usage() {
echo "WARNING: swconfig runs in DSA wrapper mode"
$SWCONFIG_REAL && exit 0 || exit $?
}
swconfig_port_get() {
local port="$1"
local key="$2"
return 0
}
swconfig_vlan_get() {
local vlan="$1"
local key="$2"
return 0
}
swconfig_get() {
local key="$1"
case $key in
reset|reset_mib|apply)
# This is ignored, but leads to exit code 0 to not confuse the networking scripts
return 0
;;
*)
echo "Unknown key $key for device" >/dev/stderr
return 1
;;
esac
return 0
}
swconfig_port_set() {
local port="$1"
local key="$2"
local val="$3"
case $key in
*)
echo "Unknown key $key for port" >/dev/stderr
return 1
;;
esac
return 0
}
swconfig_vlan_set() {
local vlan="$1"
local key="$2"
local val="$3"
case $key in
*)
echo "Unknown key $key for vlan" >/dev/stderr
return 1
;;
esac
return 0
}
swconfig_set() {
local key="$1"
local val="$2"
case $key in
reset|reset_mib|apply)
# This is ignored, but leads to exit code 0 to not confuse the networking scripts
return 0
;;
*)
echo "Unknown key $key for device" >/dev/stderr
return 1
;;
esac
return 0
}
swconfig_port_load() {
local port="$1"
local config="$2"
return 0
}
swconfig_vlan_load() {
local vlan="$1"
local config="$2"
return 0
}
swconfig_load() {
local config="$1"
# This is the part, where the magic happens.
# Due to its structure, swconfig gets the configuration to use by itself.
# At this point, we use uci to fetch the configuration for the vlans to setup.
[ "$config" != "network" ] && return 1
# Set the CPU port
local CPUPORT=`eval echo "\${port_$port_cpu}"`
# Bring up the CPU port
$IP link set $CPUPORT up
for section in `$UCI show $config | $GREP "=switch_vlan" | $CUT -d "=" -f1`; do
section_id=`$UCI show $section | $GREP "=switch_vlan" | $CUT -d "=" -f1 | $CUT -d "." -f2`
vlan=`$UCI show $config.$section_id.vlan | $CUT -d "=" -f2 | $CUT -d "'" -f2`
ports=`$UCI show $config.$section_id.ports | $CUT -d "=" -f2 | $CUT -d "'" -f2`
device=`$UCI show $config.$section_id.device | $CUT -d "=" -f2 | $CUT -d "'" -f2`
[ "$device" != "$SWITCHNULL" ] && continue
for iface in `get_interface_by_portlist $ports`; do
port_id=`echo $iface | $CUT -d ":" -f1`
# We just want the CPU ports here
[ "$port_id" != "$port_cpu" ] && continue
port_tagged=`echo $iface | $CUT -d ":" -f2`
interface=`echo $iface | $CUT -d ":" -f3`
name=`echo $iface | $CUT -d ":" -f4`
# At this point, we have all we need.
if [ "$port_tagged" = 1 ]; then
# Tag the traffic on CPU port as master interface
$IP link add link $interface name $interface.$vlan type vlan id $vlan
# Bring up the master interface before the slaves
$IP link set $interface.$vlan up
fi
done
for iface in `get_interface_by_portlist $ports`; do
port_id=`echo $iface | $CUT -d ":" -f1`
# We just want the slave ports here
[ "$port_id" = "$port_cpu" ] && continue
port_tagged=`echo $iface | $CUT -d ":" -f2`
interface=`echo $iface | $CUT -d ":" -f3`
name=`echo $iface | $CUT -d ":" -f4`
if [ "$port_tagged" = 1 ]; then
interface="$interface.$vlan"
fi
# Bring up the slave interface
$IP link set $interface up
# Create the bridge
$IP link add name $name type bridge
# Set VLAN filtering and PVID
$IP link set dev $name type bridge vlan_filtering 1 vlan_default_pvid $vlan
done
for iface in `get_interface_by_portlist $ports`; do
port_id=`echo $iface | $CUT -d ":" -f1`
port_tagged=`echo $iface | $CUT -d ":" -f2`
interface=`echo $iface | $CUT -d ":" -f3`
name=`echo $iface | $CUT -d ":" -f4`
if [ "$port_tagged" = 1 ]; then
interface="$interface.$vlan"
fi
# Add port to its corresponding bridge
$IP link set dev $interface master $name
done
done
return 0
}
swconfig_port_show() {
local port="$1"
return 0
}
swconfig_vlan_show() {
local vlan="$1"
return 0
}
swconfig_show() {
return 0
}
case $1 in
dev)
device="$2"
mode="$3"
op="$5"
key="$6"
val="$7"
port=""
vlan=""
case $3 in
port)
port="$4"
;;
vlan)
vlan="$4"
;;
*)
mode="switch"
op="$3"
key="$4"
val="$5"
;;
esac
case $op in
help)
$SWCONFIG_REAL $1 $2 $3 $4 && exit 0 || exit $?
;;
set)
if [ "$mode" = "port" ]; then
swconfig_port_set $port $key $val && exit 0 || exit $?
elif [ "$mode" = "vlan" ]; then
swconfig_vlan_set $vlan $key $val && exit 0 || exit $?
else
swconfig_set $key $val && exit 0 || exit $?
fi
;;
get)
if [ "$mode" = "port" ]; then
swconfig_port_get $port $key && exit 0 || exit $?
elif [ "$mode" = "vlan" ]; then
swconfig_vlan_get $vlan $key && exit 0 || exit $?
else
swconfig_get $key && exit 0 || exit $?
fi
;;
load)
if [ "$mode" = "port" ]; then
swconfig_port_load $port $key && exit 0 || exit $?
elif [ "$mode" = "vlan" ]; then
swconfig_vlan_load $vlan $key && exit 0 || exit $?
else
swconfig_load $key && exit 0 || exit $?
fi
;;
show)
if [ "$mode" = "port" ]; then
swconfig_port_show $port && exit 0 || exit $?
elif [ "$mode" = "vlan" ]; then
swconfig_vlan_show $vlan && exit 0 || exit $?
else
swconfig_show && exit 0 || exit $?
fi
;;
*)
swconfig_usage
;;
esac
;;
list)
echo $SWITCHNULL
exit 0
;;
*)
swconfig_usage
;;
esac