1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2012-2013 OpenWrt.org
8 EXTRA_COMMANDS
="up down show_key generate_key"
13 FASTD_COMMAND
=/usr
/bin
/fastd
17 config_get_bool enabled
"$1" 'enabled' 0
22 echo "${initscript}:" "$@" 1>&2
28 config_get secret
"$s" secret
29 if [ "$secret" = 'generate' ]; then
30 secret
=`"$FASTD_COMMAND" --generate-key --machine-readable`
31 uci
-q set fastd.
"$s".secret
="$secret" && uci
-q commit fastd
40 echo -n "\"${t//\"/\\\"}\""
44 local t
=${1//[^-a-z0-9\[\].:]/}
49 local t
=${1//[^-a-zA-Z0-9\[\].:\"% ]/}
50 local quotes
=${t//[^\"]/}
51 if [ "${#quotes}" = 0 -o "${#quotes}" = 2 ]; then
58 0|no|off|false|disabled
) echo -n no
;;
63 config_string_config
='include $(escape_string "$value");'
64 config_string_config_peer
='include peer $(escape_string "$value");'
65 config_string_config_peer_dir
='include peers from $(escape_string "$value");'
66 config_string_bind
='bind $(guard_value "$value");'
67 config_string_method
='method $(escape_string "$value");'
68 config_string_syslog_level
='log to syslog level $(guard_value "$value");'
69 config_string_mode
='mode $(guard_value "$value");'
70 config_string_interface
='interface $(escape_string "$value");'
71 config_string_mtu
='mtu $(guard_value "$value");'
72 config_string_peer_limit
='peer limit $(guard_value "$value");'
73 config_string_user
='user $(escape_string "$value");'
74 config_string_group
='group $(escape_string "$value");'
75 config_string_pmtu
='pmtu $(yes_no "$value");'
76 config_string_forward
='forward $(yes_no "$value");'
77 config_string_hide_ip_addresses
='hide ip addresses $(yes_no "$value");'
78 config_string_hide_mac_addresses
='hide mac addresses $(yes_no "$value");'
79 config_string_secure_handshakes
='secure handshakes $(yes_no "$value");'
80 config_string_packet_mark
='packet mark $(guard_value "$value");'
82 config_string_peer
='peer $(escape_string "$value") {'
83 config_string_peer_group
='peer group $(escape_string "$value") {'
85 peer_string_key
='key $(escape_string "$value");'
86 peer_string_float
='float $(yes_no "$value");'
87 peer_string_remote
='remote $(guard_remote "$value");'
90 local __string
=$
(eval echo \"\$
$2\")
92 eval echo "\"$__string\""
96 local v
; local len
; local s
="$1"; local prefix
="$2"; local p
="$3"
98 config_get len
"$s" "${p}_LENGTH"
100 if [ -z "$len" ]; then
101 config_get v
"$s" "$p"
102 [ -n "$v" ] && generate_option
"$v" "${prefix}_string_${p}"
104 config_list_foreach
"$s" "$p" generate_option
"${prefix}_string_${p}"
109 local p
; local s
="$1"; local prefix
="$2"; shift; shift
111 append_option
"$s" "$prefix" "$p"
116 generate_config_secret
() {
117 echo "secret $(escape_string "$1");"
121 generate_peer_config
() {
124 # These options are deprecated
125 config_get address
"$peer" address
126 config_get hostname
"$peer" hostname
127 config_get address_family
"$peer" address_family
128 config_get port
"$peer" port
130 if [ "$address" -o "$hostname" ]; then
131 if [ -z "$port" ]; then
132 error
"peer $peer: address or hostname, but no port given"
136 if [ "$hostname" ]; then
137 generate_option peer_string_remote
"$address_family \"$hostname\" port $port"
140 if [ "$address" ]; then
141 generate_option peer_string_remote
"$address port $port"
145 append_options
"$peer" peer \
149 generate_single_peer_config
() {
150 local peer
="$1"; local net
="$2"
152 config_get peer_net
"$peer" net
153 config_get peer_group
"$peer" group
154 [ "$net" = "$peer_net" -a "$peer_group" = '' ] ||
return 0
156 section_enabled
"$peer" ||
return 0
158 generate_option
"$peer" config_string_peer
159 generate_peer_config
"$peer"
163 create_peer_config
() {
164 local peer
="$1"; local net
="$2"; local group
="$3"; local path
="$4"
166 config_get peer_net
"$peer" net
167 config_get peer_group
"$peer" group
168 [ "$group" = "$peer_group" ] ||
return 0
170 if [ "$net" != "$peer_net" ]; then
171 [ -z "$group" ] || error
"warning: the peer group of peer '$peer' doesn't match its net, the peer will be ignored"
175 section_enabled
"$peer" ||
return 0
177 generate_peer_config
"$peer" >"$path/$peer"
180 update_peer_group
() {
181 local net
="$1"; local group_dir
="$2"; local group
="$3"; local update_only
="$4"
182 local path
="$TMP_FASTD/fastd.$net/$group_dir"
187 config_foreach create_peer_config
'peer' "$net" "$group" "$path"
189 if [ -z "$update_only" ]; then
190 generate_option
"$path" config_string_config_peer_dir
193 config_foreach generate_peer_group_config
'peer_group' "$net" "$group_dir" "$update_only" "$group"
196 generate_peer_group_config
() {
197 local group
="$1"; local net
="$2"; local group_dir
="$3%$group"; local update_only
="$4"; local parent
="$5"
199 config_get group_net
"$group" net
200 config_get group_parent
"$group" parent
201 [ "$parent" = "$group_parent" ] ||
return 0
203 if [ "$net" != "$peer_net" ]; then
204 [ -z "$parent" ] || error
"warning: the parent of peer group '$group' doesn't match its net, the peer group will be ignored"
208 section_enabled
"$group" ||
return 0
210 if [ -z "$update_only" ]; then
211 generate_option
"$group" config_string_peer_group
212 append_options
"$group" config \
213 config config_peer config_peer_dir peer_limit
216 update_peer_group
"$net" "$group_dir" "$group" "$update_only"
218 if [ -z "$update_only" ]; then
223 update_peer_groups
() {
224 local net
="$1"; local update_only
="$2"
226 update_peer_group
"$net" 'peers' '' "$update_only"
232 generate_option
'info' config_string_syslog_level
234 append_options
"$s" config \
235 config config_peer config_peer_dir
bind method syslog_level mode interface mtu peer_limit \
236 user group pmtu forward hide_ip_addresses hide_mac_addresses secure_handshakes packet_mark
238 config_get mode
"$s" mode
240 if [ "$mode" = "tun" ]; then
241 config_foreach generate_single_peer_config
'peer' "$s"
243 update_peer_groups
"$s"
248 generate_key_instance
() {
251 config_get secret
"$s" secret
252 if [ -z "$secret" -o "$secret" = 'generate' ]; then
253 secret
=`fastd --generate-key --machine-readable`
254 uci
-q set fastd.
"$s".secret
="$secret" && uci
-q commit fastd
257 generate_config_secret
"$secret" |
"$FASTD_COMMAND" --config - --show-key --machine-readable
260 show_key_instance
() {
263 local secret
=`get_key_instance "$s"`
264 if [ -z "$secret" ]; then
265 error
"$s: secret is not set"
269 generate_config_secret
"$secret" |
"$FASTD_COMMAND" --config - --show-key --machine-readable
275 section_enabled
"$s" ||
return 1
277 SERVICE_PID_FILE
="/var/run/fastd.$s.pid"
279 config_get interface
"$s" interface
280 if [ -z "$interface" ]; then
281 error
"$s: interface is not set"
285 if ifconfig
"$interface" &>/dev
/null
; then
286 error
"$s: interface '$interface' is already in use"
290 config_get mode
"$s" mode
291 if [ -z "$mode" ]; then
292 error
"$s: mode is not set"
296 local secret
=`get_key_instance "$s"`
297 if [ -z "$secret" ]; then
298 error
"$s: secret is not set"
302 rm -f "$SERVICE_PID_FILE"
303 touch "$SERVICE_PID_FILE"
305 config_get user
"$s" user
307 chown
"$user" "$SERVICE_PID_FILE"
310 (generate_config_secret
"$secret"; generate_config
"$s") | service_start
"$FASTD_COMMAND" --config - --daemon --pid-file "$SERVICE_PID_FILE"
312 if ! ifconfig
"$interface" >/dev
/null
2>&1; then
313 error
"$s: startup failed"
317 config_get up
"$s" up
318 [ -n "$up" ] && sh
-c "$up" - "$interface"
324 section_enabled
"$s" ||
return 1
326 SERVICE_PID_FILE
="/var/run/fastd.$s.pid"
328 config_get interface
"$s" interface
329 if [ -z "$interface" ]; then
330 error
"$s: interface is not set"
334 if ! ifconfig
"$interface" &>/dev
/null
; then
335 error
"$s: interface '$interface' does not exist"
339 config_get down
"$s" down
340 [ -n "$down" ] && sh
-c "$down" - "$interface"
342 service_stop
"$FASTD_COMMAND"
344 rm -rf "$TMP_FASTD/fastd.$s"
350 section_enabled
"$s" ||
return 1
352 config_get mode
"$s" mode
353 [ "$mode" = "tun" ] && return 1
355 update_peer_groups
"$s" true
357 SERVICE_PID_FILE
="/var/run/fastd.$s.pid"
358 service_reload
"$FASTD_COMMAND"
363 config_foreach start_instance
'fastd'
369 config_foreach stop_instance
'fastd'
375 config_foreach reload_instance
'fastd'
383 for instance
in "$@"; do
384 config_get exists
"$instance" 'TYPE'
385 if [ "$exists" = 'fastd' ]; then
386 start_instance
"$instance"
395 for instance
in "$@"; do
396 config_get exists
"$instance" 'TYPE'
397 if [ "$exists" = 'fastd' ]; then
398 stop_instance
"$instance"
407 for instance
in "$@"; do
408 config_get exists
"$instance" 'TYPE'
409 if [ "$exists" = 'fastd' ]; then
410 show_key_instance
"$instance"
419 for instance
in "$@"; do
420 config_get exists
"$instance" 'TYPE'
421 if [ "$exists" = 'fastd' ]; then
422 generate_key_instance
"$instance"