diff --git a/usr.sbin/ppp/README.changes b/usr.sbin/ppp/README.changes
index ea50741c3496..e0c796e453f7 100644
--- a/usr.sbin/ppp/README.changes
+++ b/usr.sbin/ppp/README.changes
@@ -50,9 +50,9 @@ o Set encrypt is no longer necessary.  Ppp will respond to M$CHAP
 o Throughput statistics are enabled by default.
 o `Set stopped' only has two parameters.  It's no longer possible to
   have an IPCP stopped timer.
-o `Set timeout' only has one parameter.  Use `set lqrperiod' and `set
-  {lcp,ccp,ipcp,chap,pap}retry' for the other timers.  `show timeout'
-  is also now available using the relevant show commands.
+o `Set timeout' only has one or two parameters.  Use `set lqrperiod' and
+  `set {lcp,ccp,ipcp,chap,pap}retry' for the other timers.  These timeout
+  values can be seen using the relevant show commands.
 o `set loopback' is now `enable/disable loopback'.
 o `show auto', `show loopback' and `show mtu' are all part of `show bundle'.
 o `show mru' is part of `show lcp'
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 353a546722e3..7c6828820d65 100644
--- a/usr.sbin/ppp/bundle.c
+++ b/usr.sbin/ppp/bundle.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: bundle.c,v 1.60 1999/08/06 20:04:01 brian Exp $
+ *	$Id: bundle.c,v 1.61 1999/08/09 22:56:17 brian Exp $
  */
 
 #include <sys/param.h>
@@ -231,6 +231,7 @@ bundle_LayerUp(void *v, struct fsm *fp)
    * If it's an LCP, adjust our phys_mode.open value and check the
    * autoload timer.
    * If it's the first NCP, calculate our bandwidth
+   * If it's the first NCP, set our ``upat'' time
    * If it's the first NCP, start the idle timer.
    * If it's an NCP, tell our -background parent to go away.
    * If it's the first NCP, start the autoload timer
@@ -244,6 +245,7 @@ bundle_LayerUp(void *v, struct fsm *fp)
     mp_CheckAutoloadTimer(&bundle->ncp.mp);
   } else if (fp->proto == PROTO_IPCP) {
     bundle_CalculateBandwidth(fp->bundle);
+    time(&bundle->upat);
     bundle_StartIdleTimer(bundle);
     bundle_Notify(bundle, EX_NORMAL);
     mp_CheckAutoloadTimer(&fp->bundle->ncp.mp);
@@ -256,6 +258,7 @@ bundle_LayerDown(void *v, struct fsm *fp)
   /*
    * The given FSM has been told to come down.
    * If it's our last NCP, stop the idle timer.
+   * If it's our last NCP, clear our ``upat'' value.
    * If it's our last NCP, stop the autoload timer
    * If it's an LCP, adjust our phys_type.open value and any timers.
    * If it's an LCP and we're in multilink mode, adjust our tun
@@ -266,6 +269,7 @@ bundle_LayerDown(void *v, struct fsm *fp)
 
   if (fp->proto == PROTO_IPCP) {
     bundle_StopIdleTimer(bundle);
+    bundle->upat = 0;
     mp_StopAutoloadTimer(&bundle->ncp.mp);
   } else if (fp->proto == PROTO_LCP) {
     bundle_LinksRemoved(bundle);  /* adjust timers & phys_type values */
@@ -684,7 +688,8 @@ bundle_Create(const char *prefix, int type, const char **argv)
   bundle.fsm.LayerFinish = bundle_LayerFinish;
   bundle.fsm.object = &bundle;
 
-  bundle.cfg.idle_timeout = NCP_IDLE_TIMEOUT;
+  bundle.cfg.idle.timeout = NCP_IDLE_TIMEOUT;
+  bundle.cfg.idle.min_timeout = 0;
   *bundle.cfg.auth.name = '\0';
   *bundle.cfg.auth.key = '\0';
   bundle.cfg.opt = OPT_SROUTES | OPT_IDCHECK | OPT_LOOPBACK |
@@ -694,6 +699,7 @@ bundle_Create(const char *prefix, int type, const char **argv)
   bundle.cfg.choked.timeout = CHOKED_TIMEOUT;
   bundle.phys_type.all = type;
   bundle.phys_type.open = 0;
+  bundle.upat = 0;
 
   bundle.links = datalink_Create("deflink", &bundle, type);
   if (bundle.links == NULL) {
@@ -1053,10 +1059,17 @@ bundle_ShowStatus(struct cmdargs const *arg)
   prompt_Printf(arg->prompt, "Phase %s\n", bundle_PhaseName(arg->bundle));
   prompt_Printf(arg->prompt, " Title:         %s\n", arg->bundle->argv[0]);
   prompt_Printf(arg->prompt, " Device:        %s\n", arg->bundle->dev.Name);
-  prompt_Printf(arg->prompt, " Interface:     %s @ %lubps\n",
+  prompt_Printf(arg->prompt, " Interface:     %s @ %lubps",
                 arg->bundle->iface->name, arg->bundle->bandwidth);
 
-  prompt_Printf(arg->prompt, "\nDefaults:\n");
+  if (arg->bundle->upat) {
+    int secs = time(NULL) - arg->bundle->upat;
+
+    prompt_Printf(arg->prompt, ", up time %d:%02d:%02d", secs / 3600,
+                  (secs / 60) % 60, secs % 60);
+  }
+
+  prompt_Printf(arg->prompt, "\n\nDefaults:\n");
   prompt_Printf(arg->prompt, " Label:         %s\n", arg->bundle->cfg.label);
   prompt_Printf(arg->prompt, " Auth name:     %s\n",
                 arg->bundle->cfg.auth.name);
@@ -1069,8 +1082,11 @@ bundle_ShowStatus(struct cmdargs const *arg)
 #endif
 
   prompt_Printf(arg->prompt, " Idle Timer:    ");
-  if (arg->bundle->cfg.idle_timeout) {
-    prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout);
+  if (arg->bundle->cfg.idle.timeout) {
+    prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle.timeout);
+    if (arg->bundle->cfg.idle.min_timeout)
+      prompt_Printf(arg->prompt, ", min %ds",
+                    arg->bundle->cfg.idle.min_timeout);
     remaining = bundle_RemainingIdleTime(arg->bundle);
     if (remaining != -1)
       prompt_Printf(arg->prompt, " (%ds remaining)", remaining);
@@ -1137,20 +1153,31 @@ bundle_StartIdleTimer(struct bundle *bundle)
 {
   timer_Stop(&bundle->idle.timer);
   if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL)) !=
-      bundle->phys_type.open && bundle->cfg.idle_timeout) {
+      bundle->phys_type.open && bundle->cfg.idle.timeout) {
+    int secs;
+
+    secs = bundle->cfg.idle.timeout;
+    if (bundle->cfg.idle.min_timeout > secs && bundle->upat) {
+      int up = time(NULL) - bundle->upat;
+
+      if ((long long)bundle->cfg.idle.min_timeout - up > (long long)secs)
+        secs = bundle->cfg.idle.min_timeout - up;
+    }
     bundle->idle.timer.func = bundle_IdleTimeout;
     bundle->idle.timer.name = "idle";
-    bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
+    bundle->idle.timer.load = secs * SECTICKS;
     bundle->idle.timer.arg = bundle;
     timer_Start(&bundle->idle.timer);
-    bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;
+    bundle->idle.done = time(NULL) + secs;
   }
 }
 
 void
-bundle_SetIdleTimer(struct bundle *bundle, int value)
+bundle_SetIdleTimer(struct bundle *bundle, int timeout, int min_timeout)
 {
-  bundle->cfg.idle_timeout = value;
+  bundle->cfg.idle.timeout = timeout;
+  if (min_timeout >= 0)
+    bundle->cfg.idle.min_timeout = min_timeout;
   if (bundle_LinkIsUp(bundle))
     bundle_StartIdleTimer(bundle);
 }
diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h
index fbe3f0e39380..1ffce90a8e4d 100644
--- a/usr.sbin/ppp/bundle.h
+++ b/usr.sbin/ppp/bundle.h
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$Id: bundle.h,v 1.23 1999/06/02 00:46:52 brian Exp $
+ *	$Id: bundle.h,v 1.24 1999/08/05 10:32:08 brian Exp $
  */
 
 #define	PHASE_DEAD		0	/* Link is dead */
@@ -89,8 +89,13 @@ struct bundle {
   struct fsm_parent fsm;      /* Our callback functions */
   struct datalink *links;     /* Our data links */
 
+  time_t upat;                /* When the link came up */
+
   struct {
-    int idle_timeout;         /* NCP Idle timeout value */
+    struct {
+      int timeout;              /* NCP Idle timeout value */
+      int min_timeout;          /* Don't idle out before this */
+    } idle;
     struct {
       char name[AUTHLEN];     /* PAP/CHAP system name */
       char key[AUTHLEN];      /* PAP/CHAP key */
@@ -155,7 +160,7 @@ extern int bundle_FillQueues(struct bundle *);
 extern int bundle_ShowLinks(struct cmdargs const *);
 extern int bundle_ShowStatus(struct cmdargs const *);
 extern void bundle_StartIdleTimer(struct bundle *);
-extern void bundle_SetIdleTimer(struct bundle *, int);
+extern void bundle_SetIdleTimer(struct bundle *, int, int);
 extern void bundle_StopIdleTimer(struct bundle *);
 extern int bundle_IsDead(struct bundle *);
 extern struct datalink *bundle2datalink(struct bundle *, const char *);
diff --git a/usr.sbin/ppp/command.c b/usr.sbin/ppp/command.c
index 6c37b1029bf1..1a9008ea4d8d 100644
--- a/usr.sbin/ppp/command.c
+++ b/usr.sbin/ppp/command.c
@@ -17,7 +17,7 @@
  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  *
- * $Id: command.c,v 1.205 1999/08/05 10:32:09 brian Exp $
+ * $Id: command.c,v 1.206 1999/08/17 14:59:05 brian Exp $
  *
  */
 #include <sys/param.h>
@@ -144,7 +144,7 @@
 #define NEG_VJCOMP	53
 
 const char Version[] = "2.23";
-const char VersionDate[] = "$Date: 1999/08/05 10:32:09 $";
+const char VersionDate[] = "$Date: 1999/08/17 14:59:05 $";
 
 static int ShowCommand(struct cmdargs const *);
 static int TerminalCommand(struct cmdargs const *);
@@ -1605,10 +1605,17 @@ SetVariable(struct cmdargs const *arg)
     break;
 
   case VAR_IDLETIMEOUT:
-    if (arg->argc > arg->argn+1)
+    if (arg->argc > arg->argn+2)
       err = "Too many idle timeout values\n";
-    else if (arg->argc == arg->argn+1)
-      bundle_SetIdleTimer(arg->bundle, atoi(argp));
+    else if (arg->argc == arg->argn)
+      err = "Too few idle timeout values\n";
+    else {
+      int timeout, min;
+
+      timeout = atoi(argp);
+      min = arg->argc == arg->argn + 2 ? atoi(arg->argv[arg->argn + 1]) : -1;
+      bundle_SetIdleTimer(arg->bundle, timeout, min);
+    }
     if (err)
       log_Printf(LogWARN, err);
     break;
diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8
index f62598ab2ed9..310208ca0c2c 100644
--- a/usr.sbin/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp.8
@@ -1,4 +1,4 @@
-.\" $Id: ppp.8,v 1.187 1999/08/05 10:32:14 brian Exp $
+.\" $Id: ppp.8,v 1.188 1999/08/06 20:04:05 brian Exp $
 .Dd 20 September 1995
 .nr XX \w'\fC00'
 .Os FreeBSD
@@ -4457,11 +4457,18 @@ doesn't time out in the stopped state.
 This value should not be set to less than the openmode delay (see
 .Dq set openmode
 above).
-.It set timeout Ar idleseconds
+.It set timeout Ar idleseconds Op Ar mintimeout
 This command allows the setting of the idle timer.  Refer to the
 section titled
 .Sx SETTING THE IDLE TIMER
 for further details.
+.Pp
+If
+.Ar mintimeout
+is specified,
+.Nm
+will never idle out before the link has been up for at least that number
+of seconds.
 .It set vj slotcomp on|off
 This command tells
 .Nm
diff --git a/usr.sbin/ppp/ppp.8.m4 b/usr.sbin/ppp/ppp.8.m4
index f62598ab2ed9..310208ca0c2c 100644
--- a/usr.sbin/ppp/ppp.8.m4
+++ b/usr.sbin/ppp/ppp.8.m4
@@ -1,4 +1,4 @@
-.\" $Id: ppp.8,v 1.187 1999/08/05 10:32:14 brian Exp $
+.\" $Id: ppp.8,v 1.188 1999/08/06 20:04:05 brian Exp $
 .Dd 20 September 1995
 .nr XX \w'\fC00'
 .Os FreeBSD
@@ -4457,11 +4457,18 @@ doesn't time out in the stopped state.
 This value should not be set to less than the openmode delay (see
 .Dq set openmode
 above).
-.It set timeout Ar idleseconds
+.It set timeout Ar idleseconds Op Ar mintimeout
 This command allows the setting of the idle timer.  Refer to the
 section titled
 .Sx SETTING THE IDLE TIMER
 for further details.
+.Pp
+If
+.Ar mintimeout
+is specified,
+.Nm
+will never idle out before the link has been up for at least that number
+of seconds.
 .It set vj slotcomp on|off
 This command tells
 .Nm