304 lines
5.7 KiB
Bash
304 lines
5.7 KiB
Bash
#!/bin/sh /etc/rc.common
|
|
# Copyright (C) 2012-2013 OpenWrt.org
|
|
|
|
START=95
|
|
|
|
EXTRA_COMMANDS="up down show_key generate_key"
|
|
|
|
LIST_SEP="
|
|
"
|
|
TMP_FASTD=/tmp/fastd
|
|
FASTD_COMMAND=/usr/bin/fastd
|
|
|
|
append_opt() {
|
|
local v="$1"; local p="$2"
|
|
|
|
OPTS="$OPTS --${p//_/-} '${v//'/\\'}'"
|
|
}
|
|
|
|
append_opt_bool() {
|
|
local p="$1"
|
|
|
|
OPTS="$OPTS --${p//_/-}"
|
|
}
|
|
|
|
append_opts() {
|
|
local p; local v; local s="$1"; shift
|
|
for p in $*; do
|
|
config_get v "$s" "$p"
|
|
[ -n "$v" ] && append_opt "$v" "$p"
|
|
done
|
|
}
|
|
|
|
append_opts_bool() {
|
|
local p; local v; local s="$1"; shift
|
|
for p in $*; do
|
|
config_get_bool v "$s" "$p" 0
|
|
[ "$v" = 1 ] && append_opt_bool "$p"
|
|
done
|
|
}
|
|
|
|
append_opts_list() {
|
|
local p; local s="$1"; shift
|
|
for p in $*; do
|
|
config_list_foreach "$s" "$p" append_opt "$p"
|
|
done
|
|
}
|
|
|
|
section_enabled() {
|
|
config_get_bool enabled "$1" 'enabled' 0
|
|
[ $enabled -gt 0 ]
|
|
}
|
|
|
|
error() {
|
|
echo "${initscript}:" "$@" 1>&2
|
|
}
|
|
|
|
create_peer_config() {
|
|
local s="$2"; local peer="$1"
|
|
|
|
config_get net "$peer" net
|
|
[ "$net" == "$s" ] || return 0
|
|
|
|
section_enabled "$peer" || return 0
|
|
|
|
config_get key "$peer" key
|
|
config_get address "$peer" address
|
|
config_get hostname "$peer" hostname
|
|
config_get address_family "$peer" address_family
|
|
config_get port "$peer" port
|
|
config_get_bool float "$peer" float 0
|
|
|
|
if [ -z "$key" ]; then
|
|
error "peer $peer: key is not set"
|
|
return 1
|
|
fi
|
|
|
|
local remote=''
|
|
if [ "$address" -o "$hostname" ]; then
|
|
if [ "$address" -a "$hostname" ]; then
|
|
error "peer $peer: both address and hostname given"
|
|
return 1
|
|
fi
|
|
|
|
if [ "$float" = 0 ]; then
|
|
float=''
|
|
else
|
|
float='float'
|
|
fi
|
|
|
|
if [ "$port" ]; then
|
|
if [ "$address" ]; then
|
|
remote="remote $address port $port $float;"
|
|
else # $hostname
|
|
if [ "$address_family" -a "$address_family" != 'ipv4' -a "$address_family" != 'ipv6' ]; then
|
|
error "peer $peer: invalid address family given"
|
|
return 1
|
|
fi
|
|
remote="remote $address_family \"$hostname\" port $port $float;"
|
|
fi
|
|
else
|
|
error "peer $peer: address or hostname, but no port given"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
cat > "$TMP_FASTD/fastd.$s.peers/$peer" <<EOF
|
|
key "$key";
|
|
$remote
|
|
EOF
|
|
}
|
|
|
|
update_peers_instance() {
|
|
local s="$1"
|
|
|
|
rm -rf "$TMP_FASTD/fastd.$s.peers"
|
|
mkdir -p "$TMP_FASTD/fastd.$s.peers"
|
|
|
|
config_foreach create_peer_config 'peer' "$s"
|
|
}
|
|
|
|
get_key_instance() {
|
|
local s="$1"
|
|
|
|
config_get secret "$s" secret
|
|
if [ "$secret" = 'generate' ]; then
|
|
secret=`fastd --generate-key --machine-readable`
|
|
uci -q set fastd."$s".secret="$secret" && uci -q commit fastd
|
|
fi
|
|
|
|
echo "$secret"
|
|
}
|
|
|
|
generate_key_instance() {
|
|
local s="$1"
|
|
|
|
config_get secret "$s" secret
|
|
if [ -z "$secret" -o "$secret" = 'generate' ]; then
|
|
secret=`fastd --generate-key --machine-readable`
|
|
uci -q set fastd."$s".secret="$secret" && uci -q commit fastd
|
|
fi
|
|
|
|
"$FASTD_COMMAND" --config - --show-key --machine-readable <<EOF
|
|
secret "$secret";
|
|
EOF
|
|
}
|
|
|
|
show_key_instance() {
|
|
local s="$1"
|
|
|
|
local secret=`get_key_instance "$s"`
|
|
if [ -z "$secret" ]; then
|
|
error "$s: secret is not set"
|
|
return 1
|
|
fi
|
|
|
|
"$FASTD_COMMAND" --config - --show-key --machine-readable <<EOF
|
|
secret "$secret";
|
|
EOF
|
|
}
|
|
|
|
start_instance() {
|
|
local s="$1"
|
|
|
|
section_enabled "$s" || return 1
|
|
|
|
SERVICE_PID_FILE="/var/run/fastd.$s.pid"
|
|
OPTS=""
|
|
|
|
config_get interface "$s" interface
|
|
if [ -z "$interface" ]; then
|
|
error "$s: interface is not set"
|
|
return 1
|
|
fi
|
|
|
|
if ifconfig "$interface" &>/dev/null; then
|
|
error "$s: interface '$interface' is already in use"
|
|
return 1
|
|
fi
|
|
|
|
local secret=`get_key_instance "$s"`
|
|
if [ -z "$secret" ]; then
|
|
error "$s: secret is not set"
|
|
return 1
|
|
fi
|
|
|
|
append_opts_list "$s" config config_peer_dir config_peer bind method
|
|
append_opts "$s" syslog_level mode interface mtu
|
|
append_opts_bool "$s" forward
|
|
|
|
update_peers_instance "$s"
|
|
|
|
eval service_start "'$FASTD_COMMAND'" --daemon --pid-file "'$SERVICE_PID_FILE'" --syslog-level info $OPTS --config-peer-dir "$TMP_FASTD/fastd.$s.peers" --config - <<EOF
|
|
secret "$secret";
|
|
EOF
|
|
|
|
if ! ifconfig "$interface" >/dev/null 2>&1; then
|
|
error "$s: startup failed"
|
|
return 1
|
|
fi
|
|
|
|
config_get up "$s" up
|
|
[ -n "$up" ] && sh -c "$up" - "$interface"
|
|
}
|
|
|
|
stop_instance() {
|
|
local s="$1"
|
|
|
|
section_enabled "$s" || return 1
|
|
|
|
SERVICE_PID_FILE="/var/run/fastd.$s.pid"
|
|
|
|
config_get interface "$s" interface
|
|
if [ -z "$interface" ]; then
|
|
error "$s: interface is not set"
|
|
return 1
|
|
fi
|
|
|
|
if ! ifconfig "$interface" &>/dev/null; then
|
|
error "$s: interface '$interface' does not exist"
|
|
return 1
|
|
fi
|
|
|
|
config_get down "$s" down
|
|
[ -n "$down" ] && sh -c "$down" - "$interface"
|
|
|
|
service_stop "$FASTD_COMMAND"
|
|
|
|
rm -rf "$TMP_FASTD/fastd.$s.peers"
|
|
}
|
|
|
|
reload_instance() {
|
|
local s="$1"
|
|
|
|
section_enabled "$s" || return 1
|
|
|
|
update_peers_instance "$s"
|
|
|
|
SERVICE_PID_FILE="/var/run/fastd.$s.pid"
|
|
service_reload "$FASTD_COMMAND"
|
|
}
|
|
|
|
start() {
|
|
config_load 'fastd'
|
|
config_foreach start_instance 'fastd'
|
|
}
|
|
|
|
stop() {
|
|
config_load 'fastd'
|
|
config_foreach stop_instance 'fastd'
|
|
}
|
|
|
|
reload() {
|
|
config_load 'fastd'
|
|
config_foreach reload_instance 'fastd'
|
|
}
|
|
|
|
up() {
|
|
local exists
|
|
local instance
|
|
config_load 'fastd'
|
|
for instance in "$@"; do
|
|
config_get exists "$instance" 'TYPE'
|
|
if [ "$exists" = 'fastd' ]; then
|
|
start_instance "$instance"
|
|
fi
|
|
done
|
|
}
|
|
|
|
down() {
|
|
local exists
|
|
local instance
|
|
config_load 'fastd'
|
|
for instance in "$@"; do
|
|
config_get exists "$instance" 'TYPE'
|
|
if [ "$exists" = 'fastd' ]; then
|
|
stop_instance "$instance"
|
|
fi
|
|
done
|
|
}
|
|
|
|
show_key() {
|
|
local exists
|
|
local instance
|
|
config_load 'fastd'
|
|
for instance in "$@"; do
|
|
config_get exists "$instance" 'TYPE'
|
|
if [ "$exists" = 'fastd' ]; then
|
|
show_key_instance "$instance"
|
|
fi
|
|
done
|
|
}
|
|
|
|
generate_key() {
|
|
local exists
|
|
local instance
|
|
config_load 'fastd'
|
|
for instance in "$@"; do
|
|
config_get exists "$instance" 'TYPE'
|
|
if [ "$exists" = 'fastd' ]; then
|
|
generate_key_instance "$instance"
|
|
fi
|
|
done
|
|
}
|