[packages] radvd: add new 1.8 options, split radvdump into a separate package
[openwrt/svn-archive/archive.git] / ipv6 / radvd / files / radvd.init
1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008 Alina Friedrichsen <x-alina@gmx.net>
3 START=50
4
5 RADVD_INTERFACE_STRING_OPTIONS='MaxRtrAdvInterval MinRtrAdvInterval MinDelayBetweenRAs AdvLinkMTU AdvReachableTime AdvRetransTimer AdvCurHopLimit AdvDefaultLifetime AdvDefaultPreference HomeAgentLifetime HomeAgentPreference'
6 RADVD_INTERFACE_BOOLEAN_OPTIONS='IgnoreIfMissing AdvSendAdvert UnicastOnly AdvManagedFlag AdvOtherConfigFlag AdvSourceLLAddress AdvHomeAgentFlag AdvHomeAgentInfo AdvMobRtrSupportFlag AdvIntervalOpt'
7
8 RADVD_PREFIX_STRING_OPTIONS='AdvValidLifetime AdvPreferredLifetime'
9 RADVD_PREFIX_BOOLEAN_OPTIONS='AdvOnLink AdvAutonomous AdvRouterAddr DeprecatePrefix DecrementLifetimes'
10
11 RADVD_ROUTE_STRING_OPTIONS='AdvRouteLifetime AdvRoutePreference'
12 RADVD_ROUTE_BOOLEAN_OPTIONS='RemoveRoute'
13
14 RADVD_RDNSS_STRING_OPTIONS='AdvRDNSSLifetime FlushRDNSS'
15
16 RADVD_DNSSL_STRING_OPTIONS='AdvDNSSLLifetime FlushDNSSL'
17
18 validate_varname() {
19 local varname=$1
20 [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
21 return 0
22 }
23
24 validate_ifname() {
25 local ifname=$1
26 [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
27 return 0
28 }
29
30 validate_ip6addr() {
31 local ip6addr=$1
32 [ -z "$ip6addr" -o "$ip6addr" != "${ip6addr%%[!A-Fa-f0-9.:]*}" ] && return 1
33 return 0
34 }
35
36 validate_ip6prefix() {
37 local ip6prefix=$1
38 [ -z "$ip6prefix" -o "$ip6prefix" != "${ip6prefix%%[!A-Fa-f0-9./:]*}" ] && return 1
39 return 0
40 }
41
42 validate_radvd_string() {
43 local radvd_string=$1
44 [ -z "$radvd_string" -o "$radvd_string" != "${radvd_string%%[!a-z0-9.:_-]*}" ] && return 1
45 return 0
46 }
47
48 get_ifname() {
49 local interface=$1
50 validate_varname "$interface" || return 1
51 local cfgt
52 local ifname
53
54 scan_interfaces
55 config_get cfgt "$interface" TYPE
56 [ "$cfgt" != "interface" ] && return 1
57 config_get ifname "$interface" ifname
58 validate_ifname "$ifname" || return 1
59 printf '%s\n' "$ifname"
60
61 return 0
62 }
63
64 get_ip6addr() {
65 local ifname=$1
66 local scope=$2
67 local iproute2_scope
68 local ifconfig_scope
69 local ip6addr
70
71 case "$scope" in
72 host) iproute2_scope=host ifconfig_scope=Host;;
73 link) iproute2_scope=link ifconfig_scope=Link;;
74 site) iproute2_scope=site ifconfig_scope=Site;;
75 global) iproute2_scope=global ifconfig_scope=Global;;
76 "") get_ip6addr "$ifname" global || get_ip6addr "$ifname" site; return;;
77 *) return 1;;
78 esac
79
80 ip6addr=$(LANG=C ip -f inet6 -- addr show dev "$ifname" 2> /dev/null | sed -n -e 's/^ *inet6 \([A-Fa-f0-9.:]*[/][0-9]*\) scope '"$iproute2_scope"' $/\1/p' | head -n 1)
81 if [ -z "$ip6addr" ]; then
82 ip6addr=$(LANG=C ifconfig "$ifname" 2> /dev/null | sed -n -e 's/^ *inet6 addr: \([A-Fa-f0-9.:]*[/][0-9]*\) Scope:'"$ifconfig_scope"'$/\1/p' | tail -n 1)
83 [ -z "$ip6addr" ] && return 1
84 fi
85
86 printf '%s\n' "$ip6addr"
87
88 return 0
89 }
90
91 radvd_find_config_file() {
92 local cfg=$1
93 validate_varname "$cfg" || return 0
94
95 config_get_bool ignore "$cfg" ignore 0
96 [ "$ignore" -ne 0 ] && return 0
97 config_get RADVD_CONFIG_FILE "$cfg" config_file
98
99 return 0
100 }
101
102 radvd_add_interface() {
103 local cfg=$1
104 validate_varname "$cfg" || return 0
105 local ignore
106 local interfaces
107 local interface
108 local list_interface
109 local exist
110
111 config_get_bool ignore "$cfg" ignore 0
112 [ "$ignore" -ne 0 ] && return 0
113
114 config_get interfaces "$cfg" interface
115 for interface in $interfaces; do
116 validate_varname "$interface" || continue
117 exist=0
118 for list_interface in $RADVD_INTERFACES; do
119 [ "$interface" = "$list_interface" ] && exist=1
120 done
121 [ "$exist" -eq 0 ] && RADVD_INTERFACES="$RADVD_INTERFACES $interface"
122 done
123
124 return 0
125 }
126
127 radvd_write_interface() {
128 local cfg=$1
129 validate_varname "$cfg" || return 0
130 local ignore
131 local interfaces
132 local interface
133 local name
134 local value
135
136 config_get_bool ignore "$cfg" ignore 0
137 [ "$ignore" -ne 0 ] && return 0
138
139 config_get interfaces "$cfg" interface
140 exist=0
141 for interface in $interfaces; do
142 [ "$INTERFACE" = "$interface" ] && exist=1
143 done
144 [ "$exist" -eq 0 ] && return 0
145
146 for name in $RADVD_INTERFACE_STRING_OPTIONS; do
147 config_get value "$cfg" "$name"
148 validate_radvd_string "$value" || continue
149 printf '\t%s %s;\n' "$name" "$value"
150 done
151
152 for name in $RADVD_INTERFACE_BOOLEAN_OPTIONS; do
153 config_get value "$cfg" "$name"
154 [ -z "$value" ] && continue
155 config_get_bool value "$cfg" "$name" 0
156 if [ "$value" -ne 0 ]; then
157 printf '\t%s on;\n' "$name"
158 else
159 printf '\t%s off;\n' "$name"
160 fi
161 done
162
163 config_get clients "$cfg" client
164 if [ -n "$clients" ]; then
165 printf '\n\tclients\n\t{\n'
166
167 for client in $clients; do
168 validate_ip6addr "$client" || continue
169 printf '\t\t%s;\n' "$client"
170 done
171
172 printf '\t};\n'
173 fi
174
175 return 0
176 }
177
178 radvd_write_prefix() {
179 local cfg=$1
180 validate_varname "$cfg" || return 0
181 local ignore
182 local interfaces
183 local interface
184 local prefixes
185 local prefix
186 local name
187 local value
188 local cfgt
189
190 config_get_bool ignore "$cfg" ignore 0
191 [ "$ignore" -ne 0 ] && return 0
192
193 config_get interfaces "$cfg" interface
194 exist=0
195 for interface in $interfaces; do
196 [ "$INTERFACE" = "$interface" ] && exist=1
197 done
198 [ "$exist" -eq 0 ] && return 0
199
200 config_get prefixes "$cfg" prefix
201 if [ -z "$prefixes" ]; then
202 prefixes=$(get_ip6addr "$IFNAME") || return 0
203 fi
204
205 for prefix in $prefixes; do
206 validate_ip6prefix "$prefix" || continue
207 printf '\n\tprefix %s\n\t{\n' "$prefix"
208
209 for name in $RADVD_PREFIX_STRING_OPTIONS; do
210 config_get value "$cfg" "$name"
211 validate_radvd_string "$value" || continue
212 printf '\t\t%s %s;\n' "$name" "$value"
213 done
214
215 for name in $RADVD_PREFIX_BOOLEAN_OPTIONS; do
216 config_get value "$cfg" "$name"
217 [ -z "$value" ] && continue
218 config_get_bool value "$cfg" "$name" 0
219 if [ "$value" -ne 0 ]; then
220 printf '\t\t%s on;\n' "$name"
221 else
222 printf '\t\t%s off;\n' "$name"
223 fi
224 done
225
226 config_get value "$cfg" Base6Interface
227 if [ -n "$value" ]; then
228 if ifname=$(get_ifname "$value"); then
229 printf '\t\t%s %s;\n' "Base6Interface" "$ifname"
230 fi
231 fi
232
233 config_get value "$cfg" Base6to4Interface
234 if [ -n "$value" ]; then
235 if ifname=$(get_ifname "$value"); then
236 printf '\t\t%s %s;\n' "Base6to4Interface" "$ifname"
237 fi
238 fi
239
240 printf '\t};\n'
241 done
242
243 return 0
244 }
245
246 radvd_write_route() {
247 local cfg=$1
248 validate_varname "$cfg" || return 0
249 local ignore
250 local interfaces
251 local interface
252 local prefixes
253 local prefix
254 local name
255 local value
256
257 config_get_bool ignore "$cfg" ignore 0
258 [ "$ignore" -ne 0 ] && return 0
259
260 config_get interfaces "$cfg" interface
261 exist=0
262 for interface in $interfaces; do
263 [ "$INTERFACE" = "$interface" ] && exist=1
264 done
265 [ "$exist" -eq 0 ] && return 0
266
267 config_get prefixes "$cfg" prefix
268 for prefix in $prefixes; do
269 validate_ip6prefix "$prefix" || continue
270 printf '\n\troute %s\n\t{\n' "$prefix"
271
272 for name in $RADVD_ROUTE_STRING_OPTIONS; do
273 config_get value "$cfg" "$name"
274 validate_radvd_string "$value" || continue
275 printf '\t\t%s %s;\n' "$name" "$value"
276 done
277
278 for name in $RADVD_ROUTE_BOOLEAN_OPTIONS; do
279 config_get value "$cfg" "$name"
280 [ -z "$value" ] && continue
281 config_get_bool value "$cfg" "$name" 0
282 if [ "$value" -ne 0 ]; then
283 printf '\t\t%s on;\n' "$name"
284 else
285 printf '\t\t%s off;\n' "$name"
286 fi
287 done
288
289 printf '\t};\n'
290 done
291
292 return 0
293 }
294
295 radvd_write_rdnss() {
296 local cfg=$1
297 validate_varname "$cfg" || return 0
298 local ignore
299 local interfaces
300 local interface
301 local addrs
302 local addr
303 local addr_list
304 local name
305 local value
306 local i
307
308 config_get_bool ignore "$cfg" ignore 0
309 [ "$ignore" -ne 0 ] && return 0
310
311 config_get interfaces "$cfg" interface
312 exist=0
313 for interface in $interfaces; do
314 [ "$INTERFACE" = "$interface" ] && exist=1
315 done
316 [ "$exist" -eq 0 ] && return 0
317
318 config_get addrs "$cfg" addr
319 i=0
320 for addr in $addrs; do
321 [ "$i" -ge 3 ] && break
322 validate_ip6addr "$addr" || continue
323 addr_list="$addr_list $addr"
324 i=$(($i+1))
325 done
326
327 if [ -z "$addr_list" ]; then
328 addr=$(get_ip6addr "$IFNAME" link) || return 0
329 addr_list=" ${addr%%[/]*}"
330 fi
331
332 printf '\n\tRDNSS%s\n\t{\n' "$addr_list"
333
334 for name in $RADVD_RDNSS_STRING_OPTIONS; do
335 config_get value "$cfg" "$name"
336 validate_radvd_string "$value" || continue
337 printf '\t\t%s %s;\n' "$name" "$value"
338 done
339
340 printf '\t};\n'
341
342 return 0
343 }
344
345 radvd_write_dnssl() {
346 local cfg=$1
347 validate_varname "$cfg" || return 0
348 local ignore
349 local interfaces
350 local interface
351 local suffixes
352 local suffix
353 local suffix_list
354 local name
355 local value
356
357 config_get_bool ignore "$cfg" ignore 0
358 [ "$ignore" -ne 0 ] && return 0
359
360 config_get interfaces "$cfg" interface
361 exist=0
362 for interface in $interfaces; do
363 [ "$INTERFACE" = "$interface" ] && exist=1
364 done
365 [ "$exist" -eq 0 ] && return 0
366
367 config_get suffixes "$cfg" suffix
368 for suffix in $suffixes; do
369 validate_radvd_string "$suffix" || continue
370 suffix_list="$suffix_list $suffix"
371 done
372
373 printf '\n\tDNSSL%s\n\t{\n' "$suffix_list"
374
375 for name in $RADVD_DNSSL_STRING_OPTIONS; do
376 config_get value "$cfg" "$name"
377 validate_radvd_string "$value" || continue
378 printf '\t\t%s %s;\n' "$name" "$value"
379 done
380
381 printf '\t};\n'
382
383 return 0
384 }
385
386 radvd_write_config() {
387 include /lib/network
388
389 RADVD_INTERFACES=
390 config_foreach radvd_add_interface interface
391 config_foreach radvd_add_interface prefix
392 config_foreach radvd_add_interface route
393 config_foreach radvd_add_interface RDNSS
394 config_foreach radvd_add_interface DNSSL
395
396 for INTERFACE in $RADVD_INTERFACES; do
397 IFNAME=$(get_ifname "$INTERFACE") || continue
398 printf 'interface %s\n{\n' "$IFNAME"
399 config_foreach radvd_write_interface interface
400 config_foreach radvd_write_prefix prefix
401 config_foreach radvd_write_route route
402 config_foreach radvd_write_rdnss rdnss
403 config_foreach radvd_write_dnssl dnssl
404 printf '};\n\n'
405 done
406
407 return 0
408 }
409
410 start() {
411 config_load radvd
412
413 RADVD_CONFIG_FILE=
414 config_foreach radvd_find_config_file radvd
415
416 if [ -z "$RADVD_CONFIG_FILE" ]; then
417 mkdir -p -- /var/etc/
418 radvd_write_config > /var/etc/radvd.conf
419 if [ -s "/var/etc/radvd.conf" ]; then
420 RADVD_CONFIG_FILE=/var/etc/radvd.conf
421 fi
422 fi
423
424 [ -z "$RADVD_CONFIG_FILE" ] && return 1
425
426 sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null 2> /dev/null
427
428 radvd -C "$RADVD_CONFIG_FILE" -m stderr_syslog -p /var/run/radvd.pid
429 }
430
431 stop() {
432 killall radvd
433 }