script: don't leak IA_PD / IA_NA if not yet bound
[project/odhcp6c.git] / odhcp6c-example-script.sh
1 #!/bin/sh
2 [ -z "$2" ] && echo "Error: should be run by odhcpc6c" && exit 1
3
4 update_resolv() {
5 local device="$1"
6 local dns="$2"
7
8 (
9 flock -n 9
10 grep -v "#odhcp6c:$device:" /etc/resolv.conf > /tmp/resolv.conf.tmp
11 for c in $dns; do
12 echo "nameserver $c #odhcp6c:$device:" >> /tmp/resolv.conf.tmp
13 done
14 mv /tmp/resolv.conf.tmp /etc/resolv.conf
15 ) 9>/tmp/resolv.conf.lock
16 rm -f /tmp/resolv.conf.lock /tmp/resolv.conf.tmp
17 }
18
19 setup_interface () {
20 local device="$1"
21
22 # Merge RA-DNS
23 for radns in $RA_DNS; do
24 local duplicate=0
25 for dns in $RDNSS; do
26 [ "$radns" = "$dns" ] && duplicate=1
27 done
28 [ "$duplicate" = 0 ] && RDNSS="$RDNSS $radns"
29 done
30
31 local dnspart=""
32 for dns in $RDNSS; do
33 if [ -z "$dnspart" ]; then
34 dnspart="\"$dns\""
35 else
36 dnspart="$dnspart, \"$dns\""
37 fi
38 done
39
40 update_resolv "$device" "$dns"
41
42 local prefixpart=""
43 for entry in $PREFIXES; do
44 local addr="${entry%%,*}"
45 entry="${entry#*,}"
46 local preferred="${entry%%,*}"
47 entry="${entry#*,}"
48 local valid="${entry%%,*}"
49 entry="${entry#*,}"
50 [ "$entry" = "$valid" ] && entry=
51
52 local class=""
53 local excluded=""
54
55 while [ -n "$entry" ]; do
56 local key="${entry%%=*}"
57 entry="${entry#*=}"
58 local val="${entry%%,*}"
59 entry="${entry#*,}"
60 [ "$entry" = "$val" ] && entry=
61
62 if [ "$key" = "class" ]; then
63 class=", \"class\": $val"
64 elif [ "$key" = "excluded" ]; then
65 excluded=", \"excluded\": \"$val\""
66 fi
67 done
68
69 local prefix="{\"address\": \"$addr\", \"preferred\": $preferred, \"valid\": $valid $class $excluded}"
70
71 if [ -z "$prefixpart" ]; then
72 prefixpart="$prefix"
73 else
74 prefixpart="$prefixpart, $prefix"
75 fi
76
77 # TODO: delete this somehow when the prefix disappears
78 ip -6 route add unreachable "$addr"
79 done
80
81 ip -6 route flush dev "$device"
82 ip -6 address flush dev "$device" scope global
83
84 # Merge addresses
85 for entry in $RA_ADDRESSES; do
86 local duplicate=0
87 local addr="${entry%%/*}"
88 for dentry in $ADDRESSES; do
89 local daddr="${dentry%%/*}"
90 [ "$addr" = "$daddr" ] && duplicate=1
91 done
92 [ "$duplicate" = "0" ] && ADDRESSES="$ADDRESSES $entry"
93 done
94
95 for entry in $ADDRESSES; do
96 local addr="${entry%%,*}"
97 entry="${entry#*,}"
98 local preferred="${entry%%,*}"
99 entry="${entry#*,}"
100 local valid="${entry%%,*}"
101
102 ip -6 address add "$addr" dev "$device" preferred_lft "$preferred" valid_lft "$valid"
103 done
104
105 for entry in $RA_ROUTES; do
106 local addr="${entry%%,*}"
107 entry="${entry#*,}"
108 local gw="${entry%%,*}"
109 entry="${entry#*,}"
110 local valid="${entry%%,*}"
111 entry="${entry#*,}"
112 local metric="${entry%%,*}"
113
114 if [ -n "$gw" ]; then
115 ip -6 route add "$addr" via "$gw" metric "$metric" dev "$device" from "::/128"
116 else
117 ip -6 route add "$addr" metric "$metric" dev "$device"
118 fi
119
120 for prefix in $PREFIXES; do
121 local paddr="${prefix%%,*}"
122 [ -n "$gw" ] && ip -6 route add "$addr" via "$gw" metric "$metric" dev "$device" from "$paddr"
123 done
124 done
125 }
126
127 teardown_interface() {
128 local device="$1"
129 ip -6 route flush dev "$device"
130 ip -6 address flush dev "$device" scope global
131 update_resolv "$device" ""
132 }
133
134 case "$2" in
135 bound)
136 teardown_interface "$1"
137 setup_interface "$1"
138 ;;
139 informed|updated|rebound|ra-updated)
140 setup_interface "$1"
141 ;;
142 stopped|unbound)
143 teardown_interface "$1"
144 ;;
145 started)
146 teardown_interface "$1"
147 ;;
148 esac
149
150 # user rules
151 [ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user
152
153 exit 0