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 "$ip6addr" -o "$ip6addr" != "${ip6addr%%[!A-Fa-f0-9.:]*}" ] && return 1
34 validate_ip6prefix() {
36 [ -z "$ip6prefix" -o "$ip6prefix" != "${ip6prefix%%[!A-Fa-f0-9./:]*}" ] && return 1
40 validate_radvd_string() {
42 [ -z "$radvd_string" -o "$radvd_string" != "${radvd_string%%[!a-z0-9.:_-]*}" ] && return 1
54 host) iproute2_scope=host ifconfig_scope=Host;;
55 link) iproute2_scope=link ifconfig_scope=Link;;
56 site) iproute2_scope=site ifconfig_scope=Site;;
57 global) iproute2_scope=global ifconfig_scope=Global;;
58 "") get_ip6addr "$ifname" global || get_ip6addr "$ifname" site; return;;
62 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)
63 if [ -z "$ip6addr" ]; then
64 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)
65 [ -z "$ip6addr" ] && return 1
68 printf '%s\n' "$ip6addr"
73 radvd_find_config_file() {
75 validate_varname "$cfg" || return 0
77 config_get_bool ignore "$cfg" ignore 0
78 [ "$ignore" -ne 0 ] && return 0
79 config_get RADVD_CONFIG_FILE "$cfg" config_file
84 radvd_add_interface() {
86 validate_varname "$cfg" || return 0
93 config_get_bool ignore "$cfg" ignore 0
94 [ "$ignore" -ne 0 ] && return 0
96 config_get interfaces "$cfg" interface
97 for interface in $interfaces; do
98 validate_varname "$interface" || continue
100 for list_interface in $RADVD_INTERFACES; do
101 [ "$interface" = "$list_interface" ] && exist=1
103 [ "$exist" -eq 0 ] && RADVD_INTERFACES="$RADVD_INTERFACES $interface"
109 radvd_write_interface() {
111 validate_varname "$cfg" || return 0
118 config_get_bool ignore "$cfg" ignore 0
119 [ "$ignore" -ne 0 ] && return 0
121 config_get interfaces "$cfg" interface
123 for interface in $interfaces; do
124 [ "$INTERFACE" = "$interface" ] && exist=1
126 [ "$exist" -eq 0 ] && return 0
128 for name in $RADVD_INTERFACE_STRING_OPTIONS; do
129 config_get value "$cfg" "$name"
130 validate_radvd_string "$value" || continue
131 printf '\t%s %s;\n' "$name" "$value"
134 for name in $RADVD_INTERFACE_BOOLEAN_OPTIONS; do
135 config_get value "$cfg" "$name"
136 [ -z "$value" ] && continue
137 config_get_bool value "$cfg" "$name" 0
138 if [ "$value" -ne 0 ]; then
139 printf '\t%s on;\n' "$name"
141 printf '\t%s off;\n' "$name"
145 config_get clients "$cfg" client
146 if [ -n "$clients" ]; then
147 printf '\n\tclients\n\t{\n'
149 for client in $clients; do
150 validate_ip6addr "$client" || continue
151 printf '\t\t%s;\n' "$client"
160 radvd_write_prefix() {
162 validate_varname "$cfg" || return 0
173 config_get_bool ignore "$cfg" ignore 0
174 [ "$ignore" -ne 0 ] && return 0
176 config_get interfaces "$cfg" interface
178 for interface in $interfaces; do
179 [ "$INTERFACE" = "$interface" ] && exist=1
181 [ "$exist" -eq 0 ] && return 0
183 config_get prefixes "$cfg" prefix
184 if [ -z "$prefixes" ]; then
185 prefixes=$(get_ip6addr "$IFNAME") || return 0
188 for prefix in $prefixes; do
189 validate_ip6prefix "$prefix" || continue
190 printf '\n\tprefix %s\n\t{\n' "$prefix"
192 for name in $RADVD_PREFIX_STRING_OPTIONS; do
193 config_get value "$cfg" "$name"
194 validate_radvd_string "$value" || continue
195 printf '\t\t%s %s;\n' "$name" "$value"
198 for name in $RADVD_PREFIX_BOOLEAN_OPTIONS; do
199 config_get value "$cfg" "$name"
200 [ -z "$value" ] && continue
201 config_get_bool value "$cfg" "$name" 0
202 if [ "$value" -ne 0 ]; then
203 printf '\t\t%s on;\n' "$name"
205 printf '\t\t%s off;\n' "$name"
209 config_get value "$cfg" Base6Interface
210 if [ -n "$value" ]; then
211 if network_get_device device "$value"; then
212 printf '\t\t%s %s;\n' "Base6Interface" "$device"
216 config_get value "$cfg" Base6to4Interface
217 if [ -n "$value" ]; then
218 if network_get_device device "$value"; then
219 printf '\t\t%s %s;\n' "Base6to4Interface" "$device"
229 radvd_write_route() {
231 validate_varname "$cfg" || return 0
240 config_get_bool ignore "$cfg" ignore 0
241 [ "$ignore" -ne 0 ] && return 0
243 config_get interfaces "$cfg" interface
245 for interface in $interfaces; do
246 [ "$INTERFACE" = "$interface" ] && exist=1
248 [ "$exist" -eq 0 ] && return 0
250 config_get prefixes "$cfg" prefix
251 for prefix in $prefixes; do
252 validate_ip6prefix "$prefix" || continue
253 printf '\n\troute %s\n\t{\n' "$prefix"
255 for name in $RADVD_ROUTE_STRING_OPTIONS; do
256 config_get value "$cfg" "$name"
257 validate_radvd_string "$value" || continue
258 printf '\t\t%s %s;\n' "$name" "$value"
261 for name in $RADVD_ROUTE_BOOLEAN_OPTIONS; do
262 config_get value "$cfg" "$name"
263 [ -z "$value" ] && continue
264 config_get_bool value "$cfg" "$name" 0
265 if [ "$value" -ne 0 ]; then
266 printf '\t\t%s on;\n' "$name"
268 printf '\t\t%s off;\n' "$name"
278 radvd_write_rdnss() {
280 validate_varname "$cfg" || return 0
291 config_get_bool ignore "$cfg" ignore 0
292 [ "$ignore" -ne 0 ] && return 0
294 config_get interfaces "$cfg" interface
296 for interface in $interfaces; do
297 [ "$INTERFACE" = "$interface" ] && exist=1
299 [ "$exist" -eq 0 ] && return 0
301 config_get addrs "$cfg" addr
303 for addr in $addrs; do
304 [ "$i" -ge 3 ] && break
305 validate_ip6addr "$addr" || continue
306 addr_list="$addr_list $addr"
310 if [ -z "$addr_list" ]; then
311 addr=$(get_ip6addr "$IFNAME" link) || return 0
312 addr_list=" ${addr%%[/]*}"
315 printf '\n\tRDNSS%s\n\t{\n' "$addr_list"
317 for name in $RADVD_RDNSS_STRING_OPTIONS; do
318 config_get value "$cfg" "$name"
319 validate_radvd_string "$value" || continue
320 printf '\t\t%s %s;\n' "$name" "$value"
328 radvd_write_dnssl() {
330 validate_varname "$cfg" || return 0
340 config_get_bool ignore "$cfg" ignore 0
341 [ "$ignore" -ne 0 ] && return 0
343 config_get interfaces "$cfg" interface
345 for interface in $interfaces; do
346 [ "$INTERFACE" = "$interface" ] && exist=1
348 [ "$exist" -eq 0 ] && return 0
350 config_get suffixes "$cfg" suffix
351 for suffix in $suffixes; do
352 validate_radvd_string "$suffix" || continue
353 suffix_list="$suffix_list $suffix"
356 printf '\n\tDNSSL%s\n\t{\n' "$suffix_list"
358 for name in $RADVD_DNSSL_STRING_OPTIONS; do
359 config_get value "$cfg" "$name"
360 validate_radvd_string "$value" || continue
361 printf '\t\t%s %s;\n' "$name" "$value"
369 radvd_write_config() {
370 . /lib/functions/network.sh
373 config_foreach radvd_add_interface interface
374 config_foreach radvd_add_interface prefix
375 config_foreach radvd_add_interface route
376 config_foreach radvd_add_interface RDNSS
377 config_foreach radvd_add_interface DNSSL
379 for INTERFACE in $RADVD_INTERFACES; do
380 network_get_device IFNAME "$INTERFACE" || continue
381 printf 'interface %s\n{\n' "$IFNAME"
382 config_foreach radvd_write_interface interface
383 config_foreach radvd_write_prefix prefix
384 config_foreach radvd_write_route route
385 config_foreach radvd_write_rdnss rdnss
386 config_foreach radvd_write_dnssl dnssl
397 config_foreach radvd_find_config_file radvd
399 if [ -z "$RADVD_CONFIG_FILE" ]; then
400 mkdir -p -- /var/etc/
401 radvd_write_config > /var/etc/radvd.conf
402 if [ -s "/var/etc/radvd.conf" ]; then
403 RADVD_CONFIG_FILE=/var/etc/radvd.conf
407 [ -z "$RADVD_CONFIG_FILE" ] && return 1
409 sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null 2> /dev/null
411 service_start /usr/sbin/radvd -C "$RADVD_CONFIG_FILE" -m stderr_syslog -p /var/run/radvd.pid
415 service_stop /usr/sbin/radvd