1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008-2011 OpenWrt.org
3 # Copyright (C) 2008 Alina Friedrichsen <x-alina@gmx.net>
9 RADVD_INTERFACE_STRING_OPTIONS='MaxRtrAdvInterval MinRtrAdvInterval MinDelayBetweenRAs AdvLinkMTU AdvReachableTime AdvRetransTimer AdvCurHopLimit AdvDefaultLifetime AdvDefaultPreference HomeAgentLifetime HomeAgentPreference'
10 RADVD_INTERFACE_BOOLEAN_OPTIONS='IgnoreIfMissing AdvSendAdvert UnicastOnly AdvManagedFlag AdvOtherConfigFlag AdvSourceLLAddress AdvHomeAgentFlag AdvHomeAgentInfo AdvMobRtrSupportFlag AdvIntervalOpt'
12 RADVD_PREFIX_STRING_OPTIONS='AdvValidLifetime AdvPreferredLifetime'
13 RADVD_PREFIX_BOOLEAN_OPTIONS='AdvOnLink AdvAutonomous AdvRouterAddr DeprecatePrefix DecrementLifetimes'
15 RADVD_ROUTE_STRING_OPTIONS='AdvRouteLifetime AdvRoutePreference'
16 RADVD_ROUTE_BOOLEAN_OPTIONS='RemoveRoute'
18 RADVD_RDNSS_STRING_OPTIONS='AdvRDNSSLifetime FlushRDNSS'
20 RADVD_DNSSL_STRING_OPTIONS='AdvDNSSLLifetime FlushDNSSL'
24 [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
30 [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
36 [ -z "$ip6addr" -o "$ip6addr" != "${ip6addr%%[!A-Fa-f0-9.:]*}" ] && return 1
40 validate_ip6prefix() {
42 [ -z "$ip6prefix" -o "$ip6prefix" != "${ip6prefix%%[!A-Fa-f0-9./:]*}" ] && return 1
46 validate_radvd_string() {
48 [ -z "$radvd_string" -o "$radvd_string" != "${radvd_string%%[!a-z0-9.:_-]*}" ] && return 1
54 validate_varname "$interface" || return 1
59 config_get cfgt "$interface" TYPE
60 [ "$cfgt" != "interface" ] && return 1
61 config_get ifname "$interface" ifname
62 validate_ifname "$ifname" || return 1
63 printf '%s\n' "$ifname"
76 host) iproute2_scope=host ifconfig_scope=Host;;
77 link) iproute2_scope=link ifconfig_scope=Link;;
78 site) iproute2_scope=site ifconfig_scope=Site;;
79 global) iproute2_scope=global ifconfig_scope=Global;;
80 "") get_ip6addr "$ifname" global || get_ip6addr "$ifname" site; return;;
84 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)
85 if [ -z "$ip6addr" ]; then
86 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)
87 [ -z "$ip6addr" ] && return 1
90 printf '%s\n' "$ip6addr"
95 radvd_find_config_file() {
97 validate_varname "$cfg" || return 0
99 config_get_bool ignore "$cfg" ignore 0
100 [ "$ignore" -ne 0 ] && return 0
101 config_get RADVD_CONFIG_FILE "$cfg" config_file
106 radvd_add_interface() {
108 validate_varname "$cfg" || return 0
115 config_get_bool ignore "$cfg" ignore 0
116 [ "$ignore" -ne 0 ] && return 0
118 config_get interfaces "$cfg" interface
119 for interface in $interfaces; do
120 validate_varname "$interface" || continue
122 for list_interface in $RADVD_INTERFACES; do
123 [ "$interface" = "$list_interface" ] && exist=1
125 [ "$exist" -eq 0 ] && RADVD_INTERFACES="$RADVD_INTERFACES $interface"
131 radvd_write_interface() {
133 validate_varname "$cfg" || return 0
140 config_get_bool ignore "$cfg" ignore 0
141 [ "$ignore" -ne 0 ] && return 0
143 config_get interfaces "$cfg" interface
145 for interface in $interfaces; do
146 [ "$INTERFACE" = "$interface" ] && exist=1
148 [ "$exist" -eq 0 ] && return 0
150 for name in $RADVD_INTERFACE_STRING_OPTIONS; do
151 config_get value "$cfg" "$name"
152 validate_radvd_string "$value" || continue
153 printf '\t%s %s;\n' "$name" "$value"
156 for name in $RADVD_INTERFACE_BOOLEAN_OPTIONS; do
157 config_get value "$cfg" "$name"
158 [ -z "$value" ] && continue
159 config_get_bool value "$cfg" "$name" 0
160 if [ "$value" -ne 0 ]; then
161 printf '\t%s on;\n' "$name"
163 printf '\t%s off;\n' "$name"
167 config_get clients "$cfg" client
168 if [ -n "$clients" ]; then
169 printf '\n\tclients\n\t{\n'
171 for client in $clients; do
172 validate_ip6addr "$client" || continue
173 printf '\t\t%s;\n' "$client"
182 radvd_write_prefix() {
184 validate_varname "$cfg" || return 0
194 config_get_bool ignore "$cfg" ignore 0
195 [ "$ignore" -ne 0 ] && return 0
197 config_get interfaces "$cfg" interface
199 for interface in $interfaces; do
200 [ "$INTERFACE" = "$interface" ] && exist=1
202 [ "$exist" -eq 0 ] && return 0
204 config_get prefixes "$cfg" prefix
205 if [ -z "$prefixes" ]; then
206 prefixes=$(get_ip6addr "$IFNAME") || return 0
209 for prefix in $prefixes; do
210 validate_ip6prefix "$prefix" || continue
211 printf '\n\tprefix %s\n\t{\n' "$prefix"
213 for name in $RADVD_PREFIX_STRING_OPTIONS; do
214 config_get value "$cfg" "$name"
215 validate_radvd_string "$value" || continue
216 printf '\t\t%s %s;\n' "$name" "$value"
219 for name in $RADVD_PREFIX_BOOLEAN_OPTIONS; do
220 config_get value "$cfg" "$name"
221 [ -z "$value" ] && continue
222 config_get_bool value "$cfg" "$name" 0
223 if [ "$value" -ne 0 ]; then
224 printf '\t\t%s on;\n' "$name"
226 printf '\t\t%s off;\n' "$name"
230 config_get value "$cfg" Base6Interface
231 if [ -n "$value" ]; then
232 if ifname=$(get_ifname "$value"); then
233 printf '\t\t%s %s;\n' "Base6Interface" "$ifname"
237 config_get value "$cfg" Base6to4Interface
238 if [ -n "$value" ]; then
239 if ifname=$(get_ifname "$value"); then
240 printf '\t\t%s %s;\n' "Base6to4Interface" "$ifname"
250 radvd_write_route() {
252 validate_varname "$cfg" || return 0
261 config_get_bool ignore "$cfg" ignore 0
262 [ "$ignore" -ne 0 ] && return 0
264 config_get interfaces "$cfg" interface
266 for interface in $interfaces; do
267 [ "$INTERFACE" = "$interface" ] && exist=1
269 [ "$exist" -eq 0 ] && return 0
271 config_get prefixes "$cfg" prefix
272 for prefix in $prefixes; do
273 validate_ip6prefix "$prefix" || continue
274 printf '\n\troute %s\n\t{\n' "$prefix"
276 for name in $RADVD_ROUTE_STRING_OPTIONS; do
277 config_get value "$cfg" "$name"
278 validate_radvd_string "$value" || continue
279 printf '\t\t%s %s;\n' "$name" "$value"
282 for name in $RADVD_ROUTE_BOOLEAN_OPTIONS; do
283 config_get value "$cfg" "$name"
284 [ -z "$value" ] && continue
285 config_get_bool value "$cfg" "$name" 0
286 if [ "$value" -ne 0 ]; then
287 printf '\t\t%s on;\n' "$name"
289 printf '\t\t%s off;\n' "$name"
299 radvd_write_rdnss() {
301 validate_varname "$cfg" || return 0
312 config_get_bool ignore "$cfg" ignore 0
313 [ "$ignore" -ne 0 ] && return 0
315 config_get interfaces "$cfg" interface
317 for interface in $interfaces; do
318 [ "$INTERFACE" = "$interface" ] && exist=1
320 [ "$exist" -eq 0 ] && return 0
322 config_get addrs "$cfg" addr
324 for addr in $addrs; do
325 [ "$i" -ge 3 ] && break
326 validate_ip6addr "$addr" || continue
327 addr_list="$addr_list $addr"
331 if [ -z "$addr_list" ]; then
332 addr=$(get_ip6addr "$IFNAME" link) || return 0
333 addr_list=" ${addr%%[/]*}"
336 printf '\n\tRDNSS%s\n\t{\n' "$addr_list"
338 for name in $RADVD_RDNSS_STRING_OPTIONS; do
339 config_get value "$cfg" "$name"
340 validate_radvd_string "$value" || continue
341 printf '\t\t%s %s;\n' "$name" "$value"
349 radvd_write_dnssl() {
351 validate_varname "$cfg" || return 0
361 config_get_bool ignore "$cfg" ignore 0
362 [ "$ignore" -ne 0 ] && return 0
364 config_get interfaces "$cfg" interface
366 for interface in $interfaces; do
367 [ "$INTERFACE" = "$interface" ] && exist=1
369 [ "$exist" -eq 0 ] && return 0
371 config_get suffixes "$cfg" suffix
372 for suffix in $suffixes; do
373 validate_radvd_string "$suffix" || continue
374 suffix_list="$suffix_list $suffix"
377 printf '\n\tDNSSL%s\n\t{\n' "$suffix_list"
379 for name in $RADVD_DNSSL_STRING_OPTIONS; do
380 config_get value "$cfg" "$name"
381 validate_radvd_string "$value" || continue
382 printf '\t\t%s %s;\n' "$name" "$value"
390 radvd_write_config() {
394 config_foreach radvd_add_interface interface
395 config_foreach radvd_add_interface prefix
396 config_foreach radvd_add_interface route
397 config_foreach radvd_add_interface RDNSS
398 config_foreach radvd_add_interface DNSSL
400 for INTERFACE in $RADVD_INTERFACES; do
401 IFNAME=$(get_ifname "$INTERFACE") || continue
402 printf 'interface %s\n{\n' "$IFNAME"
403 config_foreach radvd_write_interface interface
404 config_foreach radvd_write_prefix prefix
405 config_foreach radvd_write_route route
406 config_foreach radvd_write_rdnss rdnss
407 config_foreach radvd_write_dnssl dnssl
418 config_foreach radvd_find_config_file radvd
420 if [ -z "$RADVD_CONFIG_FILE" ]; then
421 mkdir -p -- /var/etc/
422 radvd_write_config > /var/etc/radvd.conf
423 if [ -s "/var/etc/radvd.conf" ]; then
424 RADVD_CONFIG_FILE=/var/etc/radvd.conf
428 [ -z "$RADVD_CONFIG_FILE" ] && return 1
430 sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null 2> /dev/null
432 service_start /usr/sbin/radvd -C "$RADVD_CONFIG_FILE" -m stderr_syslog -p /var/run/radvd.pid
436 service_stop /usr/sbin/radvd