X-Git-Url: https://git.archive.openwrt.org/?a=blobdiff_plain;f=package%2Fbase-files%2Ffiles%2Flib%2Ffunctions%2Fnetwork.sh;h=86ab8905f1477f1e2ef5655dba75f5c345980a70;hb=b4d1b5ed6d3af0d95fca99e89894ff866586ef5a;hp=d86a504bf44c3f66392d5e2252e6fcadb293a687;hpb=bd4ec4d567494ce433865557e7896a2072f16707;p=openwrt.git diff --git a/package/base-files/files/lib/functions/network.sh b/package/base-files/files/lib/functions/network.sh index d86a504bf4..86ab8905f1 100644 --- a/package/base-files/files/lib/functions/network.sh +++ b/package/base-files/files/lib/functions/network.sh @@ -1,354 +1,234 @@ -. /usr/share/libubox/jshn.sh - -__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$3}\"; [ -n \"\${$__v+x}\" ]" -} - -__network_parse_ifstatus() -{ - local __iface="$1" - local __key="${__iface}" +# 1: destination variable +# 2: interface +# 3: path +# 4: separator +# 5: limit +__network_ifstatus() { local __tmp - local __old_ns - - __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 - if json_is_a "ipv${__family}_address" array; then - - json_select "ipv${__family}_address" - - if json_is_a 1 object; then - - json_select 1 - __network_set_cache "${__key}_address${__family}" address - __network_set_cache "${__key}_mask${__family}" mask - json_select ".." - - fi - - json_select ".." - - fi - done - - # parse prefixes - if json_is_a "ipv6_prefix" array; then - json_select "ipv6_prefix" - - if json_is_a 1 object; then - json_select 1 - __network_set_cache "${__key}_prefix6_address" address - __network_set_cache "${__key}_prefix6_mask" mask - json_select ".." - fi - - json_select ".." - 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 + [ -z "$__NETWORK_CACHE" ] && \ + export __NETWORK_CACHE="$(ubus call network.interface dump)" - case "${__tmp}" in - 0.0.0.0) - __network_set_cache "${__key}_gateway4" nexthop - ;; - ::) - __network_set_cache "${__key}_gateway6" nexthop - ;; - esac - fi + __tmp="$(jsonfilter ${4:+-F "$4"} ${5:+-l "$5"} -s "$__NETWORK_CACHE" -e "$1=@.interface${2:+[@.interface='$2']}$3")" - json_select ".." + [ -z "$__tmp" ] && \ + unset "$1" && \ + return 1 - 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" - - local __idx=1 - local __dns="" - - while json_is_a "$__idx" string; do - - json_get_var __tmp "$((__idx++))" - __dns="${__dns:+$__dns }$__tmp" - - done - - json_select ".." - - if [ -n "$__dns" ]; then - __network_set_cache "${__key}_${__field}" "" "$__dns" - fi - fi - done - - # parse up state, device and physdev - for __field in "up" "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 + eval "$__tmp" } +# determine first IPv4 address of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddr() { + __network_ifstatus "$1" "$2" "['ipv4-address'][0].address"; +} -__network_ipaddr() -{ - local __var="$1" - local __iface="$2" - local __family="$3" - local __prefix="$4" - local __tmp - - __network_parse_ifstatus "$__iface" || return 1 - - if [ $__prefix -eq 1 ]; then - __network_export __tmp "${__iface}_mask${__family}" && \ - __network_export "$__var" "${__iface}_address${__family}" "/$__tmp" - return $? - fi - - __network_export "$__var" "${__iface}_address${__family}" - return $? +# determine first IPv6 address of given logical interface +# 1: destination variable +# 2: interface +network_get_ipaddr6() { + __network_ifstatus "$1" "$2" "['ipv6-address'][0].address"; +} +# determine first IPv4 subnet of given logical interface +# 1: destination variable +# 2: interface +network_get_subnet() { + __network_ifstatus "$1" "$2" "['ipv4-address'][0]['address','mask']" "/" } -# determine IPv4 address of given logical interface +# determine first IPv6 subnet of given logical interface # 1: destination variable # 2: interface -network_get_ipaddr() { __network_ipaddr "$1" "$2" 4 0; } +network_get_subnet6() { + __network_ifstatus "$1" "$2" "['ipv6-address'][0]['address','mask']" "/" +} -# determine IPv6 address of given logical interface +# determine first IPv6 prefix of given logical interface # 1: destination variable # 2: interface -network_get_ipaddr6() { __network_ipaddr "$1" "$2" 6 0; } +network_get_prefix6() { + __network_ifstatus "$1" "$2" "['ipv6-prefix'][0]['address','mask']" "/" +} -# determine IPv4 subnet of given logical interface +# determine all IPv4 addresses of given logical interface # 1: destination variable # 2: interface -network_get_subnet() { __network_ipaddr "$1" "$2" 4 1; } +network_get_ipaddrs() { + __network_ifstatus "$1" "$2" "['ipv4-address'][*].address" +} -# determine IPv6 subnet of given logical interface +# determine all IPv6 addresses of given logical interface # 1: destination variable # 2: interface -network_get_subnet6() { __network_ipaddr "$1" "$2" 6 1; } +network_get_ipaddrs6() { + local __addr + local __list="" + + if __network_ifstatus "__addr" "$2" "['ipv6-address','ipv6-prefix-assignment'][*].address"; then + for __addr in $__addr; do + case "$__addr" in + *:) __list="${__list:+$__list }${__addr}1" ;; + *) __list="${__list:+$__list }${__addr}" ;; + esac + done -# determine IPv6 prefix -network_get_prefix6() { - local __var="$1" - local __iface="$2" - local __address - local __mask - - __network_parse_ifstatus "$__iface" || return 1 - __network_export __mask "${__iface}_prefix6_mask" || return 1 - __network_export "$__var" "${__iface}_prefix6_address" "/$__mask" - return $? -} + export "$1=$__list" + return 0 + fi + unset "$1" + return 1 +} -__network_gateway() -{ - local __var="$1" - local __iface="$2" - local __family="$3" - local __inactive="$4" +# determine all IPv4 subnets of given logical interface +# 1: destination variable +# 2: interface +network_get_subnets() { + __network_ifstatus "$1" "$2" "['ipv4-address'][*]['address','mask']" "/ " +} - __network_parse_ifstatus "$__iface" || return 1 +# determine all IPv6 subnets of given logical interface +# 1: destination variable +# 2: interface +network_get_subnets6() { + local __addr + local __list="" + + if __network_ifstatus "__addr" "$2" "['ipv6-address','ipv6-prefix-assignment'][*]['address','mask']" "/ "; then + for __addr in $__addr; do + case "$__addr" in + *:/*) __list="${__list:+$__list }${__addr%/*}1/${__addr##*/}" ;; + *) __list="${__list:+$__list }${__addr}" ;; + esac + done - if [ "$__inactive" = 1 -o "$__inactive" = "true" ]; then - __network_export "$__var" "${__iface}_inactive_gateway${__family}" && \ - return 0 + export "$1=$__list" + return 0 fi - __network_export "$__var" "${__iface}_gateway${__family}" - return $? + unset "$1" + return 1 } -# determine IPv4 gateway of given logical interface +# determine all IPv6 prefixes of given logical interface # 1: destination variable # 2: interface -# 3: consider inactive gateway if "true" (optional) -network_get_gateway() { __network_gateway "$1" "$2" 4 "${3:-0}"; } +network_get_prefixes6() { + __network_ifstatus "$1" "$2" "['ipv6-prefix'][*]['address','mask']" "/ " +} -# determine IPv6 gateway of given logical interface +# determine IPv4 gateway of given logical interface # 1: destination variable # 2: interface # 3: consider inactive gateway if "true" (optional) -network_get_gateway6() { __network_gateway "$1" "$2" 6 "${3:-0}"; } +network_get_gateway() { + __network_ifstatus "$1" "$2" ".route[@.target='0.0.0.0' && !@.table].nexthop" "" 1 && \ + return 0 + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive.route[@.target='0.0.0.0' && !@.table].nexthop" "" 1 +} -__network_dns() { - local __var="$1" - local __iface="$2" - local __field="$3" - local __inactive="$4" - - __network_parse_ifstatus "$__iface" || return 1 - - if [ "$__inactive" = 1 -o "$__inactive" = "true" ]; then - __network_export "$__var" "${__iface}_inactive_${__field}" && \ - return 0 - fi +# determine IPv6 gateway of given logical interface +# 1: destination variable +# 2: interface +# 3: consider inactive gateway if "true" (optional) +network_get_gateway6() { + __network_ifstatus "$1" "$2" ".route[@.target='::' && !@.table].nexthop" "" 1 && \ + return 0 - __network_export "$__var" "${__iface}_${__field}" - return $? + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive.route[@.target='::' && !@.table].nexthop" "" 1 } # determine the DNS servers of the given logical interface # 1: destination variable # 2: interface # 3: consider inactive servers if "true" (optional) -network_get_dnsserver() { __network_dns "$1" "$2" dns_server "${3:-0}"; } +network_get_dnsserver() { + __network_ifstatus "$1" "$2" "['dns-server'][*]" && return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive['dns-server'][*]" +} # determine the domains of the given logical interface # 1: destination variable # 2: interface # 3: consider inactive domains if "true" (optional) -network_get_dnssearch() { __network_dns "$1" "$2" dns_search "${3:-0}"; } +network_get_dnssearch() { + __network_ifstatus "$1" "$2" "['dns-search'][*]" && return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "$2" ".inactive['dns-search'][*]" +} +# 1: destination variable +# 2: addr +# 3: inactive __network_wan() { - local __var="$1" - local __family="$2" - local __inactive="$3" - local __iface - - for __iface in $(ubus list | sed -ne 's/^network\.interface\.//p'); do - if [ "$__iface" != loopback ]; then - if __network_gateway "$__var" "$__iface" "$__family" "$__inactive"; then - eval "export -- \"$__var=$__iface\"" - return 0 - fi - fi - done - - eval "export -- \"$__var=\"" - return 1 + __network_ifstatus "$1" "" \ + "[@.route[@.target='$2' && !@.table]].interface" "" 1 && \ + return 0 + + [ "$3" = 1 -o "$3" = "true" ] && \ + __network_ifstatus "$1" "" \ + "[@.inactive.route[@.target='$2' && !@.table]].interface" "" 1 } # find the logical interface which holds the current IPv4 default route # 1: destination variable # 2: consider inactive default routes if "true" (optional) -network_find_wan() { __network_wan "$1" 4 "${2:-0}"; } +network_find_wan() { __network_wan "$1" "0.0.0.0" "$2"; } # find the logical interface which holds the current IPv6 default route # 1: destination variable # 2: consider inactive dafault routes if "true" (optional) -network_find_wan6() { __network_wan "$1" 6 "${2:-0}"; } - - -__network_device() -{ - local __var="$1" - local __iface="$2" - local __field="$3" - - __network_parse_ifstatus "$__iface" || return 1 - __network_export "$__var" "${__iface}_${__field}" - return $? -} +network_find_wan6() { __network_wan "$1" "::" "$2"; } # test whether the given logical interface is running # 1: interface network_is_up() { local __up - __network_device __up "$1" up && [ $__up -eq 1 ] + __network_ifstatus "__up" "$1" ".up" && [ "$__up" = 1 ] } +# determine the protocol of the given logical interface +# 1: destination variable +# 2: interface +network_get_protocol() { __network_ifstatus "$1" "$2" ".proto"; } + # determine the layer 3 linux network device of the given logical interface # 1: destination variable # 2: interface -network_get_device() { __network_device "$1" "$2" l3_device; } +network_get_device() { __network_ifstatus "$1" "$2" ".l3_device"; } # determine the layer 2 linux network device of the given logical interface # 1: destination variable # 2: interface -network_get_physdev() { __network_device "$1" "$2" device; } - - -__network_defer() -{ - local __device="$1" - local __defer="$2" - - json_init - json_add_string name "$__device" - json_add_boolean defer "$__defer" - - ubus call network.device set_state "$(json_dump)" 2>/dev/null -} +network_get_physdev() { __network_ifstatus "$1" "$2" ".device"; } # defer netifd actions on the given linux network device # 1: device name -network_defer_device() { __network_defer "$1" 1; } +network_defer_device() +{ + ubus call network.device set_state \ + "$(printf '{ "name": "%s", "defer": true }' "$1")" 2>/dev/null +} # continue netifd actions on the given linux network device # 1: device name -network_ready_device() { __network_defer "$1" 0; } - -# flush the internal value cache to force re-reading values from ubus -network_flush_cache() +network_ready_device() { - local __tmp - for __tmp in $__NETWORK_CACHE __NETWORK_CACHE; do - unset "$__tmp" - done + ubus call network.device set_state \ + "$(printf '{ "name": "%s", "defer": false }' "$1")" 2>/dev/null } + +# flush the internal value cache to force re-reading values from ubus +network_flush_cache() { unset __NETWORK_CACHE; }