base-files: uci-defaults-new, config_generate: refactor code and drop old vlans
authorJo-Philipp Wich <jow@openwrt.org>
Thu, 3 Dec 2015 16:25:19 +0000 (16:25 +0000)
committerJo-Philipp Wich <jow@openwrt.org>
Thu, 3 Dec 2015 16:25:19 +0000 (16:25 +0000)
Remove support for now unused ucidef_add_switch_vlan(), move port->vlan and
vlan->interfaces conversion to uci-defaults-new.sh and massively simplify
config_generate.

This change prepares the following upcoming steps:

 * Eliminate use of ucidef_set_interface_lan_wan() for switch only devices
 * Merge ucidef_add_switch() with ucidef_add_switch_ports()

Signed-off-by: Jo-Philipp Wich <jow@openwrt.org>
SVN-Revision: 47719

package/base-files/files/bin/config_generate
package/base-files/files/lib/functions/uci-defaults-new.sh

index 1aa6d43e3f390ad92409d9cbd0d6cdfd74bed0ad..7e0e2acd3b2a30d62ddd110df562465ee6da238b 100755 (executable)
@@ -20,34 +20,26 @@ generate_static_network() {
        EOF
 }
 
-next_vlan=3
 generate_network() {
-       local vlan
+       local ifname macaddr type
 
        json_select network
-       json_select "$1"
-       json_get_vars ifname create_vlan macaddr
-       json_select ..
+               json_select "$1"
+                       json_get_vars ifname macaddr
+               json_select ..
        json_select ..
 
        [ -n "$ifname" ] || return
 
-       if [ "${create_vlan:-0}" -eq 1 ]; then
-               case "$1" in
-                       lan) vlan=1;;
-                       wan) vlan=2;;
-                       *)
-                               vlan=$next_vlan
-                               next_vlan=$((next_vlan + 1))
-                       ;;
-               esac
-       fi
-
-       [ -n "$vlan" ] && ifname=${ifname}.${vlan}
+       # force bridge for multi-interface devices (and lan)
+       case "$1:$ifname" in
+               *\ * | lan:*) type="bridge" ;;
+       esac
 
        uci -q batch <<-EOF
                delete network.$1
                set network.$1='interface'
+               set network.$1.type='$type'
                set network.$1.ifname='$ifname'
                set network.$1.proto='none'
                set network.$1.macaddr='$macaddr'
@@ -56,198 +48,82 @@ generate_network() {
        case "$1" in
                lan)
                        uci -q batch <<-EOF
-                               set network.$1.type='bridge'
                                set network.$1.proto='static'
                                set network.$1.ipaddr='192.168.1.1'
                                set network.$1.netmask='255.255.255.0'
                                set network.$1.ip6assign='60'
                        EOF
                ;;
-
                wan)
                        uci -q batch <<-EOF
                                set network.$1.proto='dhcp'
                                delete network.wan6
                                set network.wan6='interface'
+                               set network.wan6.type='$type'
                                set network.wan6.ifname='$ifname'
                                set network.wan6.proto='dhcpv6'
                        EOF
                ;;
-
-               *)
-                       uci -q batch <<-EOF
-                               set network.$1.force_link=1
-                       EOF
-               ;;
        esac
 }
 
-generate_switch_vlan() {
-       local device="$1"
-       local vlan="$2"
-       local cpu_port="$3"
+generate_switch_vlans_ports() {
+       local switch="$1"
+       local port ports role roles num attr val
 
-       case "$vlan" in
-               lan) vlan=1;;
-               wan) vlan=2;;
-               *) vlan="${vlan##vlan}";;
-       esac
+       #
+       # autogenerate vlans
+       #
+
+       json_get_keys roles roles
+       json_select roles
+
+       for role in $roles; do
+               json_select "$role"
+                       json_get_vars ports
+               json_select ..
+
+               uci -q batch <<-EOF
+                       add network switch_vlan
+                       set network.@switch_vlan[-1].device='$switch'
+                       set network.@switch_vlan[-1].vlan='$role'
+                       set network.@switch_vlan[-1].ports='$ports'
+               EOF
+       done
 
-       json_select vlans
-       json_select "$2"
-       json_get_values ports
-       json_select ..
        json_select ..
 
-       uci -q batch <<-EOF
-               add network switch_vlan
-               set network.@switch_vlan[-1].device='$device'
-               set network.@switch_vlan[-1].vlan='$vlan'
-               set network.@switch_vlan[-1].ports='$ports ${cpu_port}t'
-       EOF
-}
 
-calculate_switch_vlans() {
-       local switch="$1"
-       local ports port attr val prev_role
-       local num device role index need_tag
-       local cpu0 cpu1 cpu2 cpu3
-       local dev0 dev1 dev2 dev3
-       local tag0 tag1 tag2 tag3
-       local role0 role1 role2 role3
-       local n_cpu=0  n_vlan=0 vlan_off=-1
-       local vlan_ports cpu_port
+       #
+       # write port specific settings
+       #
 
        json_get_keys ports ports
-
        json_select ports
 
-       # gather all cpu ports and count vlans
        for port in $ports; do
                json_select "$port"
-               json_get_vars num device role need_tag
-
-               if json_is_a attr object; then
-                       json_get_keys attr attr
-                       json_select attr
-
-                       uci -q batch <<-EOF
-                               add network switch_port
-                               set network.@switch_port[-1].device='$switch'
-                               set network.@switch_port[-1].port=$num
-                       EOF
-
-                       for attr in $attr; do
-                               json_get_var val "$attr"
-                               uci -q set network.@switch_port[-1].$attr="$val"
-                       done
-
-                       json_select ..
-               fi
-
-               json_select ..
-
-               if [ -n "$num" ] && [ -n "$device" ]; then
-                       export "cpu$n_cpu=$num"
-                       export "dev$n_cpu=$device"
-                       export "tag$n_cpu=${need_tag:-0}"
-                       n_cpu=$((n_cpu + 1))
-               elif [ -n "$num" ] && [ -n "$role" ] && [ "$role" != "$prev_role" ]; then
-                       export "role$n_vlan=$role"
-                       n_vlan=$((n_vlan + 1))
-                       prev_role="$role"
-               fi
-       done
-
-       unset prev_role
-
-       # autogenerate vlans
-       for port in $ports ""; do
-               if [ -n "$port" ]; then
-                       json_select "$port"
-                       json_get_vars num device role
-                       json_select ..
-               else
-                       num="-"; role="-"
-               fi
-
-               if [ -n "$num" ] && [ -n "$role" ]; then
-                       if [ "$role" != "$prev_role" ]; then
-                               if [ -n "$vlan_ports" ]; then
-                                       let cpu_port="cpu$((vlan_off % n_cpu))"
-                                       let need_tag="tag$((vlan_off % n_cpu))"
-                                       [ $n_vlan -gt $n_cpu -o $need_tag -eq 1 ] && cpu_port="${cpu_port}t"
+                       json_get_vars num
 
+                       if json_is_a attr object; then
+                               json_get_keys attr attr
+                               json_select attr
                                        uci -q batch <<-EOF
-                                               add network switch_vlan
-                                               set network.@switch_vlan[-1].device='$switch'
-                                               set network.@switch_vlan[-1].vlan='$((vlan_off + 1))'
-                                               set network.@switch_vlan[-1].ports='$vlan_ports $cpu_port'
+                                               add network switch_port
+                                               set network.@switch_port[-1].device='$switch'
+                                               set network.@switch_port[-1].port=$num
                                        EOF
-                               fi
 
-                               vlan_off=$((vlan_off + 1))
-                               vlan_ports="$num"
-                               prev_role="$role"
-                       else
-                               vlan_ports="$vlan_ports $num"
+                                       for attr in $attr; do
+                                               json_get_var val "$attr"
+                                               uci -q set network.@switch_port[-1].$attr="$val"
+                                       done
+                               json_select ..
                        fi
-
-               fi
+               json_select ..
        done
 
        json_select ..
-
-       # autogenerate interfaces
-       vlan_off=0; while [ $vlan_off -lt $n_vlan ]; do
-               eval role="\$role$((vlan_off))"
-               eval device="\$dev$((vlan_off % n_cpu))"
-               let need_tag="tag$((vlan_off++ % n_cpu))"
-               [ $n_vlan -gt $n_cpu -o $need_tag -eq 1 ] && device="$device.$vlan_off"
-
-               # quirk: append ifnames for subsequent switches
-               case "$switch" in switch[1-9])
-                       local prev_devs="$(uci -q get "network.$role.ifname")"
-                       if echo "$prev_devs" | grep -wq "$device"; then
-                               device="$prev_devs"
-                       else
-                               device="$prev_devs $device"
-                       fi
-               ;; esac
-
-               uci -q batch <<-EOF
-                       set network.$role='interface'
-                       set network.$role.ifname='$device'
-               EOF
-
-               case $role in
-                       lan)
-                               uci -q batch <<-EOF
-                                       set network.lan.type='bridge'
-                                       set network.lan.proto='static'
-                                       set network.lan.ipaddr='192.168.1.1'
-                                       set network.lan.netmask='255.255.255.0'
-                                       set network.lan.ip6assign='60'
-                               EOF
-                       ;;
-
-                       wan)
-                               uci -q batch <<-EOF
-                                       set network.wan.proto='dhcp'
-                                       set network.wan6='interface'
-                                       set network.wan6.ifname='$device'
-                                       set network.wan6.proto='dhcpv6'
-                               EOF
-                       ;;
-
-                       *)
-                               uci -q batch <<-EOF
-                                       set network.$role.force_link='1'
-                                       set network.$role.proto='none'
-                               EOF
-                       ;;
-               esac
-       done
 }
 
 generate_switch() {
@@ -266,12 +142,7 @@ generate_switch() {
                set network.@switch[-1].blinkrate='$blinkrate'
        EOF
 
-       if [ -n "$cpu_port" ]; then
-               json_get_keys vlans vlans
-               for vlan in $vlans; do generate_switch_vlan $1 $vlan $cpu_port; done
-       elif json_is_a ports array; then
-               calculate_switch_vlans $1
-       fi
+       generate_switch_vlans_ports "$1"
 
        json_select ..
        json_select ..
index ae23d22a79eb76b946a4941ea08ccda7982f5cdc..4a7cca4df0f2721d0a6903bf632250c7c4603eca 100755 (executable)
@@ -2,6 +2,7 @@
 
 CFG=/etc/board.json
 
+. /lib/functions.sh
 . /usr/share/libubox/jshn.sh
 
 json_select_array() {
@@ -33,8 +34,7 @@ _ucidef_set_interface() {
        local iface="$2"
 
        json_select_object "$name"
-       json_add_string ifname "${iface%%.*}"
-       [ "$iface" = "${iface%%.*}" ] || json_add_boolean create_vlan 1
+       json_add_string ifname "$iface"
        json_select ..
 }
 
@@ -114,28 +114,123 @@ ucidef_add_switch_attr() {
        json_select ..
 }
 
+_ucidef_add_switch_port() {
+       # inherited: $num $device $need_tag $role $index $prev_role
+       # inherited: $n_cpu $n_ports $n_vlan $cpu0 $cpu1 $cpu2 $cpu3 $cpu4 $cpu5
+
+       n_ports=$((n_ports + 1))
+
+       json_select_array ports
+               json_add_object
+                       json_add_int num "$num"
+                       [ -n "$device"   ] && json_add_string  device   "$device"
+                       [ -n "$need_tag" ] && json_add_boolean need_tag "$need_tag"
+                       [ -n "$role"     ] && json_add_string  role     "$role"
+                       [ -n "$index"    ] && json_add_int     index    "$index"
+               json_close_object
+       json_select ..
+
+       # record pointer to cpu entry for lookup in _ucidef_finish_switch_roles()
+       [ -n "$device" ] && {
+               export "cpu$n_cpu=$n_ports"
+               n_cpu=$((n_cpu + 1))
+       }
+
+       # create/append object to role list
+       [ -n "$role" ] && {
+               json_select_array roles
+
+               if [ "$role" != "$prev_role" ]; then
+                       json_add_object
+                               json_add_string role "$role"
+                               json_add_string ports "$num"
+                       json_close_object
+
+                       prev_role="$role"
+                       n_vlan=$((n_vlan + 1))
+               else
+                       json_select_object "$n_vlan"
+                               json_get_var port ports
+                               json_add_string ports "$port $num"
+                       json_select ..
+               fi
+
+               json_select ..
+       }
+}
+
+_ucidef_finish_switch_roles() {
+       # inherited: $name $n_cpu $n_vlan $cpu0 $cpu1 $cpu2 $cpu3 $cpu4 $cpu5
+       local index role roles num device need_tag port ports
+
+       json_select switch
+               json_select "$name"
+                       json_get_keys roles roles
+               json_select ..
+       json_select ..
+
+       for index in $roles; do
+               eval "port=\$cpu$(((index - 1) % n_cpu))"
+
+               json_select switch
+                       json_select "$name"
+                               json_select ports
+                                       json_select "$port"
+                                               json_get_vars num device need_tag
+                                       json_select ..
+                               json_select ..
+
+                               if [ $n_vlan -gt $n_cpu -o ${need_tag:-0} -eq 1 ]; then
+                                       num="${num}t"
+                                       device="${device}.${index}"
+                               fi
+
+                               json_select roles
+                                       json_select "$index"
+                                               json_get_vars role ports
+                                               json_add_string ports "$ports $num"
+                                               json_add_string device "$device"
+                                       json_select ..
+                               json_select ..
+                       json_select ..
+               json_select ..
+
+               json_select_object network
+                       json_select_object "$role"
+                               # attach previous interfaces (for multi-switch devices)
+                               local prev_device; json_get_var prev_device ifname
+                               if ! list_contains prev_device "$device"; then
+                                       device="${prev_device:+$prev_device }$device"
+                               fi
+                               json_add_string ifname "$device"
+                       json_select ..
+               json_select ..
+       done
+}
+
 ucidef_add_switch_ports() {
        local name="$1"; shift
-       local port num role dev idx tag
+       local port num role device index need_tag prev_role
+       local cpu0 cpu1 cpu2 cpu3 cpu4 cpu5
+       local n_cpu=0 n_vlan=0 n_ports=0
 
        json_select_object switch
        json_select_object "$name"
-       json_select_array ports
 
        for port in "$@"; do
                case "$port" in
                        [0-9]*@*)
                                num="${port%%@*}"
-                               dev="${port##*@}"
-                               tag=0
+                               device="${port##*@}"
+                               need_tag=0
                                [ "${num%t}" != "$num" ] && {
                                        num="${num%t}"
-                                       tag=1
+                                       need_tag=1
                                }
                        ;;
                        [0-9]*:*:[0-9]*)
                                num="${port%%:*}"
-                               idx="${port##*:}"
+                               index="${port##*:}"
                                role="${port#[0-9]*:}"; role="${role%:*}"
                        ;;
                        [0-9]*:*)
@@ -144,22 +239,17 @@ ucidef_add_switch_ports() {
                        ;;
                esac
 
-               if [ -n "$num" ] && [ -n "$dev$role" ]; then
-                       json_add_object
-                       json_add_int num "$num"
-                       [ -n "$dev" ] && json_add_string device "$dev"
-                       [ -n "$tag" ] && json_add_boolean need_tag "$tag"
-                       [ -n "$role" ] && json_add_string role "$role"
-                       [ -n "$idx" ] && json_add_int index "$idx"
-                       json_close_object
+               if [ -n "$num" ] && [ -n "$device$role" ]; then
+                       _ucidef_add_switch_port
                fi
 
-               unset num dev role idx tag
+               unset num device role index need_tag
        done
 
        json_select ..
        json_select ..
-       json_select ..
+
+       _ucidef_finish_switch_roles
 }
 
 ucidef_add_switch_port_attr() {
@@ -198,38 +288,6 @@ ucidef_add_switch_port_attr() {
        json_select ..
 }
 
-ucidef_add_switch_vlan() {
-       local name="$1"
-       local vlan="$2"
-       local ports="$3"
-       local cpu_port=''
-
-       case "$vlan" in
-       1)      vlan=lan;;
-       2)      vlan=wan;;
-       *)      vlan=vlan$vlan;;
-       esac
-
-       json_select_object switch
-       json_select_object "$name"
-       json_select_object vlans
-
-       json_add_array "$vlan"
-       for p in $ports; do
-               if [ ${p%t} != $p ]; then
-                       cpu_port=$p
-               else
-                       json_add_int "" $p
-               fi
-       done
-       json_close_array
-
-       json_select ..
-       [ -n "$cpu_port" ] && json_add_int cpu_port "$cpu_port"
-       json_select ..
-       json_select ..
-}
-
 ucidef_set_interface_macaddr() {
        local network="$1"
        local macaddr="$2"