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).
This commit is contained in:
Brian Somers 1998-05-21 01:13:32 +00:00
parent b1d2f6fa1c
commit 04eaa58c59
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/cvs2svn/branches/MP/; revision=36268
4 changed files with 341 additions and 95 deletions

View File

@ -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"
};
@ -202,13 +205,106 @@ 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;
bundle_LinkAdded(bundle, dl);
if ((bundle->phys_type & (PHYS_DEDICATED|PHYS_PERM)) == bundle->phys_type)
timer_Stop(&bundle->idle.timer);
}
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;
}
log_Printf(LogWARN, "Clone: %s: name already exists\n", ndl->name);
return 0;
}
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 */

View File

@ -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 *);

View File

@ -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,

View File

@ -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