diff --git a/package/base-files/files/bin/config_generate b/package/base-files/files/bin/config_generate index 1aa6d43e3f..7e0e2acd3b 100755 --- a/package/base-files/files/bin/config_generate +++ b/package/base-files/files/bin/config_generate @@ -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" - - case "$vlan" in - lan) vlan=1;; - wan) vlan=2;; - *) vlan="${vlan##vlan}";; - esac - - 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() { +generate_switch_vlans_ports() { 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 + local port ports role roles num attr val - json_get_keys ports ports + # + # autogenerate vlans + # - 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_get_keys roles roles + json_select roles + for role in $roles; do + json_select "$role" + json_get_vars ports 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" - - 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' - EOF - fi - - vlan_off=$((vlan_off + 1)) - vlan_ports="$num" - prev_role="$role" - else - vlan_ports="$vlan_ports $num" - fi - - fi + 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 .. - # 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" + # + # write port specific settings + # + + json_get_keys ports ports + json_select ports + + for port in $ports; do + json_select "$port" + 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_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 - ;; 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 + json_select .. done + + json_select .. } 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 .. diff --git a/package/base-files/files/lib/functions/uci-defaults-new.sh b/package/base-files/files/lib/functions/uci-defaults-new.sh index ae23d22a79..4a7cca4df0 100755 --- a/package/base-files/files/lib/functions/uci-defaults-new.sh +++ b/package/base-files/files/lib/functions/uci-defaults-new.sh @@ -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"