proto-shell: fix legacy proto_config_add_* functions, make them wrap around config_add_*
[project/netifd.git] / scripts / netifd-proto.sh
1 NETIFD_MAIN_DIR="${NETIFD_MAIN_DIR:-/lib/netifd}"
2
3 . /usr/share/libubox/jshn.sh
4 . $NETIFD_MAIN_DIR/utils.sh
5
6 proto_config_add_int() {
7 config_add_int "$@"
8 }
9
10 proto_config_add_string() {
11 config_add_string "$@"
12 }
13
14 proto_config_add_boolean() {
15 config_add_boolean "$@"
16 }
17
18 _proto_do_teardown() {
19 json_load "$data"
20 eval "proto_$1_teardown \"$interface\" \"$ifname\""
21 }
22
23 _proto_do_setup() {
24 json_load "$data"
25 _EXPORT_VAR=0
26 _EXPORT_VARS=
27 eval "proto_$1_setup \"$interface\" \"$ifname\""
28 }
29
30 proto_init_update() {
31 local ifname="$1"
32 local up="$2"
33 local external="$3"
34
35 PROTO_KEEP=0
36 PROTO_INIT=1
37 PROTO_TUNNEL_OPEN=
38 PROTO_IPADDR=
39 PROTO_IP6ADDR=
40 PROTO_ROUTE=
41 PROTO_ROUTE6=
42 PROTO_PREFIX6=
43 PROTO_DNS=
44 PROTO_DNS_SEARCH=
45 json_init
46 json_add_int action 0
47 [ -n "$ifname" -a "*" != "$ifname" ] && json_add_string "ifname" "$ifname"
48 json_add_boolean "link-up" "$up"
49 [ -n "$3" ] && json_add_boolean "address-external" "$external"
50 }
51
52 proto_set_keep() {
53 PROTO_KEEP="$1"
54 }
55
56 proto_close_nested() {
57 [ -n "$PROTO_NESTED_OPEN" ] && json_close_object
58 PROTO_NESTED_OPEN=
59 }
60
61 proto_add_nested() {
62 PROTO_NESTED_OPEN=1
63 json_add_object "$1"
64 }
65
66 proto_add_tunnel() {
67 proto_add_nested "tunnel"
68 }
69
70 proto_close_tunnel() {
71 proto_close_nested
72 }
73
74 proto_add_data() {
75 proto_add_nested "data"
76 }
77
78 proto_close_data() {
79 proto_close_nested
80 }
81
82 proto_add_dns_server() {
83 local address="$1"
84
85 append PROTO_DNS "$address"
86 }
87
88 proto_add_dns_search() {
89 local address="$1"
90
91 append PROTO_DNS_SEARCH "$address"
92 }
93
94 proto_add_ipv4_address() {
95 local address="$1"
96 local mask="$2"
97 local broadcast="$3"
98 local ptp="$4"
99
100 append PROTO_IPADDR "$address/$mask/$broadcast/$ptp"
101 }
102
103 proto_add_ipv6_address() {
104 local address="$1"
105 local mask="$2"
106 local preferred="$3"
107 local valid="$4"
108 local offlink="$5"
109
110 append PROTO_IP6ADDR "$address/$mask/$preferred/$valid/$offlink"
111 }
112
113 proto_add_ipv4_route() {
114 local target="$1"
115 local mask="$2"
116 local gw="$3"
117
118 append PROTO_ROUTE "$target/$mask/$gw//"
119 }
120
121 proto_add_ipv6_route() {
122 local target="$1"
123 local mask="$2"
124 local gw="$3"
125 local metric="$4"
126 local valid="$5"
127 local source="$6"
128
129 append PROTO_ROUTE6 "$target/$mask/$gw/$metric/$valid/$source"
130 }
131
132 proto_add_ipv6_prefix() {
133 local prefix="$1"
134 local valid="$2"
135 local preferred="$3"
136
137 if [ -z "$valid" ]; then
138 append PROTO_PREFIX6 "$prefix"
139 else
140 [ -z "$preferred" ] && preferred="$valid"
141 append PROTO_PREFIX6 "$prefix,$valid,$preferred"
142 fi
143 }
144
145 _proto_push_ipv4_addr() {
146 local str="$1"
147 local address mask broadcast ptp
148
149 address="${str%%/*}"
150 str="${str#*/}"
151 mask="${str%%/*}"
152 str="${str#*/}"
153 broadcast="${str%%/*}"
154 str="${str#*/}"
155 ptp="$str"
156
157 json_add_object ""
158 json_add_string ipaddr "$address"
159 [ -n "$mask" ] && json_add_string mask "$mask"
160 [ -n "$broadcast" ] && json_add_string broadcast "$broadcast"
161 [ -n "$ptp" ] && json_add_string ptp "$ptp"
162 json_close_object
163 }
164
165 _proto_push_ipv6_addr() {
166 local str="$1"
167 local address mask preferred valid offlink
168
169 address="${str%%/*}"
170 str="${str#*/}"
171 mask="${str%%/*}"
172 str="${str#*/}"
173 preferred="${str%%/*}"
174 str="${str#*/}"
175 valid="${str%%/*}"
176 str="${str#*/}"
177 offlink="${str%%/*}"
178
179 json_add_object ""
180 json_add_string ipaddr "$address"
181 [ -n "$mask" ] && json_add_string mask "$mask"
182 [ -n "$preferred" ] && json_add_int preferred "$preferred"
183 [ -n "$valid" ] && json_add_int valid "$valid"
184 [ -n "$offlink" ] && json_add_boolean offlink "$offlink"
185 json_close_object
186 }
187
188 _proto_push_string() {
189 json_add_string "" "$1"
190 }
191
192 _proto_push_route() {
193 local str="$1";
194 local target="${str%%/*}"
195 str="${str#*/}"
196 local mask="${str%%/*}"
197 str="${str#*/}"
198 local gw="${str%%/*}"
199 str="${str#*/}"
200 local metric="${str%%/*}"
201 str="${str#*/}"
202 local valid="${str%%/*}"
203 str="${str#*/}"
204 local source="${str}"
205
206 json_add_object ""
207 json_add_string target "$target"
208 json_add_string netmask "$mask"
209 [ -n "$gw" ] && json_add_string gateway "$gw"
210 [ -n "$metric" ] && json_add_int metric "$metric"
211 [ -n "$valid" ] && json_add_int valid "$valid"
212 [ -n "$source" ] && json_add_string source "$source"
213 json_close_object
214 }
215
216 _proto_push_array() {
217 local name="$1"
218 local val="$2"
219 local cb="$3"
220
221 [ -n "$val" ] || return 0
222 json_add_array "$name"
223 for item in $val; do
224 eval "$cb \"\$item\""
225 done
226 json_close_array
227 }
228
229 _proto_notify() {
230 local interface="$1"
231 local options="$2"
232 json_add_string "interface" "$interface"
233 ubus $options call network.interface notify_proto "$(json_dump)"
234 }
235
236 proto_send_update() {
237 local interface="$1"
238
239 proto_close_nested
240 json_add_boolean keep "$PROTO_KEEP"
241 _proto_push_array "ipaddr" "$PROTO_IPADDR" _proto_push_ipv4_addr
242 _proto_push_array "ip6addr" "$PROTO_IP6ADDR" _proto_push_ipv6_addr
243 _proto_push_array "routes" "$PROTO_ROUTE" _proto_push_route
244 _proto_push_array "routes6" "$PROTO_ROUTE6" _proto_push_route
245 _proto_push_array "ip6prefix" "$PROTO_PREFIX6" _proto_push_string
246 _proto_push_array "dns" "$PROTO_DNS" _proto_push_string
247 _proto_push_array "dns_search" "$PROTO_DNS_SEARCH" _proto_push_string
248 _proto_notify "$interface"
249 }
250
251 proto_export() {
252 local var="VAR${_EXPORT_VAR}"
253 _EXPORT_VAR="$(($_EXPORT_VAR + 1))"
254 export -- "$var=$1"
255 append _EXPORT_VARS "$var"
256 }
257
258 proto_run_command() {
259 local interface="$1"; shift
260
261 json_init
262 json_add_int action 1
263 json_add_array command
264 while [ $# -gt 0 ]; do
265 json_add_string "" "$1"
266 shift
267 done
268 json_close_array
269 [ -n "$_EXPORT_VARS" ] && {
270 json_add_array env
271 for var in $_EXPORT_VARS; do
272 eval "json_add_string \"\" \"\${$var}\""
273 done
274 json_close_array
275 }
276 _proto_notify "$interface"
277 }
278
279 proto_kill_command() {
280 local interface="$1"; shift
281
282 json_init
283 json_add_int action 2
284 [ -n "$1" ] && json_add_int signal "$1"
285 _proto_notify "$interface"
286 }
287
288 proto_notify_error() {
289 local interface="$1"; shift
290
291 json_init
292 json_add_int action 3
293 json_add_array error
294 while [ $# -gt 0 ]; do
295 json_add_string "" "$1"
296 shift
297 done
298 json_close_array
299 _proto_notify "$interface"
300 }
301
302 proto_block_restart() {
303 local interface="$1"; shift
304
305 json_init
306 json_add_int action 4
307 _proto_notify "$interface"
308 }
309
310 proto_set_available() {
311 local interface="$1"
312 local state="$2"
313 json_init
314 json_add_int action 5
315 json_add_boolean available "$state"
316 _proto_notify "$interface"
317 }
318
319 proto_add_host_dependency() {
320 local interface="$1"
321 local host="$2"
322 local ifname="$3"
323
324 # execute in subshell to not taint callers env
325 # see tickets #11046, #11545, #11570
326 (
327 json_init
328 json_add_int action 6
329 json_add_string host "$host"
330 [ -n "$ifname" ] && json_add_string ifname "$ifname"
331 _proto_notify "$interface" -S
332 )
333 }
334
335 proto_setup_failed() {
336 local interface="$1"
337 json_init
338 json_add_int action 7
339 _proto_notify "$interface"
340 }
341
342 init_proto() {
343 proto="$1"; shift
344 cmd="$1"; shift
345
346 case "$cmd" in
347 dump)
348 add_protocol() {
349 no_device=0
350 available=0
351
352 add_default_handler "proto_$1_init_config"
353
354 json_init
355 json_add_string "name" "$1"
356 json_add_array "config"
357 eval "proto_$1_init_config"
358 json_close_array
359 json_add_boolean no-device "$no_device"
360 json_add_boolean available "$available"
361 json_dump
362 }
363 ;;
364 setup|teardown)
365 interface="$1"; shift
366 data="$1"; shift
367 ifname="$1"; shift
368
369 add_protocol() {
370 [[ "$proto" == "$1" ]] || return 0
371
372 case "$cmd" in
373 setup) _proto_do_setup "$1";;
374 teardown) _proto_do_teardown "$1" ;;
375 *) return 1 ;;
376 esac
377 }
378 ;;
379 esac
380 }