| #!/bin/selfclean /bin/sh |
| # |
| # This script monitors /tmp/conman/command* /tmp/conman/access_point_enabled* |
| # and starts or stops access points accordingly. |
| # |
| # Also adds routes based on gateways output by dhclient-script. |
| # |
| . /etc/utils.sh |
| |
| if experiment BigInitRwnd; then |
| initrwnd='initrwnd 1000' |
| else |
| initrwnd= |
| fi |
| |
| if experiment ConmanDebug; then |
| set -x |
| fi |
| |
| TMP_DIR="/tmp/conman" |
| CONFIG_DIR="/config/conman" |
| |
| mkdir -p $TMP_DIR |
| mkdir -p $CONFIG_DIR |
| |
| iplog() { |
| echo "running: ip" "$@" >&2 |
| ip "$@" |
| } |
| |
| valid_word() { |
| case "$1" in |
| access_point|command) return 0 ;; |
| *) return 1 ;; |
| esac |
| } |
| |
| valid_band() { |
| case "$1" in |
| 2.4|5) return 0 ;; |
| *) return 1 ;; |
| esac |
| } |
| |
| stopap() { |
| local interface_suffix="$1" |
| local band="$2" |
| |
| flags="--band $band" |
| if [ -n "$interface_suffix" ]; then |
| flags="$flags --interface-suffix "$interface_suffix"" |
| fi |
| if ! $(wifi stopap $flags); then |
| echo "Failed to stop access point for $suffix $band" |
| false |
| fi |
| } |
| |
| # Check all existing command and gateway files, then monitor those as well as |
| # access_point files for changes. |
| { cd "$TMP_DIR" && ls gateway.* command.* subnet.*; |
| cd "$CONFIG_DIR" && ls command.*; |
| watch-dir $TMP_DIR $CONFIG_DIR; } | |
| while read filename; do |
| route_type= |
| if startswith "$filename" "subnet."; then |
| route_type="subnet" |
| fi |
| if startswith "$filename" "gateway."; then |
| route_type="gateway" |
| fi |
| if [ "$route_type" != "" ]; then |
| filepath="$TMP_DIR/$filename" |
| if [ -e "$filepath" ]; then |
| interface=${filename#${route_type}.} |
| |
| # make sure interface is actually an interface, and not a .tmp file |
| if [ ! -e "/sys/class/net/$interface" ]; then |
| continue |
| fi |
| |
| # Trying to add a default route without a subnet route fails, because |
| # there is no route to the gateway. So just always update the subnet |
| # route first, and then update the default route if we know the gateway. |
| subnet_filepath="$TMP_DIR/subnet.$interface" |
| if [ -e "$subnet_filepath" ]; then |
| subnet=$(cat "$subnet_filepath") |
| # If this script is running as conman's deathrattle, it is possible that |
| # there is a wifi route up too and also that acs_autoprovisioning is |
| # enabled. Between deleting and re-adding this default route, traffic |
| # could be routed via wifi, and if autoprovisioning is enabled and the |
| # wifi connection is to a neighbor's RG then the ACS could provision this |
| # device to the neighbor. Removing the file which enables that |
| # autoprovisioning here prevents that from happening. |
| rm -f /tmp/conman/acs_autoprovisioning |
| |
| # Remove all subnet routes on $interface except default, with 'scope |
| # link', then recreate the desired subnet route. |
| iplog -4 route show dev "$interface" | |
| while read route junk; do |
| # Ignore the RFC2365 multicast route. |
| if ! startswith "$route" "239"; then |
| if contains "$route" "/" && [ "$route" != "$subnet" ]; then |
| iplog -4 route del "$route" dev "$interface" |
| fi |
| fi |
| done |
| iplog -4 route add "$subnet" dev "$interface" $initrwnd |
| |
| gateway_filepath="$TMP_DIR/gateway.$interface" |
| if [ -e "$gateway_filepath" ]; then |
| gateway=$(cat "$gateway_filepath") |
| if ! ip route show dev "$interface" | grep default | grep "via $gateway"; then |
| iplog -4 route del default dev "$interface" |
| iplog -4 route add default via "$gateway" dev "$interface" $initrwnd |
| fi |
| fi |
| fi |
| fi |
| continue |
| fi |
| |
| # This assumes command files in /tmp (for provisioning networks) will have an |
| # interface suffix, and those in /config (the user's WLAN) will not. |
| word= |
| suffix= |
| band= |
| |
| IFS='.' read word band <<EOF |
| $filename |
| EOF |
| if valid_word "$word" && valid_band "$band"; then |
| expect_dir="$CONFIG_DIR" |
| else |
| IFS='.' read word suffix band <<EOF |
| $filename |
| EOF |
| if valid_word "$word" && valid_band "$band"; then |
| expect_dir="$TMP_DIR" |
| else |
| continue |
| fi |
| fi |
| |
| if [ -z "$suffix" ]; then |
| command="$expect_dir/command.$band" |
| access_point="$expect_dir/access_point.$band" |
| else |
| command="$expect_dir/command.$suffix.$band" |
| access_point="$expect_dir/access_point.$suffix.$band" |
| fi |
| |
| if [ -e "$command" ] && [ -e "$access_point" ]; then |
| if ! run_command_lines $command; then |
| echo "Failed to start access point for '$extension'" |
| fi |
| else |
| stopap "$suffix" "$band" |
| fi |
| done |