forked from freifunk-franken/firmware
Adrian Schmutzler
3d9eb1db2e
Previously, when configurehood switched status, all WiFi devices were completely rewritten and all interfaces were deleted and recreated. This is both unnecessary and ugly. This patch redesigns WiFi setup to create all interfaces (in parallel) initially, and then only to enable/disable them as necessary. Where reconfiguration is necessary, only the variable parts are changed. Since most of the wifi-device config is already created by OpenWrt, this builds based on the existing wifi-devices and only removes the default wifi-ifaces. This patch will not change the logic (codeflow) of configurehood, but only affects how action on the WiFi devices/interfaces is taken. Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de> Reviewed-by: Fabian Bläse <fabian@blaese.de>
258 lines
8.0 KiB
Bash
Executable File
258 lines
8.0 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# Allow only one instance
|
|
lockfile="/var/lock/${0##*/}.lock"
|
|
if ! lock -n "$lockfile"; then
|
|
echo "Only one instance of $0 allowed."
|
|
exit 1
|
|
fi
|
|
trap "lock -u \"$lockfile\"" INT TERM EXIT
|
|
|
|
. /usr/share/libubox/jshn.sh
|
|
. /lib/functions/fff/keyxchange
|
|
. /lib/functions/fff/network
|
|
. /lib/functions/fff/wireless
|
|
. /lib/functions/fff/timeserver
|
|
. /usr/lib/functions/fff/hoodfile
|
|
|
|
|
|
hoodfilelocal=/etc/hoodfile
|
|
|
|
rm -f "$hoodfiletmp"
|
|
|
|
# Gatewaycheck function
|
|
isGatewayAvailable() {
|
|
if [ -n "$(batctl gwl -H)" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
# Ping test
|
|
hasInternet() {
|
|
test_ipv4_host1="keyserver.freifunk-franken.de" # Freifunk-Franken keyserver
|
|
test_ipv4_host2="8.8.8.8" # Google DNS
|
|
test_ipv6_host1="heise.de" # heise Zeitschriftenverlag
|
|
if ping -w5 -c3 "$test_ipv4_host1" &>/dev/null ||
|
|
ping -w5 -c3 "$test_ipv4_host2" &>/dev/null ||
|
|
ping6 -w5 -c3 "$test_ipv6_host1" &>/dev/null ; then
|
|
return 0
|
|
fi
|
|
return 1
|
|
}
|
|
|
|
# Hidden AP check
|
|
|
|
if [ -s "$hoodfilewww" ] && isGatewayAvailable ; then
|
|
needwifi="0"
|
|
for radio in $(wifiListRadio); do
|
|
freq="$(wifiGetFreq $radio)"
|
|
|
|
# Break: wXconfig is up
|
|
[ "$(uci get "wireless.w${freq}configap.disabled")" = "0" ] && continue
|
|
# Break: No mesh interface
|
|
[ "$(uci get "wireless.w${freq}mesh.disabled")" = "0" ] || continue
|
|
|
|
# Enable configap
|
|
uci set wireless.w${freq}configap.disabled='0'
|
|
uci commit wireless
|
|
needwifi="1"
|
|
done
|
|
|
|
if [ "$needwifi" = "1" ] ; then
|
|
wifi
|
|
sleep 10
|
|
fi
|
|
fi
|
|
|
|
if [ -s "$hoodfilelocal" ]; then
|
|
# remove webroot hoodfile to prevent offering local hoodfiles to neighbours
|
|
rm -f "$hoodfilewww"
|
|
|
|
cp "$hoodfilelocal" "$hoodfiletmp"
|
|
echo "Use local hood file"
|
|
else
|
|
# if we have Internet, we download the Hoodfile from the keyxchangev2
|
|
if hasInternet ; then
|
|
getKeyserverHoodfile "$hoodfiletmp" && cp "$hoodfiletmp" "$hoodfilewww"
|
|
|
|
#if no Internet, we connect to the hidden AP and download the file from another Node in range
|
|
else
|
|
# connect to wireless hidden ap here and download the json File from the nearest router
|
|
# Only do that, when we have no gateway in range. If the Uplinkrouter changed the hood, we lost the GW and do this automatically again, I think! Nice idea?
|
|
if ! isGatewayAvailable ; then
|
|
#now we haven't a gateway in Range, we search for a hidden AP to get a keyxchangev2data file!
|
|
#first we delete all wifi settings
|
|
rm -f "$hoodfileref" # delete this, so interfaces are recreated if reconnect with unchanged hood file takes place
|
|
rm -f "$hoodfilewww" # delete this, so wrong hood file is not broadcasted anymore
|
|
|
|
uci -q del "system.@system[0].hood"
|
|
uci -q del "system.@system[0].hoodid"
|
|
uci -q commit system
|
|
reload_config
|
|
|
|
sleep 30 # Wait for the config AP, which may be created at the same time as this script has started
|
|
|
|
getEthernetHoodfile "$hoodfiletmp" || getWirelessHoodfile "$hoodfiletmp"
|
|
else
|
|
echo "We have a Gateway in Range, we load the keyxchangev2data from fe80::1"
|
|
getGatewayHoodfile "$hoodfiletmp" && cp "$hoodfiletmp" "$hoodfilewww"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
if [ -s "$hoodfiletmp" ]; then
|
|
|
|
# we get a json file in this format:
|
|
# https://pw.freifunk-franken.de/patch/205/
|
|
# but without signature, every hood file we get is valid!
|
|
|
|
sumnew=$(cat "$hoodfiletmp" 2>/dev/null | sha256sum | cut -f1 -d " ")
|
|
sumold=$(cat "$hoodfileref" 2>/dev/null | sha256sum | cut -f1 -d " ")
|
|
|
|
json_load "$(cat "$hoodfiletmp")"
|
|
|
|
if [ "$sumnew" != "$sumold" ] ; then
|
|
echo "New file detected, we reconfigure the Node";
|
|
|
|
json_select hood
|
|
|
|
json_get_var hood name
|
|
json_get_var hoodid id
|
|
[ -n "$mesh_id" ] || json_get_var mesh_id mesh_id
|
|
[ -n "$mesh_bssid" ] || json_get_var mesh_bssid mesh_bssid
|
|
[ -n "$mesh_essid" ] || json_get_var mesh_essid mesh_essid
|
|
[ -n "$essid" ] || json_get_var essid essid
|
|
json_get_var ntpip ntp_ip
|
|
[ -n "$chan2ghz" ] || json_get_var chan2ghz channel2
|
|
[ -n "$mesh_type2" ] || json_get_var mesh_type2 mesh_type2
|
|
[ -n "$chan5ghz" ] || json_get_var chan5ghz channel5
|
|
[ -n "$mesh_type5" ] || json_get_var mesh_type5 mesh_type5
|
|
# Additional parameters may be activated in future versions
|
|
#json_get_var mode2 mode2
|
|
#json_get_var mode5 mode5
|
|
#json_get_var protocol protocol
|
|
|
|
json_select ".." # back to root
|
|
|
|
if ! ([ -n "$chan2ghz" ] && [ -n "$chan5ghz" ]) ; then
|
|
# If channel is missing, do nothing
|
|
exit 0
|
|
fi
|
|
|
|
echo "Setting hood name: $hood (ID $hoodid)"
|
|
uci -q set "system.@system[0].hood=$hood"
|
|
uci -q set "system.@system[0].hoodid=$hoodid"
|
|
uci -q commit system
|
|
reload_config
|
|
|
|
for radio in $(wifiListRadio); do
|
|
freq="$(wifiGetFreq $radio)"
|
|
|
|
if [ "$freq" = "5" ]; then
|
|
uci set wireless.${radio}.channel="$chan5ghz"
|
|
mesh_type="$mesh_type5"
|
|
elif [ "$freq" = "2" ]; then
|
|
uci set wireless.${radio}.channel="$chan2ghz"
|
|
mesh_type="$mesh_type2"
|
|
fi
|
|
|
|
# Disable wXsta, wXconfigap
|
|
uci set wireless.w${freq}sta.disabled='1'
|
|
uci set wireless.w${freq}configap.disabled='1'
|
|
|
|
# Configure wXap
|
|
uci set wireless.w${freq}ap.ssid="$essid"
|
|
uci set wireless.w${freq}ap.disabled='0'
|
|
|
|
# Configure 802.11s mesh if type = "802.11s"
|
|
if [ "$mesh_type" = "802.11s" ]; then
|
|
uci set wireless.w${freq}mesh.mode='mesh'
|
|
uci -q del wireless.w${freq}mesh.bssid
|
|
uci -q del wireless.w${freq}mesh.ssid
|
|
uci -q del wireless.w${freq}mesh.mcast_rate
|
|
uci set wireless.w${freq}mesh.mesh_id="$mesh_id"
|
|
uci set wireless.w${freq}mesh.mesh_fwding='0'
|
|
uci set wireless.w${freq}mesh.disabled='0'
|
|
# Configure IBSS mesh if type = "ibss"
|
|
elif [ "$mesh_type" = "ibss" ]; then
|
|
uci set wireless.w${freq}mesh.mode='adhoc'
|
|
uci -q del wireless.w${freq}mesh.mesh_id
|
|
uci -q del wireless.w${freq}mesh.mesh_fwding
|
|
uci set wireless.w${freq}mesh.bssid="$mesh_bssid"
|
|
uci set wireless.w${freq}mesh.ssid="$mesh_essid"
|
|
uci set wireless.w${freq}mesh.mcast_rate='6000'
|
|
uci set wireless.w${freq}mesh.disabled='0'
|
|
# Disable mesh by setting no mesh_type
|
|
else
|
|
uci set wireless.w${freq}mesh.disabled='1'
|
|
fi
|
|
done
|
|
|
|
uci commit wireless
|
|
echo "Loading wifi"
|
|
wifi
|
|
|
|
oldntp="$(uci -q get system.ntp.server)"
|
|
newntp="${ntpip}" # requires routable address, no link-local
|
|
[ "$newntp" = "$oldntp" ] || setTimeserver "${newntp}" # only rewrite if changed
|
|
|
|
# copy the file to webroot so that other mesh routers can download it;
|
|
# copy only after all other steps so IF can be reentered if something goes wrong
|
|
cp "$hoodfiletmp" "$hoodfileref"
|
|
|
|
# This is a workaround to enable alfred on devices which do not see a configap during initial setup
|
|
/etc/init.d/alfred restart
|
|
else
|
|
echo "We have no new file. We do nothing. We try it again in 5 minutes...";
|
|
fi
|
|
|
|
# and now we get to vpn-select script and load VPNs directly from /tmp/keyxchangev2data
|
|
|
|
if hasInternet ; then
|
|
/usr/sbin/vpn-select "$hoodfiletmp"
|
|
else
|
|
/usr/sbin/vpn-stop
|
|
fi
|
|
|
|
# now we load the prefix from the hoodfile and set this to br-mesh
|
|
json_select network
|
|
json_get_var prefix ula_prefix
|
|
# Set $prefix::MAC as IP
|
|
if [ -n "$prefix" ] ; then
|
|
prefix="$(echo "$prefix" | sed -e 's,\\,,')"
|
|
mac="$(cat "/sys/class/net/br-mesh/address")"
|
|
addr="$(ipMacAssemble "$prefix" "$mac")"
|
|
addr="$(ipTidyColon "$addr")"
|
|
addr_eui="$(ipEUIAssemble "$prefix" "$mac")"
|
|
addr_eui="$(ipTidyColon "$addr_eui")"
|
|
for ip in $(ip -6 addr show dev br-mesh | grep inet6 | grep -v -e " $addr" -e " $addr_eui" -e " fe80::" -e " fdff::" | cut -f6 -d " "); do
|
|
ip -6 addr del "$ip" dev br-mesh
|
|
done
|
|
if ! ( ip -6 addr show dev br-mesh | grep -q "$addr" ) ; then
|
|
ip -6 addr add "$addr" dev br-mesh
|
|
echo "Set ULA address to br-mesh: $addr"
|
|
else
|
|
echo "Address already set."
|
|
fi
|
|
# Set $prefix::link-local as IP
|
|
if ! ( ip -6 addr show dev br-mesh | grep -q "$addr_eui" ) ; then
|
|
ip -6 addr add "$addr_eui" dev br-mesh
|
|
echo "Set ULA EUI-64 address to br-mesh: $addr_eui"
|
|
else
|
|
echo "Address already set."
|
|
fi
|
|
if ! ( ip -6 route show dev br-mesh | grep -q "fc00::" ) ; then
|
|
ip -6 route add fc00::/7 via fe80::1 dev br-mesh
|
|
echo "Set ULA route to br-mesh."
|
|
else
|
|
echo "Route already set."
|
|
fi
|
|
fi
|
|
json_select ".." # back to root
|
|
else
|
|
echo "We haven't got a file. We do nothing. We try it again in 5 minutes...";
|
|
exit 0
|
|
fi
|