Ticket #1229: config.sh

File config.sh, 18.5 KB (added by matthijs, 6 years ago)

Fix for this bug

Line 
1#!/bin/sh
2
3# This script contains all kinds of fon-specific configuration stuff. In
4# particular, it translates the fon-specific network configuration stuff
5# in /etc/config/fon (written by luci) to OpenWRT network configuration
6# files in /etc/config/network and /etc/config/wireless (which are again
7# processed by ifup, ifdown, /lib/network, /sbin/wifi and /lib/wifi).
8
9. /lib/config/uci.sh
10. /etc/functions.sh
11
12# First, set some device-dependent variables, such as interface names.
13# This minimizes the device-dependent code below (though not completely
14# removes it).
15
16fon_device=$(cat /etc/fon_device)
17case "$fon_device" in
18        fonera20n)
19                lan_ifname="eth0.1"
20                wan_ifname="eth0.2"
21                wifi_device="rt3052"
22                wifi_ifname="ra1"
23                private_wifi_ifname="ra0"
24                wan_wifi_ifname="apcli0"
25                # This variable is used by /etc/init.d/mgmtnetwork
26                mgmt_ifname="br-lan"
27                # TODO: Seems this one is used by
28                # /etc/init.d/chillispot, but it uses a hardcoded ifname
29                # for 2.0g. This MAC address should probably be loaded
30                # into a uci variable by config_fon or something, so
31                # everything (chilli, fonsmcd, registration url, etc.
32                # can use it).
33                wifi_ifname_mac="ra1"
34        ;;
35        fonera20)
36                lan_ifname="eth0.0"
37                wan_ifname="eth0.1"
38                wifi_device="wifi0"
39                wifi_ifname="ath0"
40                private_wifi_ifname="ath1"
41                wan_wifi_ifname="ath2"
42                # This variable is used by /etc/init.d/mgmtnetwork
43                mgmt_ifname="br-lan"
44        ;;
45        *)
46                mgmt_ifname="eth0"
47                wan_ifname="eth0"
48        ;;
49esac
50
51get_default_psk() {
52        # Load the default WPA psk from the boardconfig mtd partition
53        case "$fon_device" in
54                fonera20n)
55                        dd if=$(find_mtd_part boardconfig) bs=$((0x1026)) skip=1 count=1 2>/dev/null | head -c10
56                        ;;
57                fonera20)
58                        dd if=$(find_mtd_part boardconfig) bs=$((0x88)) skip=1 count=1 2>/dev/null | head -c10
59                        ;;
60        esac
61}
62
63load_config() {
64        # FON's config network sections have the same name as
65        # the interface groups, so their options will be used
66        local OLD_SECTIONS="$CONFIG_SECTIONS"
67        NO_CALLBACK=1
68        . /etc/config/fon
69        unset NO_CALLBACK
70        CONFIG_SECTIONS="$OLD_SECTIONS"
71}
72
73config_firewall() {
74        local M
75        . /etc/config/firewall
76        uci_remove "firewall" "hotspot_lan"
77        uci_remove "firewall" "lan" "masq"
78        M=`uci get fon.wan.mode`
79        [ "$M" = "bridge" -o "$M" = "wifi-bridge" ] && {
80                uci_set "firewall" "lan" "masq" "1"
81                uci_add "firewall" "forwarding" "hotspot_lan"
82                uci_set "firewall" "hotspot_lan" "src" "hotspot"
83                uci_set "firewall" "hotspot_lan" "dest" "lan"
84        }
85}
86
87# Configure the hardware switch, if needed. This is separate from
88# config_network below, since it must be run at boot after the ethernet
89# driver was loaded, while config_network is run before.
90config_switch() {
91        local wanmode wan_as_lan
92        config_get wanmode wan mode
93        # This settings determines if the wan port should be used as a
94        # lan port, or remain unused (in wifi mode).
95        config_get wan_as_lan wan wan_as_lan
96
97        case "$fon_device" in
98                fonera20n)
99                        if [ "$wanmode" = "bridge" -o \( "$wanmode" = "wifi" -a "$wan_as_lan" = "1" \) -o "$wanmode" = "wifi-bridge" ]; then
100                                # Configure the hardware switch to move
101                                # port 4 (the WAN port) to VLAN 1 (the
102                                # LAN vlan)
103                                switch vlan set 0 1 1111111
104                                switch vlan set 1 2 0000011
105                                switch reg w 48 1001
106                        else
107                                # Configure the hardware switch to move
108                                # port 4 (the WAN port) to VLAN 2 (the
109                                # WAN vlan)
110                                switch vlan set 0 1 1111011
111                                switch vlan set 1 2 0000111
112                                switch reg w 48 1002
113                        fi
114                        ;;
115
116                *)
117                        # There is no hardware switch in other devices
118                        ;;
119        esac
120}
121
122config_network() {
123        local wanmode lanip lanmask langateway landns wanmacaddr mtu
124        local wifiproto wanproto hostname mac wanip wanmask wangateway
125        local wandns wanusername wanpassword wanpptp_server wan_as_lan
126
127        config_get wanmode wan mode
128
129        ###################################
130        # Setup the loopback network
131        ###################################
132        uci_remove "network" "loopback" 2> /dev/null
133        uci_add "network" "interface" "loopback"
134        uci_set "network" "loopback" "proto" "static"
135        uci_set "network" "loopback" "ifname" "lo"
136        uci_set "network" "loopback" "ipaddr" "127.0.0.1"
137        uci_set "network" "loopback" "netmask" "255.255.255.0"
138
139        ###################################
140        # Setup bridging
141        ###################################
142
143        # By default, add only the lan port(s) to the lan bridge (the
144        # wifi interface will be added later when it is brought up,
145        # since it references the "lan" network in /etc/config/wireless)
146        lan_devs="$lan_ifname"
147
148        # In bridge mode and wifi mode, we turn the WAN port
149        # into a LAN port. In bridge and wifi-bridge mode, there is
150        # additional setup below to disable the wan network alltogether
151
152        case "$fon_device" in
153                fonera20n)
154                        # Set up the hardware switch
155                        config_switch
156                        ;;
157                *)
158                        # This settings determines if the wan port should be used as a
159                        # lan port, or remain unused (in wifi mode).
160                        config_get wan_as_lan wan wan_as_lan
161
162                        if [ "$wanmode" = "bridge" -o \( "$wanmode" = "wifi" -a "$wan_as_lan" = "1" \) -o "$wanmode" = "wifi-bridge" ]; then
163                                # Add the wan device to the lan bridge
164                                # so we have software bridging.
165                                lan_devs="$lan_devs $wan_ifname"
166                        fi
167                        ;;
168        esac
169
170        ###################################
171        # Setup the lan network
172        ###################################
173        uci_remove "network" "lan" 2> /dev/null
174
175        # The lan network is always a bridge with a static address
176        uci_add "network" "interface" "lan"
177        uci_set "network" "lan" "type" "bridge"
178        uci_set "network" "lan" "proto" "static"
179
180        if [ "$wanmode" == "bridge" -o "$wanmode" == "wifi-bridge" ]; then
181                # In bridge mode, use the static address from the WAN
182                # configuration for the LAN interface.
183                config_get lanip wan ipaddr
184                config_get lanmask wan netmask
185                config_get langateway wan gateway
186                config_get landns wan dns
187        else
188                # In all other cases, just use the ip addr / netmask from
189                # the LAN configuration.
190                config_get lanip lan ipaddr
191                config_get lanmask lan netmask
192        fi
193
194        uci_set "network" "lan" "ifname" "$lan_devs"
195        uci_set "network" "lan" "ipaddr" "${lanip:-192.168.0.250}"
196        uci_set "network" "lan" "netmask" "${lanmask:-255.255.255.0}"
197        [ -n "$langateway" ] && uci_set "network" "lan" "gateway" "$langateway"
198        [ -n  "$landns" ] && uci_set "network" "lan" "dns" "$landns"
199
200        ###################################
201        # Setup the wan network
202        ###################################
203        uci_remove "network" "wan" 2> /dev/null
204
205        uci_add "network" "interface" "wan"
206
207        # Set the wan ifname
208        case "$wanmode" in
209                wifi)
210                        uci_set "network" "wan" "ifname" "$wan_wifi_ifname"
211                        # Note that we don't set the wan_wifi_ifname in
212                        # the wan network in wifi-bridge mode, since
213                        # ap_client always runs ifup wan, which would
214                        # destroy the bridge config created by the wifi
215                        # scripts...
216                        ;;
217                umts)
218                        uci_set "network" "wan" "ifname" "ppp0"
219                        ;;
220                *)
221                        uci_set "network" "wan" "ifname" "$wan_ifname"
222
223                        # Allow overriding the WAN mac address for every mode that
224                        # actually uses the WAN ethernet interface
225                        config_get wanmacaddr wan macaddr
226                        [ -n "$wanmacaddr" ] && uci_set "network" "wan" "macaddr" "$wanmacaddr"
227                        ;;
228        esac
229
230        # Set the wan proto
231        case "$wanmode" in
232                wifi)
233                        # For wifi-wan mode, wmode (which can be
234                        # static or dhcp) determines how to
235                        # actually configure the interface.
236                        config_get wifiproto wan wmode
237                        wanproto="${wifiproto:-dhcp}"
238                        ;;
239                bridge | wifi-bridge)
240                        # For bridge mode, disable the wan network. Note
241                        # that we can't completely remove the network
242                        # (which would be more appropriate), since that
243                        # will prevent ConfigWan from deconfiguring the
244                        # old address, resulting in a broken network
245                        # when switching to bridge mode.
246                        wanproto="none"
247                        ;;
248                *)
249                        # For all others, just use the wanmode
250                        # as the wan proto
251                        wanproto="${wanmode:-dhcp}"
252                        ;;
253        esac
254        uci_set "network" "wan" "proto" "$wanproto"
255
256        # Set other relevant variables. Note that we switch on
257        # $wanproto now instead of wanmode, so we do the setup
258        # for the actually used proto instead of the configured
259        # mode (which will be different in wifi-wan mode, for
260        # example).
261        case "$wanproto" in
262                dhcp)
263                        # This hostname is used in DHCP requests
264                        hostname=`uci get system.@system[0].hostname`
265                        mac=`ifconfig $wan_ifname | grep HWaddr| sed "s/.*HWaddr //g" |sed "s/://g"`
266                        uci_set "network" "wan" "hostname" "${hostname}-${mac}"
267                        # Note that the dns_static option set by
268                        # luci is processed by
269                        # /usr/share/udhcpc/default.script
270                        # directly.
271                        ;;
272                static)
273                        config_get wanip wan ipaddr
274                        config_get wanmask wan netmask
275                        config_get wangateway wan gateway
276                        config_get wandns wan dns
277                        uci_set "network" "wan" "ipaddr" "$wanip"
278                        uci_set "network" "wan" "netmask" "${wanmask:-255.255.255.0}"
279                        uci_set "network" "wan" "gateway" "$wangateway"
280                        uci_set "network" "wan" "dns" "$wandns"
281                        ;;
282                pptp)
283                        # This section is a bit messy, because it seems to
284                        # be unused (there doesn't seem to actually be any
285                        # code to handle the pptp case in /lib/network)?
286                        config_get wanusername wan username
287                        config_get wanpassword wan password
288                        config_get wanpptp_server wan pptp_server
289                        uci_set "network" "wan" "username" "$wanusername"
290                        uci_set "network" "wan" "password" "$wanpassword"
291                        uci_set "network" "wan" "device" "eth0.2"
292                        uci_set "network" "wan" "ipproto" "dhcp"
293                        uci_set "network" "wan" "server" "$wanpptp_server"
294                        # TODO: mtu2 variable is set by luci but ignored
295                        # here?
296                        ;;
297                pppoe)
298                        config_get wanusername wan username
299                        config_get wanpassword wan password
300                        config_get wandns wan dns_static
301                        config_get mtu wan mtu
302                        uci_set "network" "wan" "username" "$wanusername"
303                        uci_set "network" "wan" "password" "$wanpassword"
304                        if [ -z "$wandns" -o "$wandns" = "0" ]; then
305                                uci_set "network" "wan" "peerdns" "1"
306                        else
307                                uci_set "network" "wan" "dns" "$wandns"
308                                uci_set "network" "wan" "peerdns" "0"
309                        fi
310                        uci_set "network" "wan" "mtu" "$mtu"
311                        ;;
312                wifi)
313                        ;;
314                umts)
315                        ;;
316                none)
317                        ;;
318        esac
319
320        # Don't bring up the wan interface automatically. This will
321        # be done by a switch hotplug script when a cable is plugged in,
322        # or when the ttyUSB umts device is ready, etc.
323        uci_set "network" "wan" "auto" "0"
324
325
326        ###################################
327        # Setup the hotspot network
328        ###################################
329
330        # This network is configured by chillispot
331        uci_remove "network" "hotspot" 2> /dev/null
332        uci_add "network" "interface" "hotspot"
333        uci_set "network" "hotspot" "ifname" "tun0"
334        uci_set "network" "hotspot" "proto" "none"
335
336        # This is a dummy network referred to by the "public" wifi-iface
337        # below in config_wireless
338        uci_remove "network" "hotspotwifi" 2> /dev/null
339        uci_add "network" "interface" "hotspotwifi"
340        uci_set "network" "hotspotwifi" "proto" "none"
341
342        uci commit network
343}
344
345config_wireless() {
346        local mode channel ht country diversity rtxant ssid encryption
347        local wpa_crypto enc pwd key mode auth crypt
348
349        ###################################
350        # Setup the wifi device
351        ###################################
352        config_get channel advanced channel
353        config_get mode advanced bgmode
354        uci_add "wireless" "wifi-device" "$wifi_device"
355        uci_set "wireless" "$wifi_device" "channel" "$channel"
356        case $fon_device in
357                fonera20n)
358                        config_get ht advanced ht
359                        config_get country advanced country
360                        # Lookup the regdomain for the country
361                        regdom=$(echo "for i, v in ipairs(loadfile('/etc/3166en.db.lua')()) do if v[1] == '$country' then print(v[3]) end end" | lua)
362                        uci_set "wireless" "$wifi_device" "type" "rt3052"
363                        uci_set "wireless" "$wifi_device" "ht" "${ht:-40}"
364                        uci_set "wireless" "$wifi_device" "country" "${country}"
365                        uci_set "wireless" "$wifi_device" "regdom" "${regdom:-0}"
366                        uci_set "wireless" "$wifi_device" "mode" "$mode"
367                        local wifi_switch=`cat /proc/gpio_switch`
368                        uci_set "wireless" "$wifi_device" "disabled" "${wifi_switch:-0}"
369                        ;;
370                fonera20)
371                        config_get diversity advanced diversity
372                        config_get rtxant advanced rtxant
373                        case "$mode" in
374                                B|b) mode=11b;;
375                                G|g) mode=11g;;
376                                *) mode=auto;;
377                        esac
378                        uci_set "wireless" "$wifi_device" "type" "atheros"
379                        uci_set "wireless" "$wifi_device" "mode" "$mode"
380                        uci_set "wireless" "$wifi_device" "diversity" "$diversity"
381                        uci_set "wireless" "$wifi_device" "rxantenna" "$rtxant"
382                        uci_set "wireless" "$wifi_device" "txantenna" "$rtxant"
383                        uci_remove "wireless" "$wifi_device" "disabled" 2> /dev/null
384                        ;;
385        esac
386
387        ###################################
388        # Setup the public wifi network
389        ###################################
390        uci_remove "wireless" "public" 2> /dev/null
391        uci_add "wireless" "wifi-iface" "public"
392        uci_set "wireless" "public" "device" "$wifi_device"
393        uci_set "wireless" "public" "ifname" "$wifi_ifname"
394        uci_set "wireless" "public" "network" "hotspotwifi"
395        uci_set "wireless" "public" "mode" "ap"
396        uci_set "wireless" "public" "ssid" "off"
397        uci_set "wireless" "public" "hidden" "0"
398        uci_set "wireless" "public" "encryption" "none"
399        uci_set "wireless" "public" "isolate" "1"
400
401        ###################################
402        # Setup the private wifi network
403        ###################################
404        config_get ssid private essid
405        config_get encryption private encryption
406        config_get wpa_crypto private wpa_crypto
407        config_get disable_wps private disable_wps
408        uci_remove "wireless" "private" 2> /dev/null
409        uci_add "wireless" "wifi-iface" "private"
410        uci_set "wireless" "private" "device" "$wifi_device"
411        uci_set "wireless" "private" "ifname" "$private_wifi_ifname"
412        uci_set "wireless" "private" "network" "lan"
413        uci_set "wireless" "private" "mode" "ap"
414        uci_set "wireless" "private" "ssid" "$ssid"
415        uci_set "wireless" "private" "hidden" "0"
416
417        case "$encryption" in
418                wpa*|WPA*|Mixed|mixed)
419                        case "$fon_device" in
420                                # The ra_wifi and madwifi / hostapd
421                                # driver scripts accept their wpa
422                                # parameters in different formats.
423                                # Perhaps this should be unified
424                                # sometime.
425                                fonera20n)
426                                        uci_set "wireless" "private" "encryption" "$encryption"
427                                        uci_set "wireless" "private" "wpa_crypto" "$wpa_crypto"
428
429                                        if [ "$disable_wps" == "1" ]; then
430                                                uci_set "wireless" "private" "wps" "0"
431                                        else
432                                                uci_set "wireless" "private" "wps" "1"
433                                        fi
434
435                                        ;;
436                                fonera20)
437                                        case "$encryption" in
438                                                WPA|WPA1|wpa|wpa1) enc=psk;;
439                                                WPA2|wpa2) enc=psk2;;
440                                                Mixed|mixed) enc=psk-mixed;;
441                                        esac
442                                        uci_set "wireless" "private" "encryption" "$enc${wpa_crypto:+/$wpa_crypto}"
443                                        ;;
444                        esac
445                        pwd=`/sbin/uci get fon.private.password`
446                        uci_set "wireless" "private" "key" "$pwd"
447                ;;
448                WEP|wep)
449                        config_get key private key
450                        uci_set "wireless" "private" "encryption" "wep"
451                        uci_set "wireless" "private" "key" "1"
452                        uci_set "wireless" "private" "key1" "$key"
453                ;;
454                open|none)
455                        uci_set "wireless" "private" "encryption" "none"
456                ;;
457        esac
458
459        ###################################
460        # Setup the wifi client interface
461        # for wifi-wan mode, if enabled.
462        ###################################
463
464        config_get mode wan mode
465        uci_remove "wireless" "uplink" 2> /dev/null
466        uci_add "wireless" "wifi-iface" "uplink"
467        uci_set "wireless" "uplink" "device" "$wifi_device"
468        uci_set "wireless" "uplink" "ifname" "$wan_wifi_ifname"
469        uci_set "wireless" "uplink" "mode" "sta"
470        [ "$mode" == "wifi" -o "$mode" == "wifi-bridge" ] && {
471                config_get ssid wan ssid
472                config_get auth wan auth
473                config_get channel wan channel
474                if [ "$mode" == "wifi" ]; then
475                        uci_set "wireless" "uplink" "network" "wan"
476                else
477                        # In wifi-bridge mode, the wifi-wan interface
478                        # should get bridged into the lan network
479                        uci_set "wireless" "uplink" "network" "lan"
480                fi
481                uci_set "wireless" "uplink" "ssid" "$ssid"
482                uci_set "wireless" "uplink" "hidden" "0"
483                # TODO: Is this needed just for 2.0n?
484                [ "$fon_device" = "fonera20n" ] && uci_set "wireless" "$wifi_device" "channel" "$channel"
485                case "$auth" in
486                        wpa*|WPA*|Mixed|mixed)
487                                case "$fon_device" in
488                                        fonera20n)
489                                                case "$auth" in
490                                                        WPA|WPA1|wpa|wpa1) enc=WPAPSK;;
491                                                        *) enc=WPA2PSK;;
492                                                esac
493                                                config_get crypto wan crypto
494                                                case "$crypto" in
495                                                        aes|AES) crypt=AES;;
496                                                        *) crypt=TKIP;;
497                                                esac
498                                                uci_set "wireless" "uplink" "wpa_crypto" "$crypt"
499                                                ;;
500                                        fonera20)
501                                                case "$auth" in
502                                                        WPA|WPA1|wpa|wpa1) enc=psk;;
503                                                        WPA2|wpa2) enc=psk2;;
504                                                        Mixed|mixed) enc=psk-mixed;;
505                                                esac
506                                                ;;
507                                esac
508                                uci_set "wireless" "uplink" "encryption" "$enc"
509                                pwd=`/sbin/uci get fon.wan.psk`
510                                uci_set "wireless" "uplink" "key" "$pwd"
511                        ;;
512                        WEP|wep)
513                                config_get key wan key1
514                                uci_set "wireless" "uplink" "encryption" "WEP"
515                                uci_set "wireless" "uplink" "key" "1"
516                                uci_set "wireless" "uplink" "key1" "$key"
517                        ;;
518                        open|none)
519                                uci_set "wireless" "uplink" "encryption" "OPEN"
520                        ;;
521                esac
522        }
523
524        uci commit wireless
525}
526
527config_dhcp() {
528        local enable dhcp
529
530        dhcp=`uci get fon.lan.dhcp`
531        mode=`uci get fon.wan.mode`
532        if [ "$dhcp" -eq 0 -o "$mode" = "bridge" -o "$mode" = "wifi-bridge" ]; then
533                uci_set "dhcp" "lan" "ignore" "1"
534        else
535                uci_remove "dhcp" "lan" "ignore"
536        fi
537}
538
539config_fon() {
540        # This is called exactly once after a firmware flash or factory
541        # reset, to set the initial wpa psk. In 2.0g this happens to be
542        # the serial number as well, but for 2.0n this is a different
543        # number.
544        local default_psk psk
545        psk=`uci -q get fon.private.password`
546        default_psk=`get_default_psk`
547
548        # Set the current wpa PSK if none is set yet. We need to check
549        # this, since we are also called after a firmware update that
550        # preserved the fon config file. We don't want to overwrite a
551        # psk set by the user.
552        if [ -z "$psk"]; then
553                # Note that this is not the admin password, as
554                # the name might suggest, but the wifi PSK.
555                uci_set "fon" "private" "password"  "$default_psk"
556        fi
557
558        # Also store the default psk separately, which is used as
559        # a default after switch (back) to wpa.
560        uci_set "fon" "private" "default_psk"  "$default_psk"
561}
562
563config_umts() {
564        # This is called on startup, to remove the umts mode (just like
565        # /etc/fonstated/UMTS does when the stick is unplugged).
566        uci del umtsd.umtsd.start
567        uci del umtsd.umtsd.killed
568        WAN=`uci get fon.wan.mode`
569        if [ "$WAN" == "umts" ]; then
570                # Restore the old mode, or dhcp if no old mode is set
571                # (the latter should never happen)
572                OLDWAN=`uci get fon.wan.old_mode`
573                uci set fon.wan.mode=${OLDWAN:-dhcp}
574                uci del fon.wan.old_mode
575        fi
576        uci commit fon
577        uci commit umtsd
578}
579
580config_timezone() {
581        config_get timezone advanced timezone
582        if [ -n "$timezone" ]; then
583                tzdesc=$(cat /etc/timezones.db | awk "\$1 == \"$timezone\" {print \$2}")
584                # /etc/init.d/boot takes care of putting this in /etc/TZ
585                uci_set "system" "@system[0]" "timezone" "$tzdesc"
586                uci commit system
587        fi
588}
589
590load_config
591
592case "$1" in
593        network)
594                # Make sure fonsmcd is started or stopped appropriately
595                # (StartFonsmcd also stops it if wifi or sharing is
596                # disabled).
597                fs -l StartFonsmcd
598                config_network;;
599        wireless) config_wireless;;
600        dhcp) config_dhcp;;
601        fon) config_fon;;
602        firewall) config_firewall;;
603        3g) config_umts;;
604        switch) config_switch;;
605        timezone) config_timezone;;
606        *) true;;
607esac
608
609
610# vim: set ts=8 sw=8 sts=8 noexpandtab: