radv: let an explicit lease time floor constructed-prefix RA lifetimes

For constructor: ranges dnsmasq advertises the residual kernel lifetimes
of the interface address, and an explicitly configured lease time only
caps them. Behind an upstream that delegates with very short lifetimes
(Starlink PD: ~300s valid / 150s preferred) every client inherits the
churn verbatim, and any device that sleeps through a few RAs (every
phone) loses its GUA mid-flow, killing established connections.

With this patch an explicitly configured lease time on a constructed
range acts as a floor as well. Prefix deprecation is untouched: a
deprecated context or kernel-deprecated address still advertises
preferred=0, and a vanished prefix still goes through the CONTEXT_OLD
path, so renumbering behaves exactly as stock.

Document both the existing RA lifetime ceiling and the new floor
behaviour for constructed ranges in dnsmasq.8.

diff --git a/src/radv.c b/src/radv.c
--- a/src/radv.c
+++ b/src/radv.c
@@ -608,6 +608,7 @@
 	  int do_slaac = 0;
 	  int deprecate  = 0;
 	  int constructed = 0;
+	  int have_lease = 0;
 	  int adv_router = 0;
 	  int off_link = 0;
 	  unsigned int time = 0xffffffff;
@@ -660,6 +661,8 @@
 		    if (time < ((unsigned int)(3 * param->adv_interval)))
 		      time = 3 * param->adv_interval;
 		  }
+		if (context->flags & CONTEXT_SETLEASE)
+		  have_lease = 1;
 
 		if (context->flags & CONTEXT_DEPRECATE)
 		  deprecate = 1;
@@ -697,7 +700,19 @@
 	  /* configured time is ceiling */
 	  if (!constructed || valid > time)
 	    valid = time;
-	  
+
+	  /* For CONSTRUCTED prefixes an explicitly configured lease time is
+	     also a floor: an upstream delegating with very short lifetimes
+	     (mobile links) would otherwise churn the addresses of any client
+	     that sleeps through a few RAs. Deprecation still wins below. */
+	  if (constructed && have_lease && !deprecate && !(flags & IFACE_DEPRECATED))
+	    {
+	      if (valid < time)
+		valid = time;
+	      if (preferred < time)
+		preferred = time;
+	    }
+
 	  if (flags & IFACE_DEPRECATED)
 	    preferred = 0;
 	  
diff --git a/man/dnsmasq.8 b/man/dnsmasq.8
--- a/man/dnsmasq.8
+++ b/man/dnsmasq.8
@@ -1061,1 +1061,5 @@
 The minimum lease time is two minutes.
+An explicitly configured lease time also affects IPv6 router advertisements:
+it acts as a ceiling on the advertised prefix lifetimes. For constructed
+ranges it also acts as a floor, unless the prefix is being deprecated.
+
