+__network_set_cache()
+{
+ if [ -n "$3" ]; then
+ eval "export -- __NETWORK_CV_$1='$3'"
+ __NETWORK_CACHE="${__NETWORK_CACHE:+$__NETWORK_CACHE }__NETWORK_CV_$1"
+ elif json_get_var "__NETWORK_CV_$1" "$2"; then
+ __NETWORK_CACHE="${__NETWORK_CACHE:+$__NETWORK_CACHE }__NETWORK_CV_$1"
+ fi
+}
+
+__network_export()
+{
+ local __v="__NETWORK_CV_$2"
+ eval "export -- \"$1=\${$__v:+\${$__v$4}$3}\"; [ -n \"\${$__v+x}\" ]"
+}
+
+__network_parse_ifstatus()
+{
+ local __iface="$1"
+ local __key="${__iface}"
+ local __tmp
+ local __idx
+ local __list
+ local __old_ns
+
+ case "$__iface" in
+ *[^a-zA-Z0-9_]*) return 1 ;;
+ esac
+
+ __network_export __tmp "${__key}__parsed" && return 0
+ __tmp="$(ubus call network.interface."$__iface" status 2>/dev/null)"
+ [ -n "$__tmp" ] || return 1
+
+ json_set_namespace "network" __old_ns
+ json_load "$__tmp"
+
+ __network_set_cache "${__key}__parsed" "" "1"
+
+ for __tmp in "" "_inactive"; do
+
+ __key="${__key}${__tmp}"
+
+ # parse addresses
+ local __family
+ for __family in 4 6; do
+
+ __list=""
+
+ if json_is_a "ipv${__family}_address" array; then
+
+ json_select "ipv${__family}_address"
+
+ __idx=1
+
+ while json_is_a "$__idx" object; do
+
+ json_select "$((__idx++))"
+ json_get_var __tmp "address" && __list="${__list:+$__list }$__tmp"
+ json_get_var __tmp "mask" && __list="${__list:+$__list/}$__tmp"
+ json_select ".."
+
+ done
+
+ json_select ".."
+
+ fi
+
+ if json_is_a "ipv${__family}_prefix_assignment" array; then
+
+ json_select "ipv${__family}_prefix_assignment"
+
+ __idx=1
+
+ while json_is_a "$__idx" object; do
+
+ json_select "$((__idx++))"
+ json_get_var __tmp "address" && __list="${__list:+$__list }${__tmp}1"
+ json_get_var __tmp "mask" && __list="${__list:+$__list/}$__tmp"
+ json_select ".."
+
+ done
+
+ json_select ".."
+
+ fi
+
+ if [ -n "$__list" ]; then
+ __network_set_cache "${__key}_address${__family}" "" "$__list"
+ fi
+
+ done
+
+ # parse prefixes
+ if json_is_a "ipv6_prefix" array; then
+ json_select "ipv6_prefix"
+
+ __idx=1
+ __list=""
+
+ while json_is_a "$__idx" object; do
+
+ json_select "$((__idx++))"
+ json_get_var __tmp "address" && __list="${__list:+$__list }$__tmp"
+ json_get_var __tmp "mask" && __list="${__list:+$__list/}$__tmp"
+ json_select ".."
+
+ done
+
+ json_select ".."
+
+
+ if [ -n "$__list" ]; then
+ __network_set_cache "${__key}_prefix6" "" "$__list"
+ fi
+
+ fi
+
+ # parse routes
+ if json_is_a route array; then
+
+ json_select "route"
+
+ local __idx=1
+ while json_is_a "$__idx" object; do
+
+ json_select "$((__idx++))"
+ json_get_var __tmp table
+
+ if [ -z "$__tmp" ]; then
+ json_get_var __tmp target
+
+ case "${__tmp}" in
+ 0.0.0.0)
+ __network_set_cache "${__key}_gateway4" nexthop
+ ;;
+ ::)
+ __network_set_cache "${__key}_gateway6" nexthop
+ ;;
+ esac
+ fi
+
+ json_select ".."
+
+ done
+
+ json_select ".."
+
+ fi
+
+ # parse dns info
+ local __field
+ for __field in "dns_server" "dns_search"; do
+ if json_is_a "$__field" array; then
+
+ json_select "$__field"
+
+ __idx=1
+ __list=""
+
+ while json_is_a "$__idx" string; do
+
+ json_get_var __tmp "$((__idx++))"
+ __list="${__list:+$__list }$__tmp"
+
+ done
+
+ json_select ".."
+
+ if [ -n "$__list" ]; then
+ __network_set_cache "${__key}_${__field}" "" "$__list"
+ fi
+ fi
+ done
+
+ # parse up state, proto, device and physdev
+ for __field in "up" "proto" "l3_device" "device"; do
+ if json_get_type __tmp "$__field"; then
+ __network_set_cache "${__key}_${__field}" "$__field"
+ fi
+ done
+
+ # descend into inactive table
+ json_is_a "inactive" object && json_select "inactive"
+
+ done
+
+ json_cleanup
+ json_set_namespace "$__old_ns"
+
+ return 0
+}
+
+