blob: 8823b97e74b604d1da325dfb4898f8375ce4075b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001#!/bin/sh /etc/rc.common
2# Copyright (C) 2011 OpenWrt.org
3# Copyright (C) 2011 Linus Lüssing
4# Based on Jo-Philipp Wich's OpenVPN init script
5# This is free software, licensed under the GNU General Public License v2.
6# See /LICENSE for more information.
7
8START=42
9
10SERVICE_USE_PID=1
11
12BIN=/usr/sbin/tincd
13if ( type extra_command >/dev/null 2>&1 ); then
14 extra_command "up" "<instance> Setting instance up"
15 extra_command "down" "<instance> Setting instance down"
16else
17 EXTRA_COMMANDS="up down"
18fi
19
20LIST_SEP="
21"
22TMP_TINC="/tmp/tinc"
23
24append_param() {
25 local v="$1"
26 case "$v" in
27 *_*_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
28 *_*_*) v=${v%%_*}-${v#*_}; v=${v%%_*}-${v#*_} ;;
29 *_*) v=${v%%_*}-${v#*_} ;;
30 esac
31 ARGS="$ARGS --$v"
32 return 0
33}
34
35append_conf_bools() {
36 local p; local v; local s="$1"; local f="$2"; shift; shift
37 for p in $*; do
38 config_get_bool v "$s" "$p"
39 [ "$v" == 1 ] && echo "$p = yes" >> "$f"
40 [ "$v" == 0 ] && echo "$p = no" >> "$f"
41 done
42}
43
44append_params() {
45 local p; local v; local s="$1"; shift
46 for p in $*; do
47 config_get v "$s" "$p"
48 IFS="$LIST_SEP"
49 for v in $v; do
50 [ -n "$v" ] && append_param "$p" && ARGS="$ARGS=$v"
51 done
52 unset IFS
53 done
54}
55
56append_conf_params() {
57 local p; local v; local s="$1"; local f="$2"; shift; shift
58 for p in $*; do
59 config_get v "$s" "$p"
60 IFS="$LIST_SEP"
61 for v in $v; do
62 # Look up OpenWRT interface names
63 [ "$p" = "BindToInterface" ] && {
64 local ifname=$(uci_get_state network "$v" ifname "")
65 [ -n "$ifname" ] && v="$ifname"
66 }
67
68 [ -n "$v" ] && echo "$p = $v" >> "$f"
69 done
70 unset IFS
71 done
72}
73
74section_enabled() {
75 config_get_bool enabled "$1" 'enabled' 0
76 [ $enabled -gt 0 ]
77}
78
79prepare_host() {
80 local s="$1"
81 local n
82
83 # net disabled?
84 config_get n "$s" net
85 section_enabled "$n" || return 1
86
87 if [ "$#" = "2" ]; then
88 [ "$2" != "$n" ] && return 1
89 fi
90
91 HOST_CONF_FILE="$TMP_TINC/$n/hosts/$s"
92 MANDATORY_PARAM_IN_UCI=0
93 [ ! -f "/etc/tinc/$n/hosts/$s" ] && {
94 config_get pk "$s" "PublicKey"
95 config_get na "$s" "Name"
96 if [ -n "$pk" -a -n "$na" ] ; then
97 HOST_CONF_FILE="$TMP_TINC/$n/hosts/$na"
98 MANDATORY_PARAM_IN_UCI=1
99 fi
100 }
101
102 # host disabled?
103 section_enabled "$s" || {
104 [ -f "$HOST_CONF_FILE" ] && rm "$HOST_CONF_FILE"
105 return 1
106 }
107
108 [ ! -f "/etc/tinc/$n/hosts/$s" ] && {
109 if [ "$MANDATORY_PARAM_IN_UCI" -eq 1 ] ; then
110 touch "$HOST_CONF_FILE" ;
111 else
112 echo -n "tinc: Warning, public key for $s for network $n "
113 echo -n "missing in /etc/tinc/$n/hosts/$s, "
114 echo "skipping configuration of $s"
115 return 1
116 fi
117 }
118
119 # append flags
120 append_conf_bools "$s" "$HOST_CONF_FILE" \
121 ClampMSS IndirectData PMTUDiscovery TCPOnly
122
123 # append params
124 append_conf_params "$s" "$HOST_CONF_FILE" \
125 Address Cipher Compression Digest Ed25519PublicKey MACLength Name PMTU \
126 Port PublicKey PublicKeyFile Subnet
127}
128
129check_gen_own_key() {
130 local s="$1"; local n; local k
131
132 config_get n "$s" Name
133 config_get_bool k "$s" generate_keys 0
134 [ "$k" == 0 ] && return 0
135
136 ([ -z "$n" ] || [ -f "$TMP_TINC/$s/hosts/$n" ] || [ -f "$TMP_TINC/$s/rsa_key.priv" ]) && \
137 return 0
138 [ ! -d "$TMP_TINC/$s/hosts" ] && mkdir -p "$TMP_TINC/$s/hosts"
139
140 config_get k "$s" key_size
141 if [ -z "$k" ]; then
142 $BIN -c "$TMP_TINC/$s" --generate-keys </dev/null
143 else
144 $BIN -c "$TMP_TINC/$s" "--generate-keys=$k" </dev/null
145 fi
146
147 [ ! -d "/etc/tinc/$s/hosts" ] && mkdir -p "/etc/tinc/$s/hosts"
148 cp "$TMP_TINC/$s/rsa_key.priv" "/etc/tinc/$s/"
149 [ -n "$n" ] && cp "$TMP_TINC/$s/hosts/$n" "/etc/tinc/$s/hosts/"
150}
151
152prepare_net() {
153 local s="$1"
154 local n
155
156 section_enabled "$s" || return 1
157
158 [ -d "$TMP_TINC/$s" ] && rm -rf "$TMP_TINC/$s/"
159 mkdir -p "$TMP_TINC/$s/hosts"
160 [ -d "/etc/tinc/$s" ] && cp -r "/etc/tinc/$s" "$TMP_TINC/"
161
162 # append flags
163 append_conf_bools "$s" "$TMP_TINC/$s/tinc.conf" \
164 AutoConnect \
165 DecrementTTL \
166 DeviceStandby \
167 DirectOnly \
168 ExperimentalProtocol \
169 Hostnames \
170 LocalDiscovery \
171 PriorityInheritance \
172 StrictSubnets \
173 TunnelServer \
174 ClampMSS \
175 IndirectData \
176 PMTUDiscovery \
177 TCPOnly
178
179 # append params
180 append_conf_params "$s" "$TMP_TINC/$s/tinc.conf" \
181 AddressFamily \
182 BindToAddress \
183 BindToInterface \
184 Broadcast \
185 BroadcastSubnet \
186 ConnectTo \
187 Device \
188 DeviceType \
189 Ed25519PrivateKeyFile \
190 ECDSAPublicKey \
191 Forwarding \
192 Interface \
193 ListenAddress \
194 LocalDiscoveryAddress \
195 Mode \
196 KeyExpire \
197 MACExpire \
198 MaxConnectionBurst \
199 Name \
200 PingInterval \
201 PingTimeout \
202 PrivateKey \
203 PrivateKeyFile \
204 ProcessPriority \
205 Proxy \
206 ReplayWindow \
207 UDPRcvBuf \
208 UDPSndBuf \
209 Address \
210 Cipher \
211 Compression \
212 Digest \
213 MACLength \
214 PMTU \
215 Port \
216 PublicKey \
217 PublicKeyFile \
218 Subnet \
219 Weight
220
221 check_gen_own_key "$s" && return 0
222}
223
224start_instance() {
225 local s="$1"
226
227 section_enabled "$s" || return 1
228
229 ARGS=""
230
231 # append params
232 append_params "$s" logfile debug
233
234 SERVICE_PID_FILE="/var/run/tinc.$s.pid"
235 service_start $BIN -c "$TMP_TINC/$s" $ARGS --pidfile="$SERVICE_PID_FILE"
236}
237
238stop_instance() {
239 local s="$1"
240
241 section_enabled "$s" || return 1
242
243 SERVICE_PID_FILE="/var/run/tinc.$s.pid"
244 service_stop $BIN
245 # rm old config
246 rm -rf "$TMP_TINC/$s/"
247}
248
249reload_instance() {
250 local s="$1"
251
252 section_enabled "$s" || return 1
253
254 SERVICE_PID_FILE="/var/run/tinc.$s.pid"
255 service_reload $BIN
256}
257
258start() {
259 config_load 'tinc'
260
261 config_foreach prepare_net 'tinc-net'
262 config_foreach prepare_host 'tinc-host'
263
264 config_foreach start_instance 'tinc-net'
265}
266
267stop() {
268 config_load 'tinc'
269 config_foreach stop_instance 'tinc-net'
270}
271
272reload() {
273 config_load 'tinc'
274 config_foreach reload_instance 'tinc-net'
275}
276
277up() {
278 local exists
279 local instance
280 config_load 'tinc'
281 for instance in "$@"; do
282 config_get exists "$instance" 'TYPE'
283 if [ "$exists" == "tinc-net" ]; then
284 prepare_net "$instance"
285 config_foreach prepare_host 'tinc-host' "$instance"
286 start_instance "$instance"
287 fi
288 done
289}
290
291down() {
292 local exists
293 local instance
294 config_load 'tinc'
295 for instance in "$@"; do
296 config_get exists "$instance" 'TYPE'
297 if [ "$exists" == "tinc-net" ]; then
298 stop_instance "$instance"
299 fi
300 done
301}