odhcp6c: move IPv6 /proc config to userspace and sanitize
[openwrt.git] / package / network / ipv6 / odhcp6c / files / dhcpv6.script
1 #!/bin/sh
2 [ -z "$2" ] && echo "Error: should be run by odhcpc6c" && exit 1
3 . /lib/functions.sh
4 . /lib/netifd/netifd-proto.sh
5
6 setup_interface () {
7         local device="$1"
8         proto_init_update "*" 1
9
10         # Merge RA-DNS
11         for radns in $RA_DNS; do
12                 local duplicate=0
13                 for dns in $RDNSS; do
14                         [ "$radns" = "$dns" ] && duplicate=1
15                 done
16                 [ "$duplicate" = 0 ] && RDNSS="$RDNSS $radns"
17         done
18
19         for dns in $RDNSS; do
20                 proto_add_dns_server "$dns"
21         done
22
23         for domain in $DOMAINS; do
24                 proto_add_dns_search "$domain"
25         done
26
27         for prefix in $PREFIXES; do
28                 proto_add_ipv6_prefix "$prefix"
29                 local entry="${prefix#*/}"
30                 entry="${entry#*,}"
31                 entry="${entry#*,}"
32                 local valid="${entry%%,*}"
33
34                 if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
35                                 -z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
36                         RA_ROUTES="::/0,$SERVER,$valid,4096"
37                 fi
38         done
39
40         [ -n "$USERPREFIX" ] && proto_add_ipv6_prefix "$USERPREFIX"
41
42         # Merge addresses
43         for entry in $RA_ADDRESSES; do
44                 local duplicate=0
45                 local addr="${entry%%/*}"
46                 for dentry in $ADDRESSES; do
47                         local daddr="${dentry%%/*}"
48                         [ "$addr" = "$daddr" ] && duplicate=1
49                 done
50                 [ "$duplicate" = "0" ] && ADDRESSES="$ADDRESSES $entry"
51         done
52
53         for entry in $ADDRESSES; do
54                 local addr="${entry%%/*}"
55                 entry="${entry#*/}"
56                 local mask="${entry%%,*}"
57                 entry="${entry#*,}"
58                 local preferred="${entry%%,*}"
59                 entry="${entry#*,}"
60                 local valid="${entry%%,*}"
61
62                 proto_add_ipv6_address "$addr" "$mask" "$preferred" "$valid" 1
63
64                 if [ -z "$RA_ADDRESSES" -a -z "$RA_ROUTES" -a \
65                                 -z "$RA_DNS" -a "$FAKE_ROUTES" = 1 ]; then
66                         RA_ROUTES="::/0,$SERVER,$valid,4096"
67                 fi
68         done
69
70         for entry in $RA_ROUTES; do
71                 local addr="${entry%%/*}"
72                 entry="${entry#*/}"
73                 local mask="${entry%%,*}"
74                 entry="${entry#*,}"
75                 local gw="${entry%%,*}"
76                 entry="${entry#*,}"
77                 local valid="${entry%%,*}"
78                 entry="${entry#*,}"
79                 local metric="${entry%%,*}"
80
81                 if [ -z "$SOURCE_ROUTING" -o -z "$gw" ]; then
82                         proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid"
83                 else
84                         proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid" "::/128"
85                         for prefix in $PREFIXES $ADDRESSES; do
86                                 local paddr="${prefix%%,*}"
87                                 proto_add_ipv6_route "$addr" "$mask" "$gw" "$metric" "$valid" "$paddr"
88                         done
89                 fi
90         done
91
92         proto_add_data
93         [ -n "$CER" ] && json_add_string cer "$CER"
94         [ -n "$PASSTHRU" ] && json_add_string passthru "$PASSTHRU"
95         [ -n "$ZONE" ] && json_add_string zone "$ZONE"
96         proto_close_data
97
98         proto_send_update "$INTERFACE"
99
100         MAPTYPE=""
101         MAPRULE=""
102
103         if [ -n "$MAPE" -a -f /lib/netifd/proto/map.sh ]; then
104                 MAPTYPE="map-e"
105                 MAPRULE="$MAPE"
106         elif [ -n "$MAPT" -a -f /lib/netifd/proto/map.sh -a -f /proc/net/nat46/control ]; then
107                 MAPTYPE="map-t"
108                 MAPRULE="$MAPT"
109         elif [ -n "$LW4O6" -a -f /lib/netifd/proto/map.sh ]; then
110                 MAPTYPE="lw4o6"
111                 MAPRULE="$LW4O6"
112         fi
113
114         [ -n "$ZONE" ] || ZONE=$(fw3 -q network $INTERFACE)
115
116         if [ "$IFACE_MAP" != 0 -a -n "$MAPTYPE" -a -n "$MAPRULE" ]; then
117                 [ -z "$IFACE_MAP" -o "$IFACE_MAP" = 1 ] && IFACE_MAP=${INTERFACE}_map
118                 json_init
119                 json_add_string name "$IFACE_MAP"
120                 json_add_string ifname "@$INTERFACE"
121                 json_add_string proto map
122                 json_add_string type "$MAPTYPE"
123                 json_add_string rule "$MAPRULE"
124                 json_add_string tunlink "$INTERFACE"
125                 [ -n "$ZONE_MAP" ] || ZONE_MAP=$ZONE
126                 [ -n "$ZONE_MAP" ] && json_add_string zone "$ZONE_MAP"
127                 [ -n "$IFACE_MAP_DELEGATE" ] && json_add_boolean delegate "$IFACE_MAP_DELEGATE"
128                 json_close_object
129                 ubus call network add_dynamic "$(json_dump)"
130         elif [ -n "$AFTR" -a "$IFACE_DSLITE" != 0 -a -f /lib/netifd/proto/dslite.sh ]; then
131                 [ -z "$IFACE_DSLITE" -o "$IFACE_DSLITE" = 1 ] && IFACE_DSLITE=${INTERFACE}_dslite
132                 json_init
133                 json_add_string name "$IFACE_DSLITE"
134                 json_add_string ifname "@$INTERFACE"
135                 json_add_string proto "dslite"
136                 json_add_string peeraddr "$AFTR"
137                 json_add_string tunlink "$INTERFACE"
138                 [ -n "$ZONE_DSLITE" ] || ZONE_DSLITE=$ZONE
139                 [ -n "$ZONE_DSLITE" ] && json_add_string zone "$ZONE_DSLITE"
140                 [ -n "$IFACE_DSLITE_DELEGATE" ] && json_add_boolean delegate "$IFACE_DSLITE_DELEGATE"
141                 json_close_object
142                 ubus call network add_dynamic "$(json_dump)"
143         elif [ "$IFACE_464XLAT" != 0 -a -f /lib/netifd/proto/464xlat.sh ]; then
144                 [ -z "$IFACE_464XLAT" -o "$IFACE_464XLAT" = 1 ] && IFACE_464XLAT=${INTERFACE}_464xlat
145                 json_init
146                 json_add_string name "$IFACE_464XLAT"
147                 json_add_string ifname "@$INTERFACE"
148                 json_add_string proto "464xlat"
149                 json_add_string tunlink "$INTERFACE"
150                 [ -n "$ZONE_464XLAT" ] || ZONE_464XLAT=$ZONE
151                 [ -n "$ZONE_464XLAT" ] && json_add_string zone "$ZONE_464XLAT"
152                 [ -n "$IFACE_464XLAT_DELEGATE" ] && json_add_boolean delegate "$IFACE_464XLAT_DELEGATE"
153                 json_close_object
154                 ubus call network add_dynamic "$(json_dump)"
155         fi
156
157         # Apply IPv6 / ND configuration
158         HOPLIMIT=$(cat /proc/sys/net/ipv6/conf/$device/hop_limit)
159         [ "$RA_HOPLIMIT" -gt "$HOPLIMIT" ] && echo "$RA_HOPLIMIT" > /proc/sys/net/ipv6/conf/$device/hop_limit
160         [ "$RA_MTU" -gt 0 ] && echo "$RA_MTU" > /proc/sys/net/ipv6/conf/$device/mtu
161         [ "$RA_REACHABLE" -gt 0 ] && echo "$RA_REACHABLE" > /proc/sys/net/ipv6/neigh/$device/base_reachable_time_ms
162         [ "$RA_RETRANSMIT" -gt 0 ] && echo "$RA_RETRANSMIT" > /proc/sys/net/ipv6/neigh/$device/retrans_time_ms
163
164         # TODO: $SNTP_IP $SIP_IP $SNTP_FQDN $SIP_DOMAIN
165 }
166
167 teardown_interface() {
168         proto_init_update "*" 0
169         proto_send_update "$INTERFACE"
170 }
171
172 case "$2" in
173         bound)
174                 teardown_interface "$1"
175                 setup_interface "$1"
176         ;;
177         informed|updated|rebound)
178                 setup_interface "$1"
179         ;;
180         ra-updated)
181                 [ -n "$ADDRESSES$RA_ADDRESSES$PREFIXES$USERPREFIX" ] && setup_interface "$1"
182         ;;
183         started|stopped|unbound)
184                 teardown_interface "$1"
185         ;;
186 esac
187
188 # user rules
189 [ -f /etc/odhcp6c.user ] && . /etc/odhcp6c.user
190
191 exit 0