Browse Source
This reverts commit 96b87196b0
.
This commit was not meant to go into master.
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
master
4 changed files with 0 additions and 364 deletions
@ -1,40 +0,0 @@ |
|||
include $(TOPDIR)/rules.mk |
|||
|
|||
PKG_NAME:=dsaconfig |
|||
PKG_RELEASE:=1 |
|||
PKG_LICENSE:=GPL-2.0 |
|||
|
|||
include $(INCLUDE_DIR)/package.mk |
|||
|
|||
define Package/dsaconfig |
|||
SECTION:=net |
|||
CATEGORY:=Network |
|||
MAINTAINER:=Jo-Philipp Wich <jo@mein.io> |
|||
TITLE:=UCI configuration support for DSA switch VLAN filtering |
|||
DEPENDS:= +ip-bridge +ip-full |
|||
PKGARCH:=all |
|||
endef |
|||
|
|||
define Package/dsaconfig/description |
|||
This package provides UCI configuration abstraction for VLAN filter rules |
|||
on top of DSA switches. |
|||
endef |
|||
|
|||
define Build/Compile |
|||
endef |
|||
|
|||
define Build/Configure |
|||
endef |
|||
|
|||
define Package/dsaconfig/install |
|||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface |
|||
$(INSTALL_DATA) ./files/dsaconfig.hotplug $(1)/etc/hotplug.d/iface/01-dsaconfig |
|||
|
|||
$(INSTALL_DIR) $(1)/lib/network |
|||
$(INSTALL_DATA) ./files/dsaconfig.include $(1)/lib/network/dsaconfig.sh |
|||
|
|||
$(INSTALL_DIR) $(1)/sbin |
|||
$(INSTALL_BIN) ./files/dsaconfig.sh $(1)/sbin/dsaconfig |
|||
endef |
|||
|
|||
$(eval $(call BuildPackage,dsaconfig)) |
@ -1,7 +0,0 @@ |
|||
#!/bin/sh |
|||
|
|||
if [ "$ACTION" = ifup ] && [ "$INTERFACE" = loopback ]; then |
|||
. /lib/network/dsaconfig.sh |
|||
setup_switch |
|||
fi |
|||
|
@ -1,11 +0,0 @@ |
|||
#!/bin/sh |
|||
|
|||
setup_switch() { |
|||
# Skip switch setup on network restart. The netifd process |
|||
# will be started afterwards and remove all interfaces again... |
|||
if [ "$initscript" = /etc/init.d/network ] && [ "$action" = restart ]; then |
|||
return 0 |
|||
fi |
|||
|
|||
/sbin/dsaconfig apply 2>&1 | logger -t dsaconfig |
|||
} |
@ -1,306 +0,0 @@ |
|||
#!/bin/sh |
|||
|
|||
. /lib/functions.sh |
|||
. /lib/functions/network.sh |
|||
|
|||
switch_names="" |
|||
|
|||
warn() { |
|||
echo "$@" >&2 |
|||
} |
|||
|
|||
clear_port_vlans() { |
|||
local port=$1 |
|||
local self=$2 |
|||
local vlans=$(bridge vlan show dev "$port" | sed -ne 's#^[^ ]* \+\([0-9]\+\).*$#\1#p') |
|||
|
|||
local vlan |
|||
for vlan in $vlans; do |
|||
bridge vlan del vid "$vlan" dev "$port" $self |
|||
done |
|||
} |
|||
|
|||
lookup_switch() { |
|||
local cfg=$1 |
|||
local swname |
|||
|
|||
config_get swname "$cfg" switch |
|||
|
|||
# Auto-determine switch if not specified ... |
|||
if [ -z "$swname" ]; then |
|||
case "$switch_names" in |
|||
*\ *) |
|||
warn "VLAN section '$cfg' does not specify a switch but multiple switches present, using first one" |
|||
swname=${switch_names%% *} |
|||
;; |
|||
*) |
|||
swname=${switch_names} |
|||
;; |
|||
esac |
|||
|
|||
# ... otherwise check if the referenced switch is declared |
|||
else |
|||
case " $switch_names " in |
|||
*" $swname "*) : ;; |
|||
*) |
|||
warn "Switch '$swname' specified by VLAN section '$cfg' does not exist" |
|||
return 1 |
|||
;; |
|||
esac |
|||
fi |
|||
|
|||
export -n "switch=$swname" |
|||
} |
|||
|
|||
validate_vid() { |
|||
local vid=$1 |
|||
|
|||
case "$vid" in |
|||
[1-9]|[1-9][0-9]|[1-9][0-9][0-9]|[1-4][0-9][0-9][0-9]) |
|||
if [ $vid -gt 4096 ]; then |
|||
return 1 |
|||
fi |
|||
;; |
|||
*) |
|||
return 1 |
|||
;; |
|||
esac |
|||
|
|||
return 0 |
|||
} |
|||
|
|||
setup_switch() { |
|||
local cfg=$1 |
|||
local cpu |
|||
|
|||
# Read configured CPU port from uci ... |
|||
config_get cpu "$cfg" cpu_port |
|||
|
|||
# ... if unspecified, find first CPU port |
|||
if [ -z "$cpu" ]; then |
|||
local e |
|||
for e in /sys/class/net/*/dsa; do |
|||
if [ -d "$e" ]; then |
|||
cpu=${e%/dsa} |
|||
cpu=${cpu##*/} |
|||
break |
|||
fi |
|||
done |
|||
fi |
|||
|
|||
# Bail out if we cannot determine the CPU port |
|||
if [ -z "$cpu" ]; then |
|||
warn "Unable to determine CPU port for switch '$cfg'" |
|||
return 1 |
|||
fi |
|||
|
|||
append switch_names "$cfg" |
|||
|
|||
# Prevent netifd from picking up our switch bridge just yet |
|||
network_defer_device "$cfg" |
|||
|
|||
# Increase MTU of CPU port to 1508 to accomodate for VID + DSA tag |
|||
ip link set "$cpu" mtu 1508 |
|||
ip link set "$cpu" up |
|||
|
|||
# (Re)create switch bridge device in case it is not yet set up |
|||
local filtering=$(cat "/sys/class/net/$cfg/bridge/vlan_filtering" 2>/dev/null) |
|||
if [ ${filtering:-0} != 1 ]; then |
|||
ip link set "$cfg" down 2>/dev/null |
|||
ip link delete dev "$cfg" 2>/dev/null |
|||
ip link add name "$cfg" type bridge |
|||
echo 1 > "/sys/class/net/$cfg/bridge/vlan_filtering" |
|||
fi |
|||
|
|||
ip link set "$cfg" up |
|||
|
|||
# Unbridge DSA ports and flush any VLAN filters on them, they're added back later |
|||
local port |
|||
for port in /sys/class/net/*"/upper_${cfg}"; do |
|||
if [ -e "$port" ]; then |
|||
port=${port%/upper_*} |
|||
port=${port##*/} |
|||
|
|||
ip link set "$port" nomaster |
|||
|
|||
# Unbridging the port should already clear VLANs, but be safe |
|||
clear_port_vlans "$port" |
|||
fi |
|||
done |
|||
|
|||
# Clear any VLANs on the switch bridge, they're added back later |
|||
clear_port_vlans "$cfg" self |
|||
} |
|||
|
|||
setup_switch_vlan() { |
|||
local cfg=$1 |
|||
local switch vlan ports |
|||
|
|||
config_get switch "$cfg" switch |
|||
config_get vlan "$cfg" vlan |
|||
config_get ports "$cfg" ports |
|||
|
|||
lookup_switch "$cfg" || return 1 |
|||
validate_vid "$vlan" || { |
|||
warn "VLAN section '$cfg' specifies an invalid VLAN ID '$vlan'" |
|||
return 1 |
|||
} |
|||
|
|||
# Setup ports |
|||
local port tag pvid |
|||
for port in $ports; do |
|||
tag=${port#*.} |
|||
port=${port%.*} |
|||
pvid= |
|||
|
|||
if [ "$tag" != "$port" ] && [ "$tag" = t ]; then |
|||
tag=tagged |
|||
else |
|||
tag=untagged |
|||
fi |
|||
|
|||
# Add the port to the switch bridge and delete the default |
|||
# VLAN 1 if it is not yet joined to the switch. |
|||
if [ ! -e "/sys/class/net/$port/upper_$switch" ]; then |
|||
ip link set dev "$port" up |
|||
ip link set dev "$port" master "$switch" |
|||
|
|||
# Get rid of default VLAN 1 |
|||
bridge vlan del vid 1 dev "$port" |
|||
fi |
|||
|
|||
# Promote the first untagged VLAN of this port to the PVID |
|||
if [ "$tag" = untagged ] && ! bridge vlan show dev "$port" | grep -qi pvid; then |
|||
pvid=pvid |
|||
fi |
|||
|
|||
# Add VLAN filter entry for port |
|||
bridge vlan add dev "$port" vid $vlan $pvid $tag |
|||
done |
|||
|
|||
# Make the switch bridge itself handle the VLAN as well |
|||
bridge vlan add dev "$switch" self vid $vlan tagged |
|||
} |
|||
|
|||
setup_switch_port() { |
|||
local cfg=$1 |
|||
local switch port pvid tag |
|||
|
|||
config_get port "$cfg" port |
|||
config_get pvid "$cfg" pvid |
|||
|
|||
lookup_switch "$cfg" || return 1 |
|||
validate_vid "$pvid" || { |
|||
warn "Port section '$cfg' specifies an invalid PVID '$pvid'" |
|||
return 1 |
|||
} |
|||
|
|||
# Disallow setting the PVID of the switch bridge itself |
|||
[ "$port" != "$switch" ] || { |
|||
warn "Port section '$cfg' must not change PVID of the switch bridge" |
|||
return 1 |
|||
} |
|||
|
|||
# Determine existing VLAN config |
|||
local vlanspec=$(bridge vlan show dev "$port" vid "$pvid" 2>/dev/null | sed -ne2p) |
|||
echo "$vlanspec" | grep -qi untagged && tag=untagged || tag=tagged |
|||
|
|||
bridge vlan add vid "$pvid" dev "$port" pvid $tag |
|||
} |
|||
|
|||
apply_config() { |
|||
config_load network |
|||
config_foreach setup_switch dsa |
|||
|
|||
# If no switch is explicitely declared, synthesize switch0 |
|||
if [ -z "$switch_names" ] && ! setup_switch switch0; then |
|||
warn "No DSA switches found" |
|||
return 1 |
|||
fi |
|||
|
|||
config_foreach setup_switch_vlan dsa_vlan |
|||
config_foreach setup_switch_port dsa_port |
|||
|
|||
# Ready switch bridge devices |
|||
local switch |
|||
for switch in $switch_names; do |
|||
network_ready_device "$switch" |
|||
done |
|||
} |
|||
|
|||
show_switch() { |
|||
local switch=$1 |
|||
|
|||
printf "Switch: %s\n" "$switch" |
|||
printf "VLAN/" |
|||
|
|||
local port ports |
|||
for port in "/sys/class/net/$switch/lower_"*; do |
|||
port=${port##*/lower_} |
|||
|
|||
|
|||
printf " | %-5s" "$port" |
|||
append ports "$port" |
|||
done |
|||
|
|||
printf " |\nLink:" |
|||
|
|||
for port in $ports; do |
|||
local carrier=$(cat "/sys/class/net/$port/carrier") |
|||
local duplex=$(cat "/sys/class/net/$port/duplex") |
|||
local speed=$(cat "/sys/class/net/$port/speed") |
|||
|
|||
if [ ${carrier:-0} -eq 0 ]; then |
|||
printf " | %-5s" "down" |
|||
else |
|||
[ "$duplex" = "full" ] && duplex=F || duplex=H |
|||
printf " | %4d%s" "$speed" "$duplex" |
|||
fi |
|||
done |
|||
|
|||
local vlans=$(bridge vlan show dev "$switch" | sed -ne 's#^[^ ]* \+\([0-9]\+\).*$#\1#p') |
|||
local vlan |
|||
for vlan in $vlans; do |
|||
printf " |\n%4d " "$vlan" |
|||
|
|||
for port in $ports; do |
|||
local pvid="" utag="" word |
|||
for word in $(bridge vlan show dev "$port" vid "$vlan"); do |
|||
case "$word" in |
|||
PVID) pvid="*" ;; |
|||
"$vlan") utag="t" ;; |
|||
Untagged) utag="u" ;; |
|||
esac |
|||
done |
|||
|
|||
printf " | %-2s " "$utag$pvid" |
|||
done |
|||
done |
|||
|
|||
printf " |\n\n" |
|||
} |
|||
|
|||
add_switch() { |
|||
append switch_names "$1" |
|||
} |
|||
|
|||
show_config() { |
|||
config_load network |
|||
config_foreach add_switch dsa |
|||
|
|||
local switch |
|||
for switch in ${switch_names:-switch0}; do |
|||
show_switch "$switch" |
|||
done |
|||
} |
|||
|
|||
|
|||
case "$1" in |
|||
show) show_config ;; |
|||
apply) apply_config ;; |
|||
*) |
|||
echo "Usage: ${0##*/} show" |
|||
echo " ${0##*/} apply" |
|||
exit 1 |
|||
;; |
|||
esac |
Loading…
Reference in new issue