1 #!/bin/sh /etc/rc.common
2 # Copyright (C) 2008 Alina Friedrichsen <x-alina@gmx.net>
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'
8 RADVD_PREFIX_STRING_OPTIONS='AdvValidLifetime AdvPreferredLifetime'
9 RADVD_PREFIX_BOOLEAN_OPTIONS='AdvOnLink AdvAutonomous AdvRouterAddr'
11 RADVD_ROUTE_STRING_OPTIONS='AdvRouteLifetime AdvRoutePreference'
13 RADVD_RDNSS_STRING_OPTIONS='AdvRDNSSLifetime'
15 RADVD_DNSSL_STRING_OPTIONS='AdvDNSSLLifetime'
19 [ -z "$varname" -o "$varname" != "${varname%%[!A-Za-z0-9_]*}" ] && return 1
25 [ -z "$ifname" -o "$ifname" != "${ifname%%[!A-Za-z0-9.:_-]*}" ] && return 1
31 [ -z "$ip6addr" -o "$ip6addr" != "${ip6addr%%[!A-Fa-f0-9.:]*}" ] && return 1
35 validate_ip6prefix() {
37 [ -z "$ip6prefix" -o "$ip6prefix" != "${ip6prefix%%[!A-Fa-f0-9./:]*}" ] && return 1
41 validate_radvd_string() {
43 [ -z "$radvd_string" -o "$radvd_string" != "${radvd_string%%[!a-z0-9.:_-]*}" ] && return 1
49 validate_varname "$interface" || return 1
54 config_get cfgt "$interface" TYPE
55 [ "$cfgt" != "interface" ] && return 1
56 config_get ifname "$interface" ifname
57 validate_ifname "$ifname" || return 1
58 printf '%s\n' "$ifname"
71 host) iproute2_scope=host ifconfig_scope=Host;;
72 link) iproute2_scope=link ifconfig_scope=Link;;
73 site) iproute2_scope=site ifconfig_scope=Site;;
74 global) iproute2_scope=global ifconfig_scope=Global;;
75 "") get_ip6addr "$ifname" global || get_ip6addr "$ifname" site; return;;
79 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)
80 if [ -z "$ip6addr" ]; then
81 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)
82 [ -z "$ip6addr" ] && return 1
85 printf '%s\n' "$ip6addr"
90 radvd_find_config_file() {
92 validate_varname "$cfg" || return 0
94 config_get_bool ignore "$cfg" ignore 0
95 [ "$ignore" -ne 0 ] && return 0
96 config_get RADVD_CONFIG_FILE "$cfg" config_file
101 radvd_add_interface() {
103 validate_varname "$cfg" || return 0
110 config_get_bool ignore "$cfg" ignore 0
111 [ "$ignore" -ne 0 ] && return 0
113 config_get interfaces "$cfg" interface
114 for interface in $interfaces; do
115 validate_varname "$interface" || continue
117 for list_interface in $RADVD_INTERFACES; do
118 [ "$interface" = "$list_interface" ] && exist=1
120 [ "$exist" -eq 0 ] && RADVD_INTERFACES="$RADVD_INTERFACES $interface"
126 radvd_write_interface() {
128 validate_varname "$cfg" || return 0
135 config_get_bool ignore "$cfg" ignore 0
136 [ "$ignore" -ne 0 ] && return 0
138 config_get interfaces "$cfg" interface
140 for interface in $interfaces; do
141 [ "$INTERFACE" = "$interface" ] && exist=1
143 [ "$exist" -eq 0 ] && return 0
145 for name in $RADVD_INTERFACE_STRING_OPTIONS; do
146 config_get value "$cfg" "$name"
147 validate_radvd_string "$value" || continue
148 printf '\t%s %s;\n' "$name" "$value"
151 for name in $RADVD_INTERFACE_BOOLEAN_OPTIONS; do
152 config_get value "$cfg" "$name"
153 [ -z "$value" ] && continue
154 config_get_bool value "$cfg" "$name" 0
155 if [ "$value" -ne 0 ]; then
156 printf '\t%s on;\n' "$name"
158 printf '\t%s off;\n' "$name"
165 radvd_write_prefix() {
167 validate_varname "$cfg" || return 0
177 config_get_bool ignore "$cfg" ignore 0
178 [ "$ignore" -ne 0 ] && return 0
180 config_get interfaces "$cfg" interface
182 for interface in $interfaces; do
183 [ "$INTERFACE" = "$interface" ] && exist=1
185 [ "$exist" -eq 0 ] && return 0
187 config_get prefixes "$cfg" prefix
188 if [ -z "$prefixes" ]; then
189 prefixes=$(get_ip6addr "$IFNAME") || return 0
192 for prefix in $prefixes; do
193 validate_ip6prefix "$prefix" || continue
194 printf '\n\tprefix %s\n\t{\n' "$prefix"
196 for name in $RADVD_PREFIX_STRING_OPTIONS; do
197 config_get value "$cfg" "$name"
198 validate_radvd_string "$value" || continue
199 printf '\t\t%s %s;\n' "$name" "$value"
202 for name in $RADVD_PREFIX_BOOLEAN_OPTIONS; do
203 config_get value "$cfg" "$name"
204 [ -z "$value" ] && continue
205 config_get_bool value "$cfg" "$name" 0
206 if [ "$value" -ne 0 ]; then
207 printf '\t\t%s on;\n' "$name"
209 printf '\t\t%s off;\n' "$name"
213 config_get value "$cfg" Base6to4Interface
214 if [ -n "$value" ]; then
215 if ifname=$(get_ifname "$value"); then
216 printf '\t\t%s %s;\n' "Base6to4Interface" "$ifname"
226 radvd_write_route() {
228 validate_varname "$cfg" || return 0
237 config_get_bool ignore "$cfg" ignore 0
238 [ "$ignore" -ne 0 ] && return 0
240 config_get interfaces "$cfg" interface
242 for interface in $interfaces; do
243 [ "$INTERFACE" = "$interface" ] && exist=1
245 [ "$exist" -eq 0 ] && return 0
247 config_get prefixes "$cfg" prefix
248 for prefix in $prefixes; do
249 validate_ip6prefix "$prefix" || continue
250 printf '\n\troute %s\n\t{\n' "$prefix"
252 for name in $RADVD_ROUTE_STRING_OPTIONS; do
253 config_get value "$cfg" "$name"
254 validate_radvd_string "$value" || continue
255 printf '\t\t%s %s;\n' "$name" "$value"
264 radvd_write_rdnss() {
266 validate_varname "$cfg" || return 0
277 config_get_bool ignore "$cfg" ignore 0
278 [ "$ignore" -ne 0 ] && return 0
280 config_get interfaces "$cfg" interface
282 for interface in $interfaces; do
283 [ "$INTERFACE" = "$interface" ] && exist=1
285 [ "$exist" -eq 0 ] && return 0
287 config_get addrs "$cfg" addr
289 for addr in $addrs; do
290 [ "$i" -ge 3 ] && break
291 validate_ip6addr "$addr" || continue
292 addr_list="$addr_list $addr"
296 if [ -z "$addr_list" ]; then
297 addr=$(get_ip6addr "$IFNAME" link) || return 0
298 addr_list=" ${addr%%[/]*}"
301 printf '\n\tRDNSS%s\n\t{\n' "$addr_list"
303 for name in $RADVD_RDNSS_STRING_OPTIONS; do
304 config_get value "$cfg" "$name"
305 validate_radvd_string "$value" || continue
306 printf '\t\t%s %s;\n' "$name" "$value"
314 radvd_write_dnssl() {
316 validate_varname "$cfg" || return 0
326 config_get_bool ignore "$cfg" ignore 0
327 [ "$ignore" -ne 0 ] && return 0
329 config_get interfaces "$cfg" interface
331 for interface in $interfaces; do
332 [ "$INTERFACE" = "$interface" ] && exist=1
334 [ "$exist" -eq 0 ] && return 0
336 config_get suffixes "$cfg" suffix
337 for suffix in $suffixes; do
338 validate_radvd_string "$suffix" || continue
339 suffix_list="$suffix_list $suffix"
342 printf '\n\tDNSSL%s\n\t{\n' "$suffix_list"
344 for name in $RADVD_DNSSL_STRING_OPTIONS; do
345 config_get value "$cfg" "$name"
346 validate_radvd_string "$value" || continue
347 printf '\t\t%s %s;\n' "$name" "$value"
355 radvd_write_clients() {
357 validate_varname "$cfg" || return 0
364 config_get_bool ignore "$cfg" ignore 0
365 [ "$ignore" -ne 0 ] && return 0
367 config_get interfaces "$cfg" interface
369 for interface in $interfaces; do
370 [ "$INTERFACE" = "$interface" ] && exist=1
372 [ "$exist" -eq 0 ] && return 0
374 printf '\n\tclients\n\t{\n'
376 config_get clients "$cfg" client
377 for client in $clients; do
378 validate_ip6addr "$client" || continue
379 printf '\t\t%s;\n' "$client"
387 radvd_write_config() {
391 config_foreach radvd_add_interface interface
392 config_foreach radvd_add_interface prefix
393 config_foreach radvd_add_interface route
394 config_foreach radvd_add_interface RDNSS
395 config_foreach radvd_add_interface DNSSL
396 config_foreach radvd_add_interface clients
398 for INTERFACE in $RADVD_INTERFACES; do
399 IFNAME=$(get_ifname "$INTERFACE") || continue
400 printf 'interface %s\n{\n' "$IFNAME"
401 config_foreach radvd_write_interface interface
402 config_foreach radvd_write_prefix prefix
403 config_foreach radvd_write_route route
404 config_foreach radvd_write_rdnss rdnss
405 config_foreach radvd_write_dnssl dnssl
406 config_foreach radvd_write_clients clients
417 config_foreach radvd_find_config_file radvd
419 if [ -z "$RADVD_CONFIG_FILE" ]; then
420 mkdir -p -- /var/etc/
421 radvd_write_config > /var/etc/radvd.conf
422 if [ -s "/var/etc/radvd.conf" ]; then
423 RADVD_CONFIG_FILE=/var/etc/radvd.conf
427 [ -z "$RADVD_CONFIG_FILE" ] && return 1
429 sysctl -w net.ipv6.conf.all.forwarding=1 > /dev/null 2> /dev/null
431 radvd -C "$RADVD_CONFIG_FILE" -m stderr_syslog -p /var/run/radvd.pid