base-files: various enhancements to network.sh
[openwrt/openwrt.git] / package / base-files / files / lib / functions / network.sh
1 . /usr/share/libubox/jshn.sh
2
3 __network_switch_inactive()
4 {
5 local __tmp
6
7 if [ "$1" = 0 ] || [ "$1" = false ]; then
8 return 1
9 fi
10
11 json_get_type __tmp "inactive"
12
13 if [ "$__tmp" = object ]; then
14 json_select "inactive"
15 fi
16 }
17
18 __network_set_cache()
19 {
20 __NETWORK_CACHE="${__NETWORK_CACHE:+$__NETWORK_CACHE }__NETWORK_CV_$1"
21 eval "__NETWORK_CV_$1='\$$2'"
22 }
23
24 __network_get_cache()
25 {
26 eval "[ -n \"\${__NETWORK_CV_$1+x}\" ] && export -- \"$2=\$__NETWORK_CV_$1\""
27 }
28
29 __network_ipaddr()
30 {
31 local __var="$1"
32 local __iface="$2"
33 local __family="$3"
34 local __prefix="$4"
35 local __key="ipaddr_${2}_${3}_${4}"
36
37 __network_get_cache "$__key" "$__var" && return 0
38
39 local __tmp="$(ubus call network.interface."$__iface" status 2>/dev/null)"
40
41 json_load "${__tmp:-{}}"
42 json_get_type __tmp "ipv${__family}_address"
43
44 if [ "$__tmp" = array ]; then
45
46 json_select "ipv${__family}_address"
47 json_get_type __tmp 1
48
49 if [ "$__tmp" = object ]; then
50
51 json_select 1
52 json_get_var $__var address
53
54 [ $__prefix -gt 0 ] && {
55 json_get_var __tmp mask
56 eval "export -- \"$__var=\${$__var}/$__tmp\""
57 }
58
59 __network_set_cache "$__key" "$__var"
60 return 0
61 fi
62 fi
63
64 return 1
65 }
66
67 # determine IPv4 address of given logical interface
68 # 1: destination variable
69 # 2: interface
70 network_get_ipaddr() { __network_ipaddr "$1" "$2" 4 0; }
71
72 # determine IPv6 address of given logical interface
73 # 1: destination variable
74 # 2: interface
75 network_get_ipaddr6() { __network_ipaddr "$1" "$2" 6 0; }
76
77 # determine IPv4 subnet of given logical interface
78 # 1: destination variable
79 # 2: interface
80 network_get_subnet() { __network_ipaddr "$1" "$2" 4 1; }
81
82 # determine IPv6 subnet of given logical interface
83 # 1: destination variable
84 # 2: interface
85 network_get_subnet6() { __network_ipaddr "$1" "$2" 6 1; }
86
87
88 __network_gateway()
89 {
90 local __var="$1"
91 local __iface="$2"
92 local __family="$3"
93 local __key="gateway_${2}_${3}"
94
95 __network_get_cache "$__key" "$__var" && return 0
96
97 local __tmp="$(ubus call network.interface."$__iface" status 2>/dev/null)"
98
99 json_load "${__tmp:-{}}"
100
101 for __tmp in 0 1; do
102
103 if json_get_type __tmp route && [ "$__tmp" = array ]; then
104
105 json_select route
106
107 local __idx=1
108 while json_get_type __tmp "$__idx" && [ "$__tmp" = object ]; do
109
110 json_select "$((__idx++))"
111 json_get_var __tmp target
112
113 case "${__family}/${__tmp}" in
114 4/0.0.0.0|6/::)
115 json_get_var "$__var" nexthop
116 __network_set_cache "$__key" "$__var"
117 return $?
118 ;;
119 esac
120
121 json_select ".."
122
123 done
124
125 json_select ".."
126
127 fi
128
129 __network_switch_inactive "$4" || break
130
131 done
132
133 return 1
134 }
135
136 # determine IPv4 gateway of given logical interface
137 # 1: destination variable
138 # 2: interface
139 # 3: consider inactive gateway if "true" (optional)
140 network_get_gateway() { __network_gateway "$1" "$2" 4 "${3:-0}"; }
141
142 # determine IPv6 gateway of given logical interface
143 # 1: destination variable
144 # 2: interface
145 # 3: consider inactive gateway if "true" (optional)
146 network_get_gateway6() { __network_gateway "$1" "$2" 6 "${3:-0}"; }
147
148
149 __network_dns() {
150 local __var="$1"
151 local __iface="$2"
152 local __field="$3"
153 local __key="dns_${2}_${3}"
154
155 __network_get_cache "$__key" "$__var" && return 0
156
157 local __tmp="$(ubus call network.interface."$__iface" status 2>/dev/null)"
158 local __dns=""
159
160 json_load "${__tmp:-{}}"
161
162 for __tmp in 0 1; do
163
164 if json_get_type __tmp "$__field" && [ "$__tmp" = array ]; then
165
166 json_select "$__field"
167
168 local __idx=1
169 while json_get_type __tmp "$__idx" && [ "$__tmp" = string ]; do
170
171 json_get_var __tmp "$((__idx++))"
172 __dns="${__dns:+$__dns }$__tmp"
173
174 done
175
176 json_select ".."
177 fi
178
179 __network_switch_inactive "$4" || break
180
181 done
182
183 if [ -n "$__dns" ]; then
184 eval "export -- \"$__var=$__dns\""
185 __network_set_cache "$__key" "$__var"
186 fi
187 }
188
189 # determine the DNS servers of the given logical interface
190 # 1: destination variable
191 # 2: interface
192 # 3: consider inactive servers if "true" (optional)
193 network_get_dnsserver() { __network_dns "$1" "$2" dns_server "${3:-0}"; }
194
195 # determine the domains of the given logical interface
196 # 1: destination variable
197 # 2: interface
198 # 3: consider inactive servers if "true" (optional)
199 network_get_dnssearch() { __network_dns "$1" "$2" dns_search "${3:-0}"; }
200
201
202 __network_wan() {
203 local __var="$1"
204 local __family="$2"
205 local __key="wan_${2}"
206 local __iface
207
208 __network_get_cache "$__key" "$__var" && return 0
209
210 for __iface in $(ubus list | sed -ne 's/^network\.interface\.//p'); do
211 if __network_gateway "$__var" "$__iface" "$__family"; then
212 eval "export -- \"$__var=$__iface\""
213 __network_set_cache "$__key" "$__var"
214 return 0
215 fi
216 done
217
218 eval "export -- \"$__var=\""
219 return 1
220 }
221
222 # find the logical interface which holds the current IPv4 default route
223 # 1: destination variable
224 network_find_wan() { __network_wan "$1" 4; }
225
226 # find the logical interface which holds the current IPv6 default route
227 # 1: destination variable
228 network_find_wan6() { __network_wan "$1" 6; }
229
230
231 __network_device()
232 {
233 local __var="$1"
234 local __iface="$2"
235 local __field="$3"
236 local __key="device_${2}_${3}"
237
238 __network_get_cache "$__key" "$__var" && return 0
239
240 local __tmp="$(ubus call network.interface."$__iface" status 2>/dev/null)"
241 [ -n "$__tmp" ] || return 1
242
243 json_load "$__tmp"
244 json_get_var "$__var" "$__field" && __network_set_cache "$__key" "$__var"
245 }
246
247 # test whether the given logical interface is running
248 # 1: interface
249 network_is_up()
250 {
251 local __up
252 __network_device __up "$1" up && [ $__up -eq 1 ]
253 }
254
255 # determine the layer 3 linux network device of the given logical interface
256 # 1: destination variable
257 # 2: interface
258 network_get_device() { __network_device "$1" "$2" l3_device; }
259
260 # determine the layer 2 linux network device of the given logical interface
261 # 1: destination variable
262 # 2: interface
263 network_get_physdev() { __network_device "$1" "$2" device; }
264
265
266 __network_defer()
267 {
268 local __device="$1"
269 local __defer="$2"
270
271 json_init
272 json_add_string name "$__device"
273 json_add_boolean defer "$__defer"
274
275 ubus call network.device set_state "$(json_dump)" 2>/dev/null
276 }
277
278 # defer netifd actions on the given linux network device
279 # 1: device name
280 network_defer_device() { __network_defer "$1" 1; }
281
282 # continue netifd actions on the given linux network device
283 # 1: device name
284 network_ready_device() { __network_defer "$1" 0; }
285
286 # flush the internal value cache to force re-reading values from ubus
287 network_flush_cache()
288 {
289 local __tmp
290 for __tmp in $__NETWORK_CACHE __NETWORK_CACHE; do
291 unset "$__tmp"
292 done
293 }