summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/bundle.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1999-08-05 10:32:16 +0000
committerbrian <brian@FreeBSD.org>1999-08-05 10:32:16 +0000
commit75000c38838f6ae4afe9de4dd06bd3fde6120e1b (patch)
tree26404e4742c87264dac32602be9ec171a2100df1 /usr.sbin/ppp/bundle.c
parentc32597f76112e043f5178c1c2237ad6d753da072 (diff)
downloadFreeBSD-src-75000c38838f6ae4afe9de4dd06bd3fde6120e1b.zip
FreeBSD-src-75000c38838f6ae4afe9de4dd06bd3fde6120e1b.tar.gz
o Obsolete the undocumented ``set weight'' command.
o If we're using RADIUS and the RADIUS mtu is less than our peers mru/mrru, reduce our mtu to this value for NetBSD too. o Make struct throughput's sample period dynamic and tweak the ppp version number to reflect the extra stuff being passed through the local domain socket as a result (MP mode). o Measure the current throughput based on the number of samples actually taken rather than on the full sample period. o Keep the throughput statisics persistent while being passed to another ppp invocation through the local domain socket. o When showing throughput statistics after the timer has stopped, use the stopped time for overall calculations, not the current time. Also show the stopped time and how long the current throughput has been sampled for. o Use time() consistently in throughput.c o Tighten up the ``show bundle'' output. o Introduce the ``set bandwidth'' command. o Rewrite the ``set autoload'' command. It now takes three arguments and works based on a rolling bundle throughput average compared against the theoretical bundle bandwidth over a given period (read: it's now functional).
Diffstat (limited to 'usr.sbin/ppp/bundle.c')
-rw-r--r--usr.sbin/ppp/bundle.c344
1 files changed, 157 insertions, 187 deletions
diff --git a/usr.sbin/ppp/bundle.c b/usr.sbin/ppp/bundle.c
index 3f871fb..9d55dfe 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.57 1999/06/22 11:31:42 brian Exp $
+ * $Id: bundle.c,v 1.58 1999/07/27 23:43:58 brian Exp $
*/
#include <sys/param.h>
@@ -87,12 +87,12 @@
#include "ip.h"
#include "iface.h"
-#define SCATTER_SEGMENTS 5 /* version, datalink, name, physical, device */
+#define SCATTER_SEGMENTS 6 /* version, datalink, name, physical,
+ throughput, device */
#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"
@@ -195,110 +195,12 @@ bundle_ClearQueues(void *v)
}
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_AUTO, 0);
- } 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_AUTO && dl->state == DATALINK_OPEN)
- last = dl;
-
- if (last)
- datalink_Close(last, CLOSE_STAYDOWN);
- }
-}
-
-static void
-bundle_StartAutoLoadTimer(struct bundle *bundle, int up)
-{
- struct datalink *dl;
-
- timer_Stop(&bundle->autoload.timer);
- bundle->autoload.comingup = up ? 1 : 0;
-
- 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_AUTO) {
- 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_AUTO)
- 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;
- }
-}
-
-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_LinkAdded(struct bundle *bundle, struct datalink *dl)
{
bundle->phys_type.all |= dl->physical->type;
if (dl->state == DATALINK_OPEN)
bundle->phys_type.open |= dl->physical->type;
- /* Note: We only re-add links that are DATALINK_OPEN */
- if (dl->physical->type == PHYS_AUTO &&
- bundle->autoload.timer.state == TIMER_STOPPED &&
- dl->state != DATALINK_OPEN &&
- bundle->phase == PHASE_NETWORK)
- bundle->autoload.running = 1;
-
if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
!= bundle->phys_type.open && bundle->idle.timer.state == TIMER_STOPPED)
/* We may need to start our idle timer */
@@ -314,6 +216,9 @@ bundle_LinksRemoved(struct bundle *bundle)
for (dl = bundle->links; dl; dl = dl->next)
bundle_LinkAdded(bundle, dl);
+ bundle_CalculateBandwidth(bundle);
+ mp_CheckAutoloadTimer(&bundle->ncp.mp);
+
if ((bundle->phys_type.open & (PHYS_DEDICATED|PHYS_DDIAL))
== bundle->phys_type.open)
bundle_StopIdleTimer(bundle);
@@ -324,11 +229,12 @@ bundle_LayerUp(void *v, struct fsm *fp)
{
/*
* The given fsm is now up
- * If it's an LCP, adjust our phys_mode.open value.
- * If it's an LCP set our mtu (if we're multilink, add up the link
- * 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 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, 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
*/
struct bundle *bundle = (struct bundle *)v;
@@ -336,22 +242,12 @@ bundle_LayerUp(void *v, struct fsm *fp)
struct physical *p = link2physical(fp->link);
bundle_LinkAdded(bundle, p->dl);
- if (bundle->ncp.mp.active) {
- struct datalink *dl;
-
- bundle->ifSpeed = 0;
- for (dl = bundle->links; dl; dl = dl->next)
- if (dl->state == DATALINK_OPEN)
- bundle->ifSpeed += physical_GetSpeed(dl->physical);
- tun_configure(bundle, bundle->ncp.mp.peer_mrru);
- bundle->autoload.running = 1;
- } else {
- bundle->ifSpeed = physical_GetSpeed(p);
- tun_configure(bundle, fsm2lcp(fp)->his_mru);
- }
+ mp_CheckAutoloadTimer(&bundle->ncp.mp);
} else if (fp->proto == PROTO_IPCP) {
+ bundle_CalculateBandwidth(fp->bundle);
bundle_StartIdleTimer(bundle);
bundle_Notify(bundle, EX_NORMAL);
+ mp_CheckAutoloadTimer(&fp->bundle->ncp.mp);
}
}
@@ -361,6 +257,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, 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
* speed and make sure our minimum sequence number is adjusted.
@@ -368,25 +265,21 @@ bundle_LayerDown(void *v, struct fsm *fp)
struct bundle *bundle = (struct bundle *)v;
- if (fp->proto == PROTO_IPCP)
+ if (fp->proto == PROTO_IPCP) {
bundle_StopIdleTimer(bundle);
- else if (fp->proto == PROTO_LCP) {
+ mp_StopAutoloadTimer(&bundle->ncp.mp);
+ } else if (fp->proto == PROTO_LCP) {
bundle_LinksRemoved(bundle); /* adjust timers & phys_type values */
if (bundle->ncp.mp.active) {
struct datalink *dl;
struct datalink *lost;
- bundle->ifSpeed = 0;
lost = NULL;
for (dl = bundle->links; dl; dl = dl->next)
if (fp == &dl->physical->link.lcp.fsm)
lost = dl;
- else if (dl->state == DATALINK_OPEN)
- bundle->ifSpeed += physical_GetSpeed(dl->physical);
- if (bundle->ifSpeed)
- /* Don't configure down to a speed of 0 */
- tun_configure(bundle, bundle->ncp.mp.link.lcp.his_mru);
+ bundle_CalculateBandwidth(bundle);
if (lost)
mp_LinkLost(&bundle->ncp.mp, lost);
@@ -474,7 +367,6 @@ bundle_Close(struct bundle *bundle, const char *name, int how)
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);
@@ -502,7 +394,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;
- int result, want, queued, nlinks;
+ int result, queued, nlinks;
result = 0;
@@ -512,27 +404,11 @@ bundle_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
if (nlinks) {
queued = r ? bundle_FillQueues(bundle) : ip_QueueLen(&bundle->ncp.ipcp);
- 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_Phase(bundle) == PHASE_NETWORK || queued) &&
- (bundle->autoload.timer.state != TIMER_RUNNING ||
- !bundle->autoload.comingup))
- bundle_StartAutoLoadTimer(bundle, 1);
- }
if (r && (bundle->phase == PHASE_NETWORK ||
bundle->phys_type.all & PHYS_AUTO)) {
/* 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) {
+ if (queued < 20) {
/* Not enough - select() for more */
if (bundle->choked.timer.state == TIMER_RUNNING)
timer_Stop(&bundle->choked.timer); /* Not needed any more */
@@ -797,7 +673,7 @@ bundle_Create(const char *prefix, int type, const char **argv)
log_Printf(LogPHASE, "Using interface: %s\n", ifname);
- bundle.ifSpeed = 0;
+ bundle.bandwidth = 0;
bundle.routing_seq = 0;
bundle.phase = PHASE_DEAD;
bundle.CleaningUp = 0;
@@ -816,10 +692,6 @@ bundle_Create(const char *prefix, int type, const char **argv)
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.cfg.choked.timeout = CHOKED_TIMEOUT;
bundle.phys_type.all = type;
bundle.phys_type.open = 0;
@@ -866,9 +738,6 @@ bundle_Create(const char *prefix, int type, const char **argv)
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;
memset(&bundle.choked.timer, '\0', sizeof bundle.choked.timer);
#ifndef NORADIUS
radius_Init(&bundle.radius);
@@ -901,7 +770,6 @@ bundle_Destroy(struct bundle *bundle)
*/
timer_Stop(&bundle->idle.timer);
timer_Stop(&bundle->choked.timer);
- timer_Stop(&bundle->autoload.timer);
mp_Down(&bundle->ncp.mp);
ipcp_CleanInterface(&bundle->ncp.ipcp);
bundle_DownInterface(bundle);
@@ -1074,10 +942,7 @@ bundle_LinkClosed(struct bundle *bundle, struct datalink *dl)
fsm2initial(&bundle->ncp.ipcp.fsm);
bundle_NewPhase(bundle, PHASE_DEAD);
bundle_StopIdleTimer(bundle);
- bundle_StopAutoLoadTimer(bundle);
- bundle->autoload.running = 0;
- } else
- bundle->autoload.running = 1;
+ }
}
void
@@ -1088,7 +953,6 @@ bundle_Open(struct bundle *bundle, const char *name, int mask, int force)
*/
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) &&
@@ -1098,8 +962,8 @@ bundle_Open(struct bundle *bundle, const char *name, int mask, int force)
if (force) /* Ignore redial timeout ? */
timer_Stop(&dl->dial.timer);
datalink_Up(dl, 1, 1);
- if (mask == PHYS_AUTO)
- /* Only one AUTO link at a time (see the AutoLoad timer) */
+ if (mask & PHYS_AUTO)
+ /* Only one AUTO link at a time */
break;
}
if (name != NULL)
@@ -1149,17 +1013,30 @@ int
bundle_ShowLinks(struct cmdargs const *arg)
{
struct datalink *dl;
+ struct pppThroughput *t;
+ int secs;
for (dl = arg->bundle->links; dl; dl = dl->next) {
prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
- prompt_Printf(arg->prompt, " weight %d, %Ld bytes/sec",
- dl->mp.weight,
+ prompt_Printf(arg->prompt, " bandwidth %d, %qu bps (%qu bytes/sec)",
+ dl->mp.bandwidth ? dl->mp.bandwidth :
+ physical_GetSpeed(dl->physical),
+ dl->physical->link.throughput.OctetsPerSecond * 8,
dl->physical->link.throughput.OctetsPerSecond);
prompt_Printf(arg->prompt, "\n");
}
+ t = &arg->bundle->ncp.mp.link.throughput;
+ secs = t->downtime ? 0 : throughput_uptime(t);
+ if (secs > t->SamplePeriod)
+ secs = t->SamplePeriod;
+ if (secs)
+ prompt_Printf(arg->prompt, "Currently averaging %qu bps (%qu bytes/sec)"
+ " over the last %d secs\n", t->OctetsPerSecond * 8,
+ t->OctetsPerSecond, secs);
+
return 0;
}
@@ -1178,27 +1055,12 @@ bundle_ShowStatus(struct cmdargs const *arg)
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",
- arg->bundle->iface->name, arg->bundle->ifSpeed);
+ arg->bundle->iface->name, arg->bundle->bandwidth);
prompt_Printf(arg->prompt, "\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);
- 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(&arg->bundle->ncp.ipcp));
prompt_Printf(arg->prompt, " Choked Timer: %ds\n",
arg->bundle->cfg.choked.timeout);
@@ -1224,32 +1086,32 @@ bundle_ShowStatus(struct cmdargs const *arg)
prompt_Printf(arg->prompt, " sendpipe: ");
if (arg->bundle->ncp.ipcp.cfg.sendpipe > 0)
- prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.sendpipe);
+ prompt_Printf(arg->prompt, "%-20ld", arg->bundle->ncp.ipcp.cfg.sendpipe);
else
- prompt_Printf(arg->prompt, "unspecified\n");
+ prompt_Printf(arg->prompt, "unspecified ");
prompt_Printf(arg->prompt, " recvpipe: ");
if (arg->bundle->ncp.ipcp.cfg.recvpipe > 0)
prompt_Printf(arg->prompt, "%ld\n", arg->bundle->ncp.ipcp.cfg.recvpipe);
else
prompt_Printf(arg->prompt, "unspecified\n");
- prompt_Printf(arg->prompt, " Sticky Routes: %s\n",
+ prompt_Printf(arg->prompt, " Sticky Routes: %-20.20s",
optval(arg->bundle, OPT_SROUTES));
prompt_Printf(arg->prompt, " ID check: %s\n",
optval(arg->bundle, OPT_IDCHECK));
- prompt_Printf(arg->prompt, " Keep-Session: %s\n",
+ prompt_Printf(arg->prompt, " Keep-Session: %-20.20s",
optval(arg->bundle, OPT_KEEPSESSION));
prompt_Printf(arg->prompt, " Loopback: %s\n",
optval(arg->bundle, OPT_LOOPBACK));
- prompt_Printf(arg->prompt, " PasswdAuth: %s\n",
+ prompt_Printf(arg->prompt, " PasswdAuth: %-20.20s",
optval(arg->bundle, OPT_PASSWDAUTH));
prompt_Printf(arg->prompt, " Proxy: %s\n",
optval(arg->bundle, OPT_PROXY));
- prompt_Printf(arg->prompt, " Proxyall: %s\n",
+ prompt_Printf(arg->prompt, " Proxyall: %-20.20s",
optval(arg->bundle, OPT_PROXYALL));
prompt_Printf(arg->prompt, " Throughput: %s\n",
optval(arg->bundle, OPT_THROUGHPUT));
- prompt_Printf(arg->prompt, " Utmp Logging: %s\n",
+ prompt_Printf(arg->prompt, " Utmp Logging: %-20.20s",
optval(arg->bundle, OPT_UTMP));
prompt_Printf(arg->prompt, " Iface-Alias: %s\n",
optval(arg->bundle, OPT_IFACEALIAS));
@@ -1343,6 +1205,7 @@ bundle_DatalinkLinkin(struct bundle *bundle, struct datalink *dl)
dl->next = NULL;
bundle_LinkAdded(bundle, dl);
+ mp_CheckAutoloadTimer(&bundle->ncp.mp);
}
void
@@ -1483,6 +1346,7 @@ bundle_ReceiveDatalink(struct bundle *bundle, int s, struct sockaddr_un *sun)
if (dl) {
bundle_DatalinkLinkin(bundle, dl);
datalink_AuthOk(dl);
+ bundle_CalculateBandwidth(dl->bundle);
} else
close(link_fd);
@@ -1593,7 +1457,7 @@ bundle_SetMode(struct bundle *bundle, struct datalink *dl, int mode)
/* First auto link, we need an interface */
ipcp_InterfaceUp(&bundle->ncp.ipcp);
- /* Regenerate phys_type and adjust autoload & idle timers */
+ /* Regenerate phys_type and adjust idle timer */
bundle_LinksRemoved(bundle);
return 1;
@@ -1740,3 +1604,109 @@ bundle_AdjustFilters(struct bundle *bundle, struct in_addr *my_ip,
filter_AdjustAddr(&bundle->filter.dial, my_ip, peer_ip);
filter_AdjustAddr(&bundle->filter.alive, my_ip, peer_ip);
}
+
+void
+bundle_CalculateBandwidth(struct bundle *bundle)
+{
+ struct datalink *dl;
+ int mtu, sp;
+
+ bundle->bandwidth = 0;
+ mtu = 0;
+ for (dl = bundle->links; dl; dl = dl->next)
+ if (dl->state == DATALINK_OPEN) {
+ if ((sp = dl->mp.bandwidth) == 0 &&
+ (sp = physical_GetSpeed(dl->physical)) == 0)
+ log_Printf(LogDEBUG, "%s: %s: Cannot determine bandwidth\n",
+ dl->name, dl->physical->name.full);
+ else
+ bundle->bandwidth += sp;
+ if (!bundle->ncp.mp.active) {
+ mtu = dl->physical->link.lcp.his_mru;
+ break;
+ }
+ }
+
+ if(bundle->bandwidth == 0)
+ bundle->bandwidth = 115200; /* Shrug */
+
+ if (bundle->ncp.mp.active)
+ mtu = bundle->ncp.mp.peer_mrru;
+ else if (!mtu)
+ mtu = 1500;
+
+#ifndef NORADIUS
+ if (bundle->radius.valid && bundle->radius.mtu && bundle->radius.mtu < mtu) {
+ log_Printf(LogLCP, "Reducing MTU to radius value %lu\n",
+ bundle->radius.mtu);
+ mtu = bundle->radius.mtu;
+ }
+#endif
+
+ tun_configure(bundle, mtu);
+}
+
+void
+bundle_AutoAdjust(struct bundle *bundle, int percent, int what)
+{
+ struct datalink *dl, *choice, *otherlinkup;
+
+ choice = otherlinkup = NULL;
+ for (dl = bundle->links; dl; dl = dl->next)
+ if (dl->physical->type == PHYS_AUTO) {
+ if (dl->state == DATALINK_OPEN) {
+ if (what == AUTO_DOWN) {
+ if (choice)
+ otherlinkup = choice;
+ choice = dl;
+ }
+ } else if (dl->state == DATALINK_CLOSED) {
+ if (what == AUTO_UP) {
+ choice = dl;
+ break;
+ }
+ } else {
+ /* An auto link in an intermediate state - forget it for the moment */
+ choice = NULL;
+ break;
+ }
+ } else if (dl->state == DATALINK_OPEN && what == AUTO_DOWN)
+ otherlinkup = dl;
+
+ if (choice) {
+ if (what == AUTO_UP) {
+ log_Printf(LogPHASE, "%d%% saturation -> Opening link ``%s''\n",
+ percent, choice->name);
+ datalink_Up(choice, 1, 1);
+ mp_StopAutoloadTimer(&bundle->ncp.mp);
+ } else if (otherlinkup) { /* Only bring the second-last link down */
+ log_Printf(LogPHASE, "%d%% saturation -> Closing link ``%s''\n",
+ percent, choice->name);
+ datalink_Down(choice, CLOSE_NORMAL);
+ mp_StopAutoloadTimer(&bundle->ncp.mp);
+ }
+ }
+}
+
+int
+bundle_WantAutoloadTimer(struct bundle *bundle)
+{
+ struct datalink *dl;
+ int autolink, opened;
+
+ if (bundle->phase == PHASE_NETWORK) {
+ for (autolink = opened = 0, dl = bundle->links; dl; dl = dl->next)
+ if (dl->physical->type == PHYS_AUTO) {
+ if (++autolink == 2 || (autolink == 1 && opened))
+ /* Two auto links or one auto and one open in NETWORK phase */
+ return 1;
+ } else if (dl->state == DATALINK_OPEN) {
+ opened++;
+ if (autolink)
+ /* One auto and one open link in NETWORK phase */
+ return 1;
+ }
+ }
+
+ return 0;
+}
OpenPOWER on IntegriCloud