Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 19 Dec 2025 14:13:21 +0000
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: df6861d755c8 - main - ifconfig: Fix the -L flag when using netlink
Message-ID:  <69455d81.3ca96.63fd1fee@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by markj:

URL: https://cgit.FreeBSD.org/src/commit/?id=df6861d755c8f72380ae7fb8df535b27eba8c0be

commit df6861d755c8f72380ae7fb8df535b27eba8c0be
Author:     Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-12-19 14:11:20 +0000
Commit:     Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-12-19 14:11:20 +0000

    ifconfig: Fix the -L flag when using netlink
    
    By default, when ifconfig shows a v6 address derived from a
    router-advertised prefix, it shows the initial preferred and valid
    lifetimes.  When -L is specified, it is supposed to show the remaining
    lifetimes, but this was broken in the conversion to netlink.
    
    Fix that, and add a regression test which validates ifconfig output
    before and after a short-lived address expires.
    
    Reported by:    Franco Fichtner <franco@opnsense.org>
    Reviewed by:    melifaro, allanjude, Seyed Pouria Mousavizadeh Tehrani
    Fixes:          4c91a5dfe483 ("ifconfig: make interface and address listing use Netlink as transport")
    MFC after:      2 weeks
    Sponsored by:   OPNsense
    Sponsored by:   Klara, Inc.
    Differential Revision:  https://reviews.freebsd.org/D54294
---
 sbin/ifconfig/af_inet6.c  |  6 +++--
 tests/sys/netinet6/ndp.sh | 62 +++++++++++++++++++++++++++++++++++++++++++++++
 tests/sys/netinet6/ra.py  | 11 ++++++++-
 3 files changed, 76 insertions(+), 3 deletions(-)

diff --git a/sbin/ifconfig/af_inet6.c b/sbin/ifconfig/af_inet6.c
index 9386f5eaf513..365f01be9590 100644
--- a/sbin/ifconfig/af_inet6.c
+++ b/sbin/ifconfig/af_inet6.c
@@ -375,8 +375,10 @@ show_lifetime(struct ifa_cacheinfo *ci)
 	vl = (ci->ifa_valid == ND6_INFINITE_LIFETIME) ? 0 : ci->ifa_valid;
 
 	clock_gettime(CLOCK_MONOTONIC_FAST, &now);
-	print_lifetime("pltime", pl + now.tv_sec, &now);
-	print_lifetime("vltime", vl + now.tv_sec, &now);
+	print_lifetime("pltime",
+	    pl + (ip6lifetime ? ci->tstamp / 1000 : now.tv_sec), &now);
+	print_lifetime("vltime",
+	    vl + (ip6lifetime ? ci->tstamp / 1000 : now.tv_sec), &now);
 }
 
 static void
diff --git a/tests/sys/netinet6/ndp.sh b/tests/sys/netinet6/ndp.sh
index 21a50cda02ba..3464ac59c898 100755
--- a/tests/sys/netinet6/ndp.sh
+++ b/tests/sys/netinet6/ndp.sh
@@ -226,10 +226,72 @@ ndp_prefix_len_mismatch_cleanup() {
 	vnet_cleanup
 }
 
+atf_test_case "ndp_prefix_lifetime" "cleanup"
+ndp_prefix_lifetime_head() {
+	atf_set descr 'Test ndp slaac address lifetime handling'
+	atf_set require.user root
+	atf_set require.progs python3 scapy
+}
+
+ndp_prefix_lifetime_body() {
+	local epair0 jname prefix
+
+	vnet_init
+
+	jname="v6t-ndp_prefix_lifetime"
+
+	epair0=$(vnet_mkepair)
+
+	vnet_mkjail ${jname} ${epair0}a
+
+	ndp_if_up ${epair0}a ${jname}
+	ndp_if_up ${epair0}b
+	atf_check jexec ${jname} ifconfig ${epair0}a inet6 accept_rtadv no_dad
+
+	prefix="2001:db8:ffff:1000:"
+
+        # Send an RA advertising a prefix.
+	atf_check -e ignore python3 $(atf_get_srcdir)/ra.py \
+	    --sendif ${epair0}b \
+	    --dst $(ndp_if_lladdr ${epair0}a ${jname}) \
+	    --src $(ndp_if_lladdr ${epair0}b) \
+	    --prefix "2001:db8:ffff:1000::" --prefixlen 64 \
+	    --validlifetime 10 --preferredlifetime 5
+
+	# Wait for a default router to appear.
+	while [ -z "$(jexec ${jname} ndp -r)" ]; do
+		sleep 0.1
+	done
+	atf_check \
+	    -o match:"^default[[:space:]]+fe80:" \
+	    jexec ${jname} netstat -rn -6
+
+	atf_check \
+	    -o match:"inet6 ${prefix}.* prefixlen 64 autoconf pltime 5 vltime 10" \
+	    jexec ${jname} ifconfig ${epair0}a
+
+	# Wait for the address to become deprecated.
+	sleep 6
+	atf_check \
+	    -o match:"inet6 ${prefix}.* prefixlen 64 deprecated autoconf pltime 0 vltime [1-9]+" \
+	    jexec ${jname} ifconfig -L ${epair0}a
+
+	# Wait for the address to expire.
+	sleep 6
+	atf_check \
+	    -o not-match:"inet6 ${prefix}.*" \
+	    jexec ${jname} ifconfig ${epair0}a
+}
+
+ndp_prefix_lifetime_cleanup() {
+	vnet_cleanup
+}
+
 atf_init_test_cases()
 {
 	atf_add_test_case "ndp_add_gu_success"
 	atf_add_test_case "ndp_del_gu_success"
 	atf_add_test_case "ndp_slaac_default_route"
 	atf_add_test_case "ndp_prefix_len_mismatch"
+	atf_add_test_case "ndp_prefix_lifetime"
 }
diff --git a/tests/sys/netinet6/ra.py b/tests/sys/netinet6/ra.py
index a5016b3f6e9b..1b08c3e53c05 100644
--- a/tests/sys/netinet6/ra.py
+++ b/tests/sys/netinet6/ra.py
@@ -25,12 +25,21 @@ def main():
                         help='The prefix to be advertised')
     parser.add_argument('--prefixlen', nargs=1, required=True, type=int,
                         help='The prefix length to be advertised')
+    parser.add_argument('--validlifetime', nargs=1, required=False,
+                        type=int, default=4294967295,
+                        help='The valid lifetime of the prefix')
+    parser.add_argument('--preferredlifetime', nargs=1, required=False,
+                        type=int, default=4294967295,
+                        help='The preferred lifetime of the prefix')
 
     args = parser.parse_args()
     pkt = sp.Ether() / \
         sp.IPv6(src=args.src, dst=args.dst) / \
         sp.ICMPv6ND_RA(chlim=64) / \
-        sp.ICMPv6NDOptPrefixInfo(prefix=args.prefix, prefixlen=args.prefixlen)
+        sp.ICMPv6NDOptPrefixInfo(prefix=args.prefix,
+                                 prefixlen=args.prefixlen,
+                                 validlifetime=args.validlifetime,
+                                 preferredlifetime=args.preferredlifetime)
 
     sp.sendp(pkt, iface=args.sendif[0], verbose=False)
     sys.exit(0)


help

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69455d81.3ca96.63fd1fee>