Explorar el Código

base-files: network.sh: fix a number of IPv6 logic flaws

* Change network_get_subnet6() to sensibly guess a suitable prefix

  Attempt to return the first non-linklocal, non-ula range, then attempt
  to return the first non-linklocal range and finally fall back to the
  previous behaviour of simply returning the first found item.

* Fix network_get_ipaddrs_all()

  Instead of replicating the flawed logic appending a fixed ":1" suffix
  to IPv6 addresses, rely on network_get_ipaddrs() and network_get_ipaddrs6()
  to build a single list of all interface addresses.

* Fix network_get_subnets6()

  Instead of replicating the flawed logic appending a fixed ":1" suffix
  to IPv6 addresses, rely on the ipv6-prefix-assignment.local-address
  field to figure out the proper network address.

Signed-off-by: Jo-Philipp Wich <[email protected]>
Jo-Philipp Wich hace 8 años
padre
commit
6426e4edef
Se han modificado 1 ficheros con 48 adiciones y 17 borrados
  1. 48 17
      package/base-files/files/lib/functions/network.sh

+ 48 - 17
package/base-files/files/lib/functions/network.sh

@@ -45,7 +45,36 @@ network_get_subnet() {
 # 1: destination variable
 # 2: interface
 network_get_subnet6() {
-	__network_ifstatus "$1" "$2" "['ipv6-address'][0]['address','mask']" "/"
+	local __nets __addr
+
+	if network_get_subnets6 __nets "$2"; then
+		# Attempt to return first non-fe80::/10, non-fc::/7 range
+		for __addr in $__nets; do
+			case "$__addr" in fe[8ab]?:*|f[cd]??:*)
+				continue
+			esac
+			export "$1=$__addr"
+			return 0
+		done
+
+		# Attempt to return first non-fe80::/10 range
+		for __addr in $__nets; do
+			case "$__addr" in fe[8ab]?:*)
+				continue
+			esac
+			export "$1=$__addr"
+			return 0
+		done
+
+		# Return first item
+		for __addr in $__nets; do
+			export "$1=$__addr"
+			return 0
+		done
+	fi
+
+	unset "$1"
+	return 1
 }
 
 # determine first IPv6 prefix of given logical interface
@@ -94,18 +123,13 @@ network_get_ipaddrs6() {
 # 1: destination variable
 # 2: interface
 network_get_ipaddrs_all() {
-	local __addr
-	local __list=""
+	local __addr __addr6
 
-	if __network_ifstatus "__addr" "$2" "['ipv4-address','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
+	network_get_ipaddrs __addr "$2"
+	network_get_ipaddrs6 __addr6 "$2"
 
-		export "$1=$__list"
+	if [ -n "$__addr" -o -n "$__addr6" ]; then
+		export "$1=${__addr:+$__addr }$__addr6"
 		return 0
 	fi
 
@@ -124,17 +148,24 @@ network_get_subnets() {
 # 1: destination variable
 # 2: interface
 network_get_subnets6() {
-	local __addr
+	local __addr __mask
 	local __list=""
 
-	if __network_ifstatus "__addr" "$2" "['ipv6-address','ipv6-prefix-assignment'][*]['address','mask']" "/ "; then
+	if __network_ifstatus "__addr" "$2" "['ipv6-address'][*]['address','mask']" "/ "; then
 		for __addr in $__addr; do
-			case "$__addr" in
-				*:/*) __list="${__list:+$__list }${__addr%/*}1/${__addr##*/}" ;;
-				*)    __list="${__list:+$__list }${__addr}"                   ;;
-			esac
+			__list="${__list:+$__list }${__addr}"
 		done
+	fi
 
+	if __network_ifstatus "__addr" "$2" "['ipv6-prefix-assignment'][*]['local-address'].address" && \
+	   __network_ifstatus "__mask" "$2" "['ipv6-prefix-assignment'][*].mask"; then
+		for __addr in $__addr; do
+			__list="${__list:+$__list }${__addr}/${__mask%% *}"
+			__mask="${__mask#* }"
+		done
+	fi
+
+	if [ -n "$__list" ]; then
 		export "$1=$__list"
 		return 0
 	fi