From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: passt.top; dmarc=none (p=none dis=none) header.from=gibson.dropbear.id.au Authentication-Results: passt.top; dkim=pass (2048-bit key; secure) header.d=gibson.dropbear.id.au header.i=@gibson.dropbear.id.au header.a=rsa-sha256 header.s=202508 header.b=fGRrgtNe; dkim-atps=neutral Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by passt.top (Postfix) with ESMTPS id 126145A0271 for ; Tue, 30 Sep 2025 07:49:21 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gibson.dropbear.id.au; s=202508; t=1759211358; bh=WayL1ShvNyigvWM8UEpYMOdLAwq7ZlVIH5/nhqtMrkA=; h=From:To:Cc:Subject:Date:From; b=fGRrgtNeKBe1FLwuadCbEwh0QUzoSB1uthCXgiid95uZv1NypR58Mgjw7XxBvRYQD JZtgabrzMQWcZPv+bhL/9TQoLLX2qkDtAGo+GgSkwbvrMFdsLZqrNO53ZebPQEOnkG xpdXODiHzc4pW4kYHRkAxmG4x4OHt3FbDkTYcQSrWrqvWBAwNgJvBO8IbPEBHe2Jfh 38khN1s6eho+uYiHbSnA9GxqzNqPZ+Gfcs3VheVWDYb7YP9p6Jp0FKdtMInF0Vu0sO FTmcqL6iHtZDEhm1tbSoIEc/7PRoDmDnz/jL5Bt401phQBh7Odc0vXfQb9W0+kfgSz eRvhAQEHwKR8g== Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4cbRvf2yQKz4wBj; Tue, 30 Sep 2025 15:49:18 +1000 (AEST) From: David Gibson To: passt-dev@passt.top, Stefano Brivio Subject: [PATCH] netlink: Don't require address to be global, just not link local Date: Tue, 30 Sep 2025 15:49:11 +1000 Message-ID: <20250930054911.1800690-1-david@gibson.dropbear.id.au> X-Mailer: git-send-email 2.51.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Message-ID-Hash: QQNCONSD4YKSHJM2S5HYFKJYTNDWWHU2 X-Message-ID-Hash: QQNCONSD4YKSHJM2S5HYFKJYTNDWWHU2 X-MailFrom: dgibson@gandalf.ozlabs.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: David Gibson , Xun Gu X-Mailman-Version: 3.3.8 Precedence: list List-Id: Development discussion and patches for passt Archived-At: Archived-At: List-Archive: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: nl_addr_get() will only pick up global IPv6 addresses (RT_SCOPE_UNIVERSE). This is because link-local addresses aren't suitable. However site-local addresses (in the rare occassions they're used) would be fine for our purposes. In fact, anything wider than link scope is fine, so update the check to reflect that. Change the logic in the test scripts to match as well. Reported-by: Xun Gu Link: https://bugs.passt.top/show_bug.cgi?id=122 Signed-off-by: David Gibson --- netlink.c | 2 +- test/demo/podman | 4 ++-- test/migrate/basic | 2 +- test/migrate/basic_fin | 2 +- test/migrate/iperf3_bidir6 | 2 +- test/migrate/iperf3_in6 | 2 +- test/migrate/iperf3_many_out6 | 2 +- test/migrate/iperf3_out6 | 2 +- test/migrate/rampstream_in | 2 +- test/migrate/rampstream_out | 2 +- test/passt/dhcp | 2 +- test/passt/ndp | 2 +- test/passt_in_ns/dhcp | 2 +- test/pasta/dhcp | 2 +- test/pasta/ndp | 2 +- test/perf/pasta_tcp | 2 +- test/perf/pasta_udp | 2 +- test/two_guests/basic | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/netlink.c b/netlink.c index c4367807..9fe70f2c 100644 --- a/netlink.c +++ b/netlink.c @@ -786,7 +786,7 @@ int nl_addr_get(int s, unsigned int ifi, sa_family_t af, prefix_max = *prefix_len = ifa->ifa_prefixlen; } else if (af == AF_INET6 && addr && - ifa->ifa_scope == RT_SCOPE_UNIVERSE && + ifa->ifa_scope < RT_SCOPE_LINK && ifa->ifa_prefixlen > prefix_max) { memcpy(addr, RTA_DATA(rta), RTA_PAYLOAD(rta)); diff --git a/test/demo/podman b/test/demo/podman index edd403a1..393691ca 100644 --- a/test/demo/podman +++ b/test/demo/podman @@ -310,8 +310,8 @@ nl say Everything is set now, let's start sleep 2 hout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -hout ADDR4 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local' -hout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local' +hout ADDR4 ip -j -4 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope != "host" and .scope != "link").local' +hout ADDR6 ip -j -6 addr show|jq -rM '.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope != "host" and .scope != "link").local' hout GW4 ip -j -4 route show|jq -rM '.[] | select(.dst == "default").gateway' hout GW6 ip -j -6 route show|jq -rM '.[] | select(.dst == "default").gateway' diff --git a/test/migrate/basic b/test/migrate/basic index 3f11f7d8..c22fee80 100644 --- a/test/migrate/basic +++ b/test/migrate/basic @@ -39,7 +39,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv4: guest1/guest2 > host diff --git a/test/migrate/basic_fin b/test/migrate/basic_fin index aa61ec5a..c35c2690 100644 --- a/test/migrate/basic_fin +++ b/test/migrate/basic_fin @@ -39,7 +39,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv4: guest1, half-close, guest2 > host diff --git a/test/migrate/iperf3_bidir6 b/test/migrate/iperf3_bidir6 index 4bfefb58..60b2a9b2 100644 --- a/test/migrate/iperf3_bidir6 +++ b/test/migrate/iperf3_bidir6 @@ -44,7 +44,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv6 host <-> guest flood, many flows, during migration diff --git a/test/migrate/iperf3_in6 b/test/migrate/iperf3_in6 index 16cf504f..9b7f2c60 100644 --- a/test/migrate/iperf3_in6 +++ b/test/migrate/iperf3_in6 @@ -44,7 +44,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv6 host to guest throughput during migration diff --git a/test/migrate/iperf3_many_out6 b/test/migrate/iperf3_many_out6 index 88133f26..9b3095f6 100644 --- a/test/migrate/iperf3_many_out6 +++ b/test/migrate/iperf3_many_out6 @@ -44,7 +44,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv6 guest to host flood, many flows, during migration diff --git a/test/migrate/iperf3_out6 b/test/migrate/iperf3_out6 index 21fbfcd6..b94a70c2 100644 --- a/test/migrate/iperf3_out6 +++ b/test/migrate/iperf3_out6 @@ -44,7 +44,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv6 guest to host throughput during migration diff --git a/test/migrate/rampstream_in b/test/migrate/rampstream_in index df333ba5..3c7fd200 100644 --- a/test/migrate/rampstream_in +++ b/test/migrate/rampstream_in @@ -40,7 +40,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv4: sequence check, ramps, inbound diff --git a/test/migrate/rampstream_out b/test/migrate/rampstream_out index 8ed3229b..8cff6d9c 100644 --- a/test/migrate/rampstream_out +++ b/test/migrate/rampstream_out @@ -40,7 +40,7 @@ guest1 /sbin/dhclient -6 __IFNAME1__ # Wait for DAD to complete on the DHCP address guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] test TCP/IPv4: sequence check, ramps, outbound diff --git a/test/passt/dhcp b/test/passt/dhcp index 145f1baa..dc6b880f 100644 --- a/test/passt/dhcp +++ b/test/passt/dhcp @@ -61,7 +61,7 @@ guest /sbin/dhclient -6 __IFNAME__ # Wait for DAD to complete guest while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done gout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR6__" = "__HOST_ADDR6__" ] test DHCPv6: route diff --git a/test/passt/ndp b/test/passt/ndp index 516cd6b8..df77cdcc 100644 --- a/test/passt/ndp +++ b/test/passt/ndp @@ -25,7 +25,7 @@ check [ -n "__IFNAME__" ] test SLAAC: prefix gout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.protocol == "kernel_ra") | .local + "/" + (.prefixlen | tostring)] | .[0]' gout PREFIX6 sipcalc __ADDR6__ | grep prefix | cut -d' ' -f4 -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' hout HOST_PREFIX6 sipcalc __HOST_ADDR6__/64 | grep prefix | cut -d' ' -f4 check [ "__PREFIX6__" = "__HOST_PREFIX6__" ] diff --git a/test/passt_in_ns/dhcp b/test/passt_in_ns/dhcp index a38a6908..0ccb4800 100644 --- a/test/passt_in_ns/dhcp +++ b/test/passt_in_ns/dhcp @@ -55,7 +55,7 @@ guest /sbin/dhclient -6 __IFNAME__ # Wait for DAD to complete guest while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done gout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR6__" = "__HOST_ADDR6__" ] test DHCPv6: route diff --git a/test/pasta/dhcp b/test/pasta/dhcp index d4f3ad58..e1c66be6 100644 --- a/test/pasta/dhcp +++ b/test/pasta/dhcp @@ -39,7 +39,7 @@ ns /sbin/dhclient -6 --no-pid __IFNAME__ ns while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done hout HOST_IFNAME6 ip -j -6 route show|jq -rM '[.[] | select(.dst == "default").dev] | .[0]' nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ __ADDR6__ = __HOST_ADDR6__ ] test DHCPv6: route diff --git a/test/pasta/ndp b/test/pasta/ndp index 952c1eab..e4828765 100644 --- a/test/pasta/ndp +++ b/test/pasta/ndp @@ -24,7 +24,7 @@ ns while ! ip -j -6 addr show dev __IFNAME__ | jq -e '.[].addr_info.[] | select( test SLAAC: prefix nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.protocol == "kernel_ra") | .local + "/" + (.prefixlen | tostring)] | .[0]' nsout PREFIX6 sipcalc __ADDR6__ | grep prefix | cut -d' ' -f4 -hout HOST_ADDR6 ip -j -6 addr show|jq -rM ['.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM ['.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' hout HOST_PREFIX6 sipcalc __HOST_ADDR6__/64 | grep prefix | cut -d' ' -f4 check [ "__PREFIX6__" = "__HOST_PREFIX6__" ] diff --git a/test/perf/pasta_tcp b/test/perf/pasta_tcp index bc0de3c4..496d0fec 100644 --- a/test/perf/pasta_tcp +++ b/test/perf/pasta_tcp @@ -211,7 +211,7 @@ tr TCP throughput over IPv6: host to ns iperf3s ns 10002 nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local] | .[0]' +nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope != "host" and .scope != "link").local] | .[0]' bw - bw - bw - diff --git a/test/perf/pasta_udp b/test/perf/pasta_udp index ab2f3e89..3a7054c9 100644 --- a/test/perf/pasta_udp +++ b/test/perf/pasta_udp @@ -196,7 +196,7 @@ tr UDP throughput over IPv6: host to ns iperf3s ns 10002 nsout IFNAME ip -j link show | jq -rM '.[] | select(.link_type == "ether").ifname' -nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope == "global").local] | .[0]' +nsout ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME__").addr_info[] | select(.scope != "host" and .scope != "link").local] | .[0]' iperf3 BW host __ADDR6__ 10002 __TIME__ __OPTS__ -b 8G -l 1472 bw __BW__ 0.3 0.5 iperf3 BW host __ADDR6__ 10002 __TIME__ __OPTS__ -b 12G -l 3972 diff --git a/test/two_guests/basic b/test/two_guests/basic index e2338ffd..a9625f3e 100644 --- a/test/two_guests/basic +++ b/test/two_guests/basic @@ -45,7 +45,7 @@ guest1 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; guest2 while ip -j -6 addr show tentative | jq -e '.[].addr_info'; do sleep 0.1; done g1out ADDR1_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME1__").addr_info[] | select(.prefixlen == 128).local] | .[0]' g2out ADDR2_6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__IFNAME2__").addr_info[] | select(.prefixlen == 128).local] | .[0]' -hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope == "global" and .deprecated != true).local] | .[0]' +hout HOST_ADDR6 ip -j -6 addr show|jq -rM '[.[] | select(.ifname == "__HOST_IFNAME6__").addr_info[] | select(.scope != "host" and .scope != "link" and .deprecated != true).local] | .[0]' check [ "__ADDR1_6__" = "__HOST_ADDR6__" ] check [ "__ADDR2_6__" = "__HOST_ADDR6__" ] -- 2.51.0