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 <jo@mein.io>
This commit is contained in:
		@@ -45,7 +45,36 @@ network_get_subnet() {
 | 
				
			|||||||
# 1: destination variable
 | 
					# 1: destination variable
 | 
				
			||||||
# 2: interface
 | 
					# 2: interface
 | 
				
			||||||
network_get_subnet6() {
 | 
					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
 | 
					# determine first IPv6 prefix of given logical interface
 | 
				
			||||||
@@ -94,18 +123,13 @@ network_get_ipaddrs6() {
 | 
				
			|||||||
# 1: destination variable
 | 
					# 1: destination variable
 | 
				
			||||||
# 2: interface
 | 
					# 2: interface
 | 
				
			||||||
network_get_ipaddrs_all() {
 | 
					network_get_ipaddrs_all() {
 | 
				
			||||||
	local __addr
 | 
						local __addr __addr6
 | 
				
			||||||
	local __list=""
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if __network_ifstatus "__addr" "$2" "['ipv4-address','ipv6-address','ipv6-prefix-assignment'][*].address"; then
 | 
						network_get_ipaddrs __addr "$2"
 | 
				
			||||||
		for __addr in $__addr; do
 | 
						network_get_ipaddrs6 __addr6 "$2"
 | 
				
			||||||
			case "$__addr" in
 | 
					 | 
				
			||||||
				*:) __list="${__list:+$__list }${__addr}1" ;;
 | 
					 | 
				
			||||||
				*)  __list="${__list:+$__list }${__addr}"  ;;
 | 
					 | 
				
			||||||
			esac
 | 
					 | 
				
			||||||
		done
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		export "$1=$__list"
 | 
						if [ -n "$__addr" -o -n "$__addr6" ]; then
 | 
				
			||||||
 | 
							export "$1=${__addr:+$__addr }$__addr6"
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -124,17 +148,24 @@ network_get_subnets() {
 | 
				
			|||||||
# 1: destination variable
 | 
					# 1: destination variable
 | 
				
			||||||
# 2: interface
 | 
					# 2: interface
 | 
				
			||||||
network_get_subnets6() {
 | 
					network_get_subnets6() {
 | 
				
			||||||
	local __addr
 | 
						local __addr __mask
 | 
				
			||||||
	local __list=""
 | 
						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
 | 
							for __addr in $__addr; do
 | 
				
			||||||
			case "$__addr" in
 | 
								__list="${__list:+$__list }${__addr}"
 | 
				
			||||||
				*:/*) __list="${__list:+$__list }${__addr%/*}1/${__addr##*/}" ;;
 | 
					 | 
				
			||||||
				*)    __list="${__list:+$__list }${__addr}"                   ;;
 | 
					 | 
				
			||||||
			esac
 | 
					 | 
				
			||||||
		done
 | 
							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"
 | 
							export "$1=$__list"
 | 
				
			||||||
		return 0
 | 
							return 0
 | 
				
			||||||
	fi
 | 
						fi
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user