firmware/src/packages/fff/fff-hoods/files/usr/sbin/configurehood
Fabian Blaese c23c98b2cb fff-hoods: create hoodfile AP earlier
The hidden AP creation is moved to the end of
configurehood, so it is executed right after hoodfile
changes are processed.

When keeping the long sleep before trying to gather hoodfiles
via wireless or ethernet, this should decrease the delay after
hood changes to a minimum, as mesh nodes don't have to wait
until configurehood on VPN nodes is executed a second time.

Because hoodfiles gathered via wireless or ethernet are not
copied to hoodfilewww (which is used to deliver the active
hoodfile via ethernet or wireless), only authoritative hoodfiles
(keyxchange and gateway) trigger the creation of a hidden AP.

Signed-off-by: Fabian Bläse <fabian@blaese.de>
Reviewed-by: Robert Langhammer <rlanghammer@web.de>
Acked-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
[bump PKG_RELEASE]
Signed-off-by: Adrian Schmutzler <freifunk@adrianschmutzler.de>
2020-08-01 01:07:57 +02:00

249 lines
7.5 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() {
internetAddresses="keyserver.freifunk-franken.de heise.de"
for addr in $internetAddresses; do
ping -w5 -c3 "$addr" &>/dev/null && return 0
done
return 1
}
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 internet is available, the hoodfile is downloaded from our keyserver
if getKeyserverHoodfile "$hoodfiletmp"; then
cp "$hoodfiletmp" "$hoodfilewww"
# if no internet is available, but the node is already configured,
# a gateway with the appropriate hoodfile should be available
elif getGatewayHoodfile "$hoodfiletmp"; then
cp "$hoodfiletmp" "$hoodfilewww"
# no internet and no gateway available. the node is either unconfigured,
# has lost connectivity or the hood is broken. Try to regain connectivity by
# fetching hoodfiles from nearby nodes
else
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 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"
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 set "system.@system[0].hood=$hood"
uci set "system.@system[0].hoodid=$hoodid"
uci commit system
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 wXconfigap
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 "Reloading wifi"
reload_config
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
# 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
reload_config
sleep 10
fi
fi