aboutsummaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorBrian Somers <brian@FreeBSD.org>1998-05-21 01:13:32 +0000
committerBrian Somers <brian@FreeBSD.org>1998-05-21 01:13:32 +0000
commit04eaa58c59b2ef73f89c48a9a7ea4ccdf2805e73 (patch)
treef39c6d58663b5b38e0288d01cd8f188208abed6a /usr.sbin
parentb1d2f6fa1cc4a4bbfdba4c11f098c1f44aa3aaf5 (diff)
downloadsrc-04eaa58c59b2ef73f89c48a9a7ea4ccdf2805e73.tar.gz
src-04eaa58c59b2ef73f89c48a9a7ea4ccdf2805e73.zip
o Add `set autoload'. You can now set the minimum and maximum
thresholds (in terms of queued packets for a period of time) where -auto links will be brought up and down. By default, all auto links come up when we reach NETWORK phase and never go down. o Display current autoload state in `show bundle'. o Disable the idle timer as soon as it's called. o Disable the idle and autoload timers when exiting (in case we're abending).
Notes
Notes: svn path=/cvs2svn/branches/MP/; revision=36268
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/ppp/bundle.c322
-rw-r--r--usr.sbin/ppp/bundle.h17
-rw-r--r--usr.sbin/ppp/command.c63
-rw-r--r--usr.sbin/ppp/ppp.832
4 files changed, 340 insertions, 94 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 0029f0e01fad..cf1fe4bfacef 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.1.2.87 1998/05/19 21:51:19 brian Exp $
+ * $Id: bundle.c,v 1.1.2.88 1998/05/19 23:05:10 brian Exp $
*/
#include <sys/types.h>
@@ -87,6 +87,9 @@
#define SOCKET_OVERHEAD 100 /* additional buffer space for large */
/* {recv,send}msg() calls */
+static int bundle_RemainingIdleTime(struct bundle *);
+static int bundle_RemainingAutoLoadTime(struct bundle *);
+
static const char *PhaseNames[] = {
"Dead", "Establish", "Authenticate", "Network", "Terminate"
};
@@ -203,12 +206,105 @@ bundle_Notify(struct bundle *bundle, char c)
}
static void
+bundle_AutoLoadTimeout(void *v)
+{
+ struct bundle *bundle = (struct bundle *)v;
+
+ if (bundle->autoload.comingup) {
+ log_Printf(LogPHASE, "autoload: Another link is required\n");
+ /* bundle_Open() stops the timer */
+ bundle_Open(bundle, NULL, PHYS_DEMAND);
+ } else {
+ struct datalink *dl, *last;
+
+ timer_Stop(&bundle->autoload.timer);
+ for (last = NULL, dl = bundle->links; dl; dl = dl->next)
+ if (dl->physical->type == PHYS_DEMAND && dl->state == DATALINK_OPEN)
+ last = dl;
+
+ if (last)
+ datalink_Close(last, 1);
+ }
+}
+
+static void
+bundle_StartAutoLoadTimer(struct bundle *bundle, int up)
+{
+ struct datalink *dl;
+
+ timer_Stop(&bundle->autoload.timer);
+
+ if (bundle->CleaningUp || bundle->phase != PHASE_NETWORK) {
+ dl = NULL;
+ bundle->autoload.running = 0;
+ } else if (up) {
+ for (dl = bundle->links; dl; dl = dl->next)
+ if (dl->state == DATALINK_CLOSED && dl->physical->type == PHYS_DEMAND) {
+ if (bundle->cfg.autoload.max.timeout) {
+ bundle->autoload.timer.func = bundle_AutoLoadTimeout;
+ bundle->autoload.timer.name = "autoload up";
+ bundle->autoload.timer.load =
+ bundle->cfg.autoload.max.timeout * SECTICKS;
+ bundle->autoload.timer.arg = bundle;
+ timer_Start(&bundle->autoload.timer);
+ bundle->autoload.done = time(NULL) + bundle->cfg.autoload.max.timeout;
+ } else
+ bundle_AutoLoadTimeout(bundle);
+ break;
+ }
+ bundle->autoload.running = (dl || bundle->cfg.autoload.min.timeout) ? 1 : 0;
+ } else {
+ int nlinks;
+ struct datalink *adl;
+
+ for (nlinks = 0, adl = NULL, dl = bundle->links; dl; dl = dl->next)
+ if (dl->state == DATALINK_OPEN) {
+ if (dl->physical->type == PHYS_DEMAND)
+ adl = dl;
+ if (++nlinks > 1 && adl) {
+ if (bundle->cfg.autoload.min.timeout) {
+ bundle->autoload.timer.func = bundle_AutoLoadTimeout;
+ bundle->autoload.timer.name = "autoload down";
+ bundle->autoload.timer.load =
+ bundle->cfg.autoload.min.timeout * SECTICKS;
+ bundle->autoload.timer.arg = bundle;
+ timer_Start(&bundle->autoload.timer);
+ bundle->autoload.done =
+ time(NULL) + bundle->cfg.autoload.min.timeout;
+ }
+ break;
+ }
+ }
+
+ bundle->autoload.running = 1;
+ }
+
+ bundle->autoload.comingup = up ? 1 : 0;
+}
+
+static void
+bundle_StopAutoLoadTimer(struct bundle *bundle)
+{
+ timer_Stop(&bundle->autoload.timer);
+ bundle->autoload.done = 0;
+}
+
+static int
+bundle_RemainingAutoLoadTime(struct bundle *bundle)
+{
+ if (bundle->autoload.done)
+ return bundle->autoload.done - time(NULL);
+ return -1;
+}
+
+
+static void
bundle_LayerUp(void *v, struct fsm *fp)
{
/*
* The given fsm is now up
* If it's an LCP set our mtu (if we're multilink, add up the link
- * speeds and set the MRRU).
+ * speeds and set the MRRU) and start our autoload timer.
* If it's an NCP, tell our -background parent to go away.
* If it's the first NCP, start the idle timer.
*/
@@ -223,6 +319,7 @@ bundle_LayerUp(void *v, struct fsm *fp)
if (dl->state == DATALINK_OPEN)
bundle->ifp.Speed += modem_Speed(dl->physical);
tun_configure(bundle, bundle->ncp.mp.peer_mrru);
+ bundle->autoload.running = 1;
} else {
bundle->ifp.Speed = modem_Speed(link2physical(fp->link));
tun_configure(bundle, fsm2lcp(fp)->his_mru);
@@ -335,6 +432,8 @@ bundle_Close(struct bundle *bundle, const char *name, int staydown)
}
if (!others_active) {
+ bundle_StopIdleTimer(bundle);
+ bundle_StopAutoLoadTimer(bundle);
if (bundle->ncp.ipcp.fsm.state > ST_CLOSED ||
bundle->ncp.ipcp.fsm.state == ST_STARTING)
fsm_Close(&bundle->ncp.ipcp.fsm);
@@ -366,7 +465,7 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
struct bundle *bundle = descriptor2bundle(d);
struct datalink *dl;
struct descriptor *desc;
- int result;
+ int result, want, queued, nlinks;
result = 0;
for (dl = bundle->links; dl; dl = dl->next)
@@ -376,18 +475,44 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
result += descriptor_UpdateSet(desc, r, w, e, n);
/* If there are aren't many packets queued, look for some more. */
- if (r && bundle->links && bundle_FillQueues(bundle) < 20) {
- if (*n < bundle->dev.fd + 1)
- *n = bundle->dev.fd + 1;
- FD_SET(bundle->dev.fd, r);
- log_Printf(LogTIMER, "tun: fdset(r) %d\n", bundle->dev.fd);
- result++;
+ for (nlinks = 0, dl = bundle->links; dl; dl = dl->next)
+ nlinks++;
+
+ if (nlinks) {
+ queued = r ? bundle_FillQueues(bundle) : ip_QueueLen();
+ if (bundle->autoload.running) {
+ if (queued < bundle->cfg.autoload.max.packets) {
+ if (queued > bundle->cfg.autoload.min.packets)
+ bundle_StopAutoLoadTimer(bundle);
+ else if (bundle->autoload.timer.state != TIMER_RUNNING ||
+ bundle->autoload.comingup)
+ bundle_StartAutoLoadTimer(bundle, 0);
+ } else if (bundle->autoload.timer.state != TIMER_RUNNING ||
+ !bundle->autoload.comingup)
+ bundle_StartAutoLoadTimer(bundle, 1);
+ }
+
+ if (r) {
+ /* enough surplus so that we can tell if we're getting swamped */
+ want = bundle->cfg.autoload.max.packets + nlinks * 2;
+ /* but at least 20 packets ! */
+ if (want < 20)
+ want = 20;
+ if (queued < want) {
+ /* Not enough - select() for more */
+ FD_SET(bundle->dev.fd, r);
+ if (*n < bundle->dev.fd + 1)
+ *n = bundle->dev.fd + 1;
+ log_Printf(LogTIMER, "tun: fdset(r) %d\n", bundle->dev.fd);
+ result++;
+ }
+ }
}
/*
* This *MUST* be called after the datalink UpdateSet()s as it
- * might be ``holding'' one of the datalinks and wants to be
- * able to de-select() from the descriptor set
+ * might be ``holding'' one of the datalinks (death-row) and
+ * wants to be able to de-select() it from the descriptor set.
*/
descriptor_UpdateSet(&bundle->ncp.mp.server.desc, r, w, e, n);
@@ -637,6 +762,10 @@ bundle_Create(const char *prefix, struct prompt *prompt, int type)
OPT_THROUGHPUT | OPT_UTMP;
*bundle.cfg.label = '\0';
bundle.cfg.mtu = DEF_MTU;
+ bundle.cfg.autoload.max.packets = 0;
+ bundle.cfg.autoload.max.timeout = 0;
+ bundle.cfg.autoload.min.packets = 0;
+ bundle.cfg.autoload.min.timeout = 0;
bundle.phys_type = type;
bundle.links = datalink_Create("deflink", &bundle, type);
@@ -672,6 +801,9 @@ bundle_Create(const char *prefix, struct prompt *prompt, int type)
memset(&bundle.idle.timer, '\0', sizeof bundle.idle.timer);
bundle.idle.done = 0;
bundle.notify.fd = -1;
+ memset(&bundle.autoload.timer, '\0', sizeof bundle.autoload.timer);
+ bundle.autoload.done = 0;
+ bundle.autoload.running = 0;
/* Clean out any leftover crud */
bundle_CleanInterface(&bundle);
@@ -725,10 +857,12 @@ bundle_Destroy(struct bundle *bundle)
struct descriptor *desc, *ndesc;
/*
- * Clean up the interface. We don't need to mp_Down(),
+ * Clean up the interface. We don't need to timer_Stop()s, mp_Down(),
* ipcp_CleanInterface() and bundle_DownInterface() unless we're getting
* out under exceptional conditions such as a descriptor exception.
*/
+ timer_Stop(&bundle->idle.timer);
+ timer_Stop(&bundle->autoload.timer);
mp_Down(&bundle->ncp.mp);
ipcp_CleanInterface(&bundle->ncp.ipcp);
bundle_DownInterface(bundle);
@@ -907,7 +1041,10 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
}
bundle_NewPhase(bundle, PHASE_DEAD);
bundle_DisplayPrompt(bundle);
- }
+ bundle_StopAutoLoadTimer(bundle);
+ bundle->autoload.running = 0;
+ } else
+ bundle->autoload.running = 1;
}
void
@@ -918,10 +1055,15 @@ bundle_Open(struct bundle *bundle, const char *name, int mask)
*/
struct datalink *dl;
+ timer_Stop(&bundle->autoload.timer);
for (dl = bundle->links; dl; dl = dl->next)
if (name == NULL || !strcasecmp(dl->name, name)) {
- if (mask & dl->physical->type)
+ if (dl->state == DATALINK_CLOSED && (mask & dl->physical->type)) {
datalink_Up(dl, 1, 1);
+ if (mask == PHYS_DEMAND)
+ /* Only one DEMAND link at a time (see the AutoLoad timer) */
+ break;
+ }
if (name != NULL)
break;
}
@@ -1002,6 +1144,22 @@ bundle_ShowStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, " Label: %s\n", arg->bundle->cfg.label);
prompt_Printf(arg->prompt, " Auth name: %s\n",
arg->bundle->cfg.auth.name);
+ prompt_Printf(arg->prompt, " Auto Load: Up after %ds of >= %d packets\n",
+ arg->bundle->cfg.autoload.max.timeout,
+ arg->bundle->cfg.autoload.max.packets);
+ prompt_Printf(arg->prompt, " Down after %ds of <= %d"
+ " packets\n", arg->bundle->cfg.autoload.min.timeout,
+ arg->bundle->cfg.autoload.min.packets);
+ if (arg->bundle->autoload.timer.state == TIMER_RUNNING)
+ prompt_Printf(arg->prompt, " %ds remaining 'till "
+ "a link comes %s\n",
+ bundle_RemainingAutoLoadTime(arg->bundle),
+ arg->bundle->autoload.comingup ? "up" : "down");
+ else
+ prompt_Printf(arg->prompt, " %srunning with %d"
+ " packets queued\n", arg->bundle->autoload.running ?
+ "" : "not ", ip_QueueLen());
+
prompt_Printf(arg->prompt, " Idle Timer: ");
if (arg->bundle->cfg.idle_timeout) {
prompt_Printf(arg->prompt, "%ds", arg->bundle->cfg.idle_timeout);
@@ -1040,8 +1198,8 @@ bundle_IdleTimeout(void *v)
{
struct bundle *bundle = (struct bundle *)v;
- bundle->idle.done = 0;
log_Printf(LogPHASE, "Idle timer expired.\n");
+ bundle_StopIdleTimer(bundle);
bundle_Close(bundle, NULL, 1);
}
@@ -1052,16 +1210,15 @@ bundle_IdleTimeout(void *v)
void
bundle_StartIdleTimer(struct bundle *bundle)
{
- if (!(bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM))) {
- timer_Stop(&bundle->idle.timer);
- if (bundle->cfg.idle_timeout) {
- bundle->idle.timer.func = bundle_IdleTimeout;
- bundle->idle.timer.name = "idle";
- bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
- bundle->idle.timer.arg = bundle;
- timer_Start(&bundle->idle.timer);
- bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;
- }
+ timer_Stop(&bundle->idle.timer);
+ if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM)) != bundle->phys_type &&
+ bundle->cfg.idle_timeout) {
+ bundle->idle.timer.func = bundle_IdleTimeout;
+ bundle->idle.timer.name = "idle";
+ bundle->idle.timer.load = bundle->cfg.idle_timeout * SECTICKS;
+ bundle->idle.timer.arg = bundle;
+ timer_Start(&bundle->idle.timer);
+ bundle->idle.done = time(NULL) + bundle->cfg.idle_timeout;
}
}
@@ -1080,7 +1237,7 @@ bundle_StopIdleTimer(struct bundle *bundle)
bundle->idle.done = 0;
}
-int
+static int
bundle_RemainingIdleTime(struct bundle *bundle)
{
if (bundle->idle.done)
@@ -1173,60 +1330,96 @@ bundle_SetTtyCommandMode(struct bundle *bundle, struct datalink *dl)
}
static void
-bundle_GenPhysType(struct bundle *bundle)
+bundle_LinkAdded(struct bundle *bundle, struct datalink *dl)
+{
+ bundle->phys_type |= dl->physical->type;
+ if (dl->physical->type == PHYS_DEMAND &&
+ bundle->autoload.timer.state == TIMER_STOPPED &&
+ bundle->phase == PHASE_NETWORK)
+ bundle->autoload.running = 1;
+}
+
+static void
+bundle_LinksRemoved(struct bundle *bundle)
{
struct datalink *dl;
bundle->phys_type = 0;
for (dl = bundle->links; dl; dl = dl->next)
- bundle->phys_type |= dl->physical->type;
-}
-
-int
-bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
- const char *name)
-{
- struct datalink *ndl;
-
- ndl = bundle2datalink(bundle, name);
- if (!ndl) {
- ndl = datalink_Clone(dl, name);
- ndl->next = dl->next;
- dl->next = ndl;
- bundle_GenPhysType(bundle);
- return 1;
- }
+ bundle_LinkAdded(bundle, dl);
- log_Printf(LogWARN, "Clone: %s: name already exists\n", ndl->name);
- return 0;
+ if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM)) == bundle->phys_type)
+ timer_Stop(&bundle->idle.timer);
}
-void
-bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
+static struct datalink *
+bundle_DatalinkLinkout(struct bundle *bundle, struct datalink *dl)
{
struct datalink **dlp;
if (dl->state == DATALINK_CLOSED)
for (dlp = &bundle->links; *dlp; dlp = &(*dlp)->next)
if (*dlp == dl) {
- *dlp = datalink_Destroy(dl);
- break;
+ *dlp = dl->next;
+ dl->next = NULL;
+ bundle_LinksRemoved(bundle);
+ return dl;
}
- bundle_GenPhysType(bundle);
+
+ return NULL;
+}
+
+static void
+bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
+{
+ struct datalink **dlp = &bundle->links;
+
+ while (*dlp)
+ dlp = &(*dlp)->next;
+
+ *dlp = dl;
+ dl->next = NULL;
+
+ bundle_LinkAdded(bundle, dl);
}
void
bundle_CleanDatalinks(struct bundle *bundle)
{
struct datalink **dlp = &bundle->links;
+ int found = 0;
while (*dlp)
if ((*dlp)->state == DATALINK_CLOSED &&
- (*dlp)->physical->type & (PHYS_DIRECT|PHYS_1OFF))
+ (*dlp)->physical->type & (PHYS_DIRECT|PHYS_1OFF)) {
*dlp = datalink_Destroy(*dlp);
- else
+ found++;
+ } else
dlp = &(*dlp)->next;
- bundle_GenPhysType(bundle);
+
+ if (found)
+ bundle_LinksRemoved(bundle);
+}
+
+int
+bundle_DatalinkClone(struct bundle *bundle, struct datalink *dl,
+ const char *name)
+{
+ if (bundle2datalink(bundle, name)) {
+ log_Printf(LogWARN, "Clone: %s: name already exists\n", name);
+ return 0;
+ }
+
+ bundle_DatalinkLinkin(bundle, datalink_Clone(dl, name));
+ return 1;
+}
+
+void
+bundle_DatalinkRemove(struct bundle *bundle, struct datalink *dl)
+{
+ dl = bundle_DatalinkLinkout(bundle, dl);
+ if (dl)
+ datalink_Destroy(dl);
}
void
@@ -1310,9 +1503,7 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
niov = 1;
dl = iov2datalink(bundle, iov, &niov, sizeof iov / sizeof *iov, link_fd);
if (dl) {
- dl->next = bundle->links;
- bundle->links = dl;
- bundle_GenPhysType(bundle);
+ bundle_DatalinkLinkin(bundle, dl);
datalink_AuthOk(dl);
} else
close(link_fd);
@@ -1328,21 +1519,11 @@ bundle_SendDatalink(struct datalink *dl, int s, struct sockaddr_un *sun)
struct msghdr msg;
struct iovec iov[SCATTER_SEGMENTS];
int niov, link_fd, f, expect;
- struct datalink **pdl;
- struct bundle *bundle = dl->bundle;
log_Printf(LogPHASE, "Transmitting datalink %s\n", dl->name);
- /* First, un-hook the datalink */
- for (pdl = &bundle->links; *pdl; pdl = &(*pdl)->next)
- if (*pdl == dl) {
- *pdl = dl->next;
- dl->next = NULL;
- break;
- }
-
- bundle_GenPhysType(bundle);
- bundle_LinkClosed(bundle, dl);
+ bundle_DatalinkLinkout(dl->bundle, dl);
+ bundle_LinkClosed(dl->bundle, dl);
/* Build our scatter/gather array */
iov[0].iov_len = strlen(Version) + 1;
@@ -1423,7 +1604,8 @@ bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
if (mode == PHYS_DEMAND && !(bundle->phys_type & PHYS_DEMAND))
ipcp_InterfaceUp(&bundle->ncp.ipcp);
- bundle_GenPhysType(bundle);
+ /* Regenerate phys_type and adjust autoload & idle timers */
+ bundle_LinksRemoved(bundle);
if (omode == PHYS_DEMAND && !(bundle->phys_type & PHYS_DEMAND))
/* Changing from demand-dial mode */
diff --git a/usr.sbin/ppp/bundle.h b/usr.sbin/ppp/bundle.h
index 1c1daf567dea..36ef9657b844 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.1.2.40 1998/05/15 23:58:15 brian Exp $
+ * $Id: bundle.h,v 1.1.2.41 1998/05/16 23:47:21 brian Exp $
*/
#define PHASE_DEAD 0 /* Link is dead */
@@ -85,6 +85,13 @@ struct bundle {
unsigned opt; /* Uses OPT_ bits from above */
char label[50]; /* last thing `load'ed */
u_short mtu; /* Interface mtu */
+
+ struct { /* We need/don't need another link when */
+ struct { /* more/less than */
+ int packets; /* this number of packets are queued for */
+ int timeout; /* this number of seconds */
+ } max, min;
+ } autoload;
} cfg;
struct {
@@ -107,6 +114,13 @@ struct bundle {
struct {
int fd; /* write status here */
} notify;
+
+ struct {
+ struct pppTimer timer;
+ time_t done;
+ unsigned running : 1;
+ unsigned comingup : 1;
+ } autoload;
};
#define descriptor2bundle(d) \
@@ -131,7 +145,6 @@ extern int bundle_ShowStatus(struct cmdargs const *);
extern void bundle_StartIdleTimer(struct bundle *);
extern void bundle_SetIdleTimer(struct bundle *, int);
extern void bundle_StopIdleTimer(struct bundle *);
-extern int bundle_RemainingIdleTime(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 f14f467b794f..2f9765f9fe9f 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.131.2.86 1998/05/16 23:47:41 brian Exp $
+ * $Id: command.c,v 1.131.2.87 1998/05/19 19:58:18 brian Exp $
*
*/
#include <sys/types.h>
@@ -85,25 +85,26 @@
#define VAR_DIAL 1
#define VAR_LOGIN 2
#define VAR_AUTHNAME 3
-#define VAR_WINSIZE 4
-#define VAR_DEVICE 5
-#define VAR_ACCMAP 6
-#define VAR_MRRU 7
-#define VAR_MRU 8
-#define VAR_MTU 9
-#define VAR_OPENMODE 10
-#define VAR_PHONE 11
-#define VAR_HANGUP 12
-#define VAR_IDLETIMEOUT 13
-#define VAR_LQRPERIOD 14
-#define VAR_LCPRETRY 15
-#define VAR_CHAPRETRY 16
-#define VAR_PAPRETRY 17
-#define VAR_CCPRETRY 18
-#define VAR_IPCPRETRY 19
-#define VAR_DNS 20
-#define VAR_NBNS 21
-#define VAR_MODE 22
+#define VAR_AUTOLOAD 4
+#define VAR_WINSIZE 5
+#define VAR_DEVICE 6
+#define VAR_ACCMAP 7
+#define VAR_MRRU 8
+#define VAR_MRU 9
+#define VAR_MTU 10
+#define VAR_OPENMODE 11
+#define VAR_PHONE 12
+#define VAR_HANGUP 13
+#define VAR_IDLETIMEOUT 14
+#define VAR_LQRPERIOD 15
+#define VAR_LCPRETRY 16
+#define VAR_CHAPRETRY 17
+#define VAR_PAPRETRY 18
+#define VAR_CCPRETRY 19
+#define VAR_IPCPRETRY 20
+#define VAR_DNS 21
+#define VAR_NBNS 22
+#define VAR_MODE 23
/* ``accept|deny|disable|enable'' masks */
#define NEG_HISMASK (1)
@@ -123,7 +124,7 @@
#define NEG_DNS 50
const char Version[] = "2.0-beta";
-const char VersionDate[] = "$Date: 1998/05/16 23:47:41 $";
+const char VersionDate[] = "$Date: 1998/05/19 19:58:18 $";
static int ShowCommand(struct cmdargs const *);
static int TerminalCommand(struct cmdargs const *);
@@ -1196,6 +1197,23 @@ SetVariable(struct cmdargs const *arg)
log_Printf(LogWARN, err);
}
break;
+ case VAR_AUTOLOAD:
+ if (arg->argc == arg->argn + 2 || arg->argc == arg->argn + 4) {
+ arg->bundle->autoload.running = 1;
+ arg->bundle->cfg.autoload.max.timeout = atoi(arg->argv[arg->argn]);
+ arg->bundle->cfg.autoload.max.packets = atoi(arg->argv[arg->argn + 1]);
+ if (arg->argc == arg->argn + 4) {
+ arg->bundle->cfg.autoload.min.timeout = atoi(arg->argv[arg->argn + 2]);
+ arg->bundle->cfg.autoload.min.packets = atoi(arg->argv[arg->argn + 3]);
+ } else {
+ arg->bundle->cfg.autoload.min.timeout = 0;
+ arg->bundle->cfg.autoload.min.packets = 0;
+ }
+ } else {
+ err = "Set autoload requires two or four arguments\n";
+ log_Printf(LogWARN, err);
+ }
+ break;
case VAR_DIAL:
strncpy(cx->cfg.script.dial, argp, sizeof cx->cfg.script.dial - 1);
cx->cfg.script.dial[sizeof cx->cfg.script.dial - 1] = '\0';
@@ -1412,6 +1430,9 @@ static struct cmdtab const SetCommands[] = {
"authentication key", "set authkey|key key", (const void *)VAR_AUTHKEY},
{"authname", NULL, SetVariable, LOCAL_AUTH,
"authentication name", "set authname name", (const void *)VAR_AUTHNAME},
+ {"autoload", NULL, SetVariable, LOCAL_AUTH,
+ "auto link [de]activation", "set autoload maxtime maxload mintime minload",
+ (const void *)VAR_AUTOLOAD},
{"ccpretry", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
"FSM retry period", "set ccpretry value", (const void *)VAR_CCPRETRY},
{"chapretry", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
diff --git a/usr.sbin/ppp/ppp.8 b/usr.sbin/ppp/ppp.8
index 20803d5d3685..b3a50e181de8 100644
--- a/usr.sbin/ppp/ppp.8
+++ b/usr.sbin/ppp/ppp.8
@@ -1,4 +1,4 @@
-.\" $Id: ppp.8,v 1.97.2.36 1998/05/18 23:24:24 brian Exp $
+.\" $Id: ppp.8,v 1.97.2.37 1998/05/19 19:58:21 brian Exp $
.Dd 20 September 1995
.Os FreeBSD
.Dt PPP 8
@@ -2472,6 +2472,36 @@ is logged as
for security reasons.
.It set authname Ar id
This sets the authentication id used in client mode PAP or CHAP negotiation.
+.It set autoload Ar maxduration maxload Op Ar minduration minload
+These settings apply only in multilink mode and all default to zero.
+When more than one
+.Ar demand-dial
+.Pq also known as Fl auto
+mode link is available, only the first link is made active when
+.Nm
+first reads data from the tun device. The next
+.Ar demand-dial
+link will be opened only when at least
+.Ar maxload
+packets have been in the send queue for
+.Ar maxduration
+seconds. Because both values default to zero,
+.Ar demand-dial
+links will simply come up one at a time by default.
+.Pp
+If two or more links are open, at least one of which is a
+.Ar demand-dial
+link, a
+.Ar demand-dial
+link will be closed when there is less than
+.Ar minpackets
+in the queue for more than
+.Ar minduration .
+If
+.Ar minduration
+is zero, this timer is disabled. Because both values default to zero,
+.Ar demand-dial
+links will stay active until the bundle idle timer expires.
.It set ctsrts|crtscts on|off
This sets hardware flow control. Hardware flow control is
.Ar on