b.liu | e958203 | 2025-04-17 19:18:16 +0800 | [diff] [blame^] | 1 | #!/bin/sh |
| 2 | |
| 3 | CFG=/etc/board.json |
| 4 | |
| 5 | . /usr/share/libubox/jshn.sh |
| 6 | |
| 7 | [ -s $CFG ] || /bin/board_detect || exit 1 |
| 8 | [ -s /etc/config/network -a -s /etc/config/system ] && exit 0 |
| 9 | |
| 10 | generate_bridge() { |
| 11 | local name=$1 |
| 12 | local macaddr=$2 |
| 13 | uci -q batch <<-EOF |
| 14 | set network.$name=device |
| 15 | set network.$name.name=$name |
| 16 | set network.$name.type=bridge |
| 17 | EOF |
| 18 | if [ -n "$macaddr" ]; then |
| 19 | uci -q batch <<-EOF |
| 20 | set network.$name.macaddr=$macaddr |
| 21 | EOF |
| 22 | fi |
| 23 | } |
| 24 | |
| 25 | bridge_vlan_id=0 |
| 26 | generate_bridge_vlan() { |
| 27 | local name=$1_vlan |
| 28 | local device=$2 |
| 29 | local ports="$3" |
| 30 | local vlan="$4" |
| 31 | uci -q batch <<-EOF |
| 32 | set network.$name=bridge-vlan |
| 33 | set network.$name.device='$device' |
| 34 | set network.$name.vlan='$vlan' |
| 35 | set network.$name.ports='$ports' |
| 36 | EOF |
| 37 | } |
| 38 | |
| 39 | generate_static_network() { |
| 40 | uci -q batch <<-EOF |
| 41 | delete network.loopback |
| 42 | set network.loopback='interface' |
| 43 | set network.loopback.device='lo' |
| 44 | set network.loopback.proto='static' |
| 45 | set network.loopback.ipaddr='127.0.0.1' |
| 46 | set network.loopback.netmask='255.0.0.0' |
| 47 | EOF |
| 48 | [ -e /proc/sys/net/ipv6 ] && { |
| 49 | uci -q batch <<-EOF |
| 50 | delete network.globals |
| 51 | set network.globals='globals' |
| 52 | set network.globals.ula_prefix='auto' |
| 53 | EOF |
| 54 | } |
| 55 | |
| 56 | if json_is_a dsl object; then |
| 57 | json_select dsl |
| 58 | if json_is_a atmbridge object; then |
| 59 | json_select atmbridge |
| 60 | local vpi vci encaps payload nameprefix |
| 61 | json_get_vars vpi vci encaps payload nameprefix |
| 62 | uci -q batch <<-EOF |
| 63 | delete network.atm |
| 64 | set network.atm='atm-bridge' |
| 65 | set network.atm.vpi='$vpi' |
| 66 | set network.atm.vci='$vci' |
| 67 | set network.atm.encaps='$encaps' |
| 68 | set network.atm.payload='$payload' |
| 69 | set network.atm.nameprefix='$nameprefix' |
| 70 | EOF |
| 71 | json_select .. |
| 72 | fi |
| 73 | |
| 74 | if json_is_a modem object; then |
| 75 | json_select modem |
| 76 | local type annex firmware tone xfer_mode |
| 77 | json_get_vars type annex firmware tone xfer_mode |
| 78 | uci -q batch <<-EOF |
| 79 | delete network.dsl |
| 80 | set network.dsl='dsl' |
| 81 | set network.dsl.annex='$annex' |
| 82 | set network.dsl.firmware='$firmware' |
| 83 | set network.dsl.tone='$tone' |
| 84 | set network.dsl.xfer_mode='$xfer_mode' |
| 85 | EOF |
| 86 | json_select .. |
| 87 | fi |
| 88 | json_select .. |
| 89 | fi |
| 90 | } |
| 91 | |
| 92 | addr_offset=2 |
| 93 | generate_network() { |
| 94 | local ports device macaddr protocol type ipaddr netmask vlan |
| 95 | local bridge=$2 |
| 96 | |
| 97 | json_select network |
| 98 | json_select "$1" |
| 99 | json_get_vars device macaddr metric protocol ipaddr netmask vlan |
| 100 | json_get_values ports ports |
| 101 | json_select .. |
| 102 | json_select .. |
| 103 | |
| 104 | [ -n "$device" -o -n "$ports" ] || return |
| 105 | |
| 106 | # Force bridge for "lan" as it may have other devices (e.g. wireless) |
| 107 | # bridged |
| 108 | [ "$1" = "lan" -a -z "$ports" ] && { |
| 109 | ports="$device" |
| 110 | } |
| 111 | |
| 112 | [ -n "$ports" -a -z "$bridge" ] && { |
| 113 | uci -q batch <<-EOF |
| 114 | add network device |
| 115 | set network.@device[-1].name='br-$1' |
| 116 | set network.@device[-1].type='bridge' |
| 117 | EOF |
| 118 | for port in $ports; do uci add_list network.@device[-1].ports="$port"; done |
| 119 | [ -n "$macaddr" ] && { |
| 120 | for port in $ports; do |
| 121 | uci -q batch <<-EOF |
| 122 | add network device |
| 123 | set network.@device[-1].name='$port' |
| 124 | set network.@device[-1].macaddr='$macaddr' |
| 125 | EOF |
| 126 | done |
| 127 | } |
| 128 | device=br-$1 |
| 129 | type= |
| 130 | macaddr="" |
| 131 | } |
| 132 | |
| 133 | [ -n "$bridge" ] && { |
| 134 | [ -z "$ports" ] && ports="$device" |
| 135 | if [ -z "$vlan" ]; then |
| 136 | bridge_vlan_id=$((bridge_vlan_id + 1)) |
| 137 | vlan=$bridge_vlan_id |
| 138 | fi |
| 139 | generate_bridge_vlan $1 $bridge "$ports" $vlan |
| 140 | device=$bridge.$vlan |
| 141 | type="" |
| 142 | } |
| 143 | |
| 144 | if [ -n "$macaddr" ]; then |
| 145 | uci -q batch <<-EOF |
| 146 | add network device |
| 147 | set network.@device[-1].name='$device' |
| 148 | set network.@device[-1].macaddr='$macaddr' |
| 149 | EOF |
| 150 | fi |
| 151 | |
| 152 | uci -q batch <<-EOF |
| 153 | delete network.$1 |
| 154 | set network.$1='interface' |
| 155 | set network.$1.type='$type' |
| 156 | set network.$1.device='$device' |
| 157 | set network.$1.metric='$metric' |
| 158 | set network.$1.proto='none' |
| 159 | EOF |
| 160 | |
| 161 | case "$protocol" in |
| 162 | static) |
| 163 | local ipad |
| 164 | case "$1" in |
| 165 | lan) ipad=${ipaddr:-"192.168.1.1"} ;; |
| 166 | *) ipad=${ipaddr:-"192.168.$((addr_offset++)).1"} ;; |
| 167 | esac |
| 168 | |
| 169 | netm=${netmask:-"255.255.255.0"} |
| 170 | |
| 171 | uci -q batch <<-EOF |
| 172 | set network.$1.proto='static' |
| 173 | set network.$1.ipaddr='$ipad' |
| 174 | set network.$1.netmask='$netm' |
| 175 | EOF |
| 176 | [ -e /proc/sys/net/ipv6 ] && uci set network.$1.ip6assign='60' |
| 177 | ;; |
| 178 | |
| 179 | dhcp) |
| 180 | # fixup IPv6 slave interface if parent is a bridge |
| 181 | [ "$type" = "bridge" ] && device="br-$1" |
| 182 | |
| 183 | uci set network.$1.proto='dhcp' |
| 184 | [ -e /proc/sys/net/ipv6 ] && { |
| 185 | uci -q batch <<-EOF |
| 186 | delete network.${1}6 |
| 187 | set network.${1}6='interface' |
| 188 | set network.${1}6.device='$device' |
| 189 | set network.${1}6.proto='dhcpv6' |
| 190 | EOF |
| 191 | } |
| 192 | ;; |
| 193 | |
| 194 | pppoe) |
| 195 | uci -q batch <<-EOF |
| 196 | set network.$1.proto='pppoe' |
| 197 | set network.$1.username='username' |
| 198 | set network.$1.password='password' |
| 199 | EOF |
| 200 | [ -e /proc/sys/net/ipv6 ] && { |
| 201 | uci -q batch <<-EOF |
| 202 | set network.$1.ipv6='1' |
| 203 | delete network.${1}6 |
| 204 | set network.${1}6='interface' |
| 205 | set network.${1}6.device='@${1}' |
| 206 | set network.${1}6.proto='dhcpv6' |
| 207 | EOF |
| 208 | } |
| 209 | ;; |
| 210 | |
| 211 | ncm|\ |
| 212 | qmi|\ |
| 213 | mbim) |
| 214 | uci -q batch <<-EOF |
| 215 | set network.$1.proto='${protocol}' |
| 216 | set network.$1.pdptype='ipv4' |
| 217 | EOF |
| 218 | ;; |
| 219 | esac |
| 220 | } |
| 221 | |
| 222 | generate_switch_vlans_ports() { |
| 223 | local switch="$1" |
| 224 | local port ports role roles num attr val |
| 225 | |
| 226 | # |
| 227 | # autogenerate vlans |
| 228 | # |
| 229 | |
| 230 | if json_is_a roles array; then |
| 231 | json_get_keys roles roles |
| 232 | json_select roles |
| 233 | |
| 234 | for role in $roles; do |
| 235 | json_select "$role" |
| 236 | json_get_vars ports |
| 237 | json_select .. |
| 238 | |
| 239 | uci -q batch <<-EOF |
| 240 | add network switch_vlan |
| 241 | set network.@switch_vlan[-1].device='$switch' |
| 242 | set network.@switch_vlan[-1].vlan='$role' |
| 243 | set network.@switch_vlan[-1].ports='$ports' |
| 244 | EOF |
| 245 | done |
| 246 | |
| 247 | json_select .. |
| 248 | fi |
| 249 | |
| 250 | |
| 251 | # |
| 252 | # write port specific settings |
| 253 | # |
| 254 | |
| 255 | if json_is_a ports array; then |
| 256 | json_get_keys ports ports |
| 257 | json_select ports |
| 258 | |
| 259 | for port in $ports; do |
| 260 | json_select "$port" |
| 261 | json_get_vars num |
| 262 | |
| 263 | if json_is_a attr object; then |
| 264 | json_get_keys attr attr |
| 265 | json_select attr |
| 266 | uci -q batch <<-EOF |
| 267 | add network switch_port |
| 268 | set network.@switch_port[-1].device='$switch' |
| 269 | set network.@switch_port[-1].port=$num |
| 270 | EOF |
| 271 | |
| 272 | for attr in $attr; do |
| 273 | json_get_var val "$attr" |
| 274 | uci -q set network.@switch_port[-1].$attr="$val" |
| 275 | done |
| 276 | json_select .. |
| 277 | fi |
| 278 | json_select .. |
| 279 | done |
| 280 | |
| 281 | json_select .. |
| 282 | fi |
| 283 | } |
| 284 | |
| 285 | generate_switch() { |
| 286 | local key="$1" |
| 287 | local vlans |
| 288 | |
| 289 | json_select switch |
| 290 | json_select "$key" |
| 291 | json_get_vars enable reset blinkrate cpu_port \ |
| 292 | ar8xxx_mib_type ar8xxx_mib_poll_interval |
| 293 | |
| 294 | uci -q batch <<-EOF |
| 295 | add network switch |
| 296 | set network.@switch[-1].name='$key' |
| 297 | set network.@switch[-1].reset='$reset' |
| 298 | set network.@switch[-1].enable_vlan='$enable' |
| 299 | set network.@switch[-1].blinkrate='$blinkrate' |
| 300 | set network.@switch[-1].ar8xxx_mib_type='$ar8xxx_mib_type' |
| 301 | set network.@switch[-1].ar8xxx_mib_poll_interval='$ar8xxx_mib_poll_interval' |
| 302 | EOF |
| 303 | |
| 304 | generate_switch_vlans_ports "$1" |
| 305 | |
| 306 | json_select .. |
| 307 | json_select .. |
| 308 | } |
| 309 | |
| 310 | generate_static_system() { |
| 311 | uci -q batch <<-EOF |
| 312 | delete system.@system[0] |
| 313 | add system system |
| 314 | set system.@system[-1].hostname='OpenWrt' |
| 315 | set system.@system[-1].timezone='CST-8' |
| 316 | set system.@system[-1].zonename='Asia/Shanghai' |
| 317 | set system.@system[-1].ttylogin='0' |
| 318 | set system.@system[-1].log_size='64' |
| 319 | set system.@system[-1].urandom_seed='0' |
| 320 | |
| 321 | delete system.ntp |
| 322 | set system.ntp='timeserver' |
| 323 | set system.ntp.enabled='1' |
| 324 | set system.ntp.enable_server='0' |
| 325 | add_list system.ntp.server='0.openwrt.pool.ntp.org' |
| 326 | add_list system.ntp.server='1.openwrt.pool.ntp.org' |
| 327 | add_list system.ntp.server='2.openwrt.pool.ntp.org' |
| 328 | add_list system.ntp.server='3.openwrt.pool.ntp.org' |
| 329 | EOF |
| 330 | |
| 331 | if json_is_a system object; then |
| 332 | json_select system |
| 333 | local hostname |
| 334 | if json_get_var hostname hostname; then |
| 335 | uci -q set "system.@system[-1].hostname=$hostname" |
| 336 | fi |
| 337 | |
| 338 | local compat_version |
| 339 | if json_get_var compat_version compat_version; then |
| 340 | uci -q set "system.@system[-1].compat_version=$compat_version" |
| 341 | else |
| 342 | uci -q set "system.@system[-1].compat_version=1.0" |
| 343 | fi |
| 344 | |
| 345 | local timezone |
| 346 | if json_get_var timezone timezone; then |
| 347 | uci -q set "system.@system[-1].timezone=$timezone" |
| 348 | fi |
| 349 | |
| 350 | if json_is_a ntpserver array; then |
| 351 | local keys key |
| 352 | json_get_keys keys ntpserver |
| 353 | json_select ntpserver |
| 354 | uci -q delete "system.ntp.server" |
| 355 | |
| 356 | for key in $keys; do |
| 357 | local server |
| 358 | if json_get_var server "$key"; then |
| 359 | uci -q add_list "system.ntp.server=$server" |
| 360 | fi |
| 361 | done |
| 362 | json_select .. |
| 363 | fi |
| 364 | json_select .. |
| 365 | fi |
| 366 | } |
| 367 | |
| 368 | generate_rssimon() { |
| 369 | local key="$1" |
| 370 | local cfg="rssid_$key" |
| 371 | local refresh threshold |
| 372 | |
| 373 | json_select rssimon |
| 374 | json_select "$key" |
| 375 | json_get_vars refresh threshold |
| 376 | json_select .. |
| 377 | json_select .. |
| 378 | |
| 379 | uci -q batch <<-EOF |
| 380 | delete system.$cfg |
| 381 | set system.$cfg='rssid' |
| 382 | set system.$cfg.dev='$key' |
| 383 | set system.$cfg.refresh='$refresh' |
| 384 | set system.$cfg.threshold='$threshold' |
| 385 | EOF |
| 386 | } |
| 387 | |
| 388 | generate_led() { |
| 389 | local key="$1" |
| 390 | local cfg="led_$key" |
| 391 | |
| 392 | json_select led |
| 393 | json_select "$key" |
| 394 | json_get_vars name sysfs type trigger default |
| 395 | |
| 396 | uci -q batch <<-EOF |
| 397 | delete system.$cfg |
| 398 | set system.$cfg='led' |
| 399 | set system.$cfg.name='$name' |
| 400 | set system.$cfg.sysfs='$sysfs' |
| 401 | set system.$cfg.trigger='$trigger' |
| 402 | set system.$cfg.default='$default' |
| 403 | EOF |
| 404 | |
| 405 | case "$type" in |
| 406 | gpio) |
| 407 | local gpio inverted |
| 408 | json_get_vars gpio inverted |
| 409 | uci -q batch <<-EOF |
| 410 | set system.$cfg.trigger='gpio' |
| 411 | set system.$cfg.gpio='$gpio' |
| 412 | set system.$cfg.inverted='$inverted' |
| 413 | EOF |
| 414 | ;; |
| 415 | |
| 416 | netdev) |
| 417 | local device mode |
| 418 | json_get_vars device mode |
| 419 | uci -q batch <<-EOF |
| 420 | set system.$cfg.trigger='netdev' |
| 421 | set system.$cfg.mode='$mode' |
| 422 | set system.$cfg.dev='$device' |
| 423 | EOF |
| 424 | ;; |
| 425 | |
| 426 | usb) |
| 427 | local device |
| 428 | json_get_vars device |
| 429 | uci -q batch <<-EOF |
| 430 | set system.$cfg.trigger='usbdev' |
| 431 | set system.$cfg.interval='50' |
| 432 | set system.$cfg.dev='$device' |
| 433 | EOF |
| 434 | ;; |
| 435 | |
| 436 | usbport) |
| 437 | local ports port |
| 438 | json_get_values ports ports |
| 439 | uci set system.$cfg.trigger='usbport' |
| 440 | for port in $ports; do |
| 441 | uci add_list system.$cfg.port=$port |
| 442 | done |
| 443 | ;; |
| 444 | |
| 445 | rssi) |
| 446 | local iface minq maxq offset factor |
| 447 | json_get_vars iface minq maxq offset factor |
| 448 | uci -q batch <<-EOF |
| 449 | set system.$cfg.trigger='rssi' |
| 450 | set system.$cfg.iface='rssid_$iface' |
| 451 | set system.$cfg.minq='$minq' |
| 452 | set system.$cfg.maxq='$maxq' |
| 453 | set system.$cfg.offset='$offset' |
| 454 | set system.$cfg.factor='$factor' |
| 455 | EOF |
| 456 | ;; |
| 457 | |
| 458 | switch) |
| 459 | local port_mask speed_mask mode |
| 460 | json_get_vars port_mask speed_mask mode |
| 461 | uci -q batch <<-EOF |
| 462 | set system.$cfg.port_mask='$port_mask' |
| 463 | set system.$cfg.speed_mask='$speed_mask' |
| 464 | set system.$cfg.mode='$mode' |
| 465 | EOF |
| 466 | ;; |
| 467 | |
| 468 | portstate) |
| 469 | local port_state |
| 470 | json_get_vars port_state |
| 471 | uci -q batch <<-EOF |
| 472 | set system.$cfg.port_state='$port_state' |
| 473 | EOF |
| 474 | ;; |
| 475 | |
| 476 | timer|oneshot) |
| 477 | local delayon delayoff |
| 478 | json_get_vars delayon delayoff |
| 479 | uci -q batch <<-EOF |
| 480 | set system.$cfg.trigger='$type' |
| 481 | set system.$cfg.delayon='$delayon' |
| 482 | set system.$cfg.delayoff='$delayoff' |
| 483 | EOF |
| 484 | ;; |
| 485 | esac |
| 486 | |
| 487 | json_select .. |
| 488 | json_select .. |
| 489 | } |
| 490 | |
| 491 | generate_gpioswitch() { |
| 492 | local cfg="$1" |
| 493 | |
| 494 | json_select gpioswitch |
| 495 | json_select "$cfg" |
| 496 | local name pin default |
| 497 | json_get_vars name pin default |
| 498 | uci -q batch <<-EOF |
| 499 | delete system.$cfg |
| 500 | set system.$cfg='gpio_switch' |
| 501 | set system.$cfg.name='$name' |
| 502 | set system.$cfg.gpio_pin='$pin' |
| 503 | set system.$cfg.value='$default' |
| 504 | EOF |
| 505 | json_select .. |
| 506 | json_select .. |
| 507 | } |
| 508 | |
| 509 | json_init |
| 510 | json_load "$(cat ${CFG})" |
| 511 | |
| 512 | umask 077 |
| 513 | |
| 514 | if [ ! -s /etc/config/network ]; then |
| 515 | bridge_name="" |
| 516 | touch /etc/config/network |
| 517 | generate_static_network |
| 518 | |
| 519 | json_get_vars bridge |
| 520 | [ -n "$bridge" ] && { |
| 521 | json_select bridge |
| 522 | json_get_vars name macaddr |
| 523 | generate_bridge "$name" "$macaddr" |
| 524 | json_select .. |
| 525 | bridge_name=$name |
| 526 | } |
| 527 | |
| 528 | json_get_keys keys network |
| 529 | for key in $keys; do generate_network $key $bridge_name; done |
| 530 | |
| 531 | json_get_keys keys switch |
| 532 | for key in $keys; do generate_switch $key; done |
| 533 | fi |
| 534 | |
| 535 | if [ ! -s /etc/config/system ]; then |
| 536 | touch /etc/config/system |
| 537 | generate_static_system |
| 538 | |
| 539 | json_get_keys keys rssimon |
| 540 | for key in $keys; do generate_rssimon $key; done |
| 541 | |
| 542 | json_get_keys keys gpioswitch |
| 543 | for key in $keys; do generate_gpioswitch $key; done |
| 544 | |
| 545 | json_get_keys keys led |
| 546 | for key in $keys; do generate_led $key; done |
| 547 | fi |
| 548 | uci commit |