mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-30 08:19:09 +00:00
Calculate the average link throughput using a counter based on the
cumulative total of all active links rather than basing it on the total of PROTO_MP traffic. This fixes a problem whereby Cisco routers send PROTO_IP packets only when there's only one link (hmm, what a good idea!).
This commit is contained in:
parent
66ce51cec7
commit
11572abf62
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=64652
@ -1122,16 +1122,16 @@ bundle_ShowLinks(struct cmdargs const *arg)
|
||||
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)
|
||||
if (dl->physical->link.stats.total.rolling && dl->state == DATALINK_OPEN)
|
||||
prompt_Printf(arg->prompt, " bandwidth %d, %llu bps (%llu bytes/sec)",
|
||||
dl->mp.bandwidth ? dl->mp.bandwidth :
|
||||
physical_GetSpeed(dl->physical),
|
||||
dl->physical->link.throughput.OctetsPerSecond * 8,
|
||||
dl->physical->link.throughput.OctetsPerSecond);
|
||||
dl->physical->link.stats.total.OctetsPerSecond * 8,
|
||||
dl->physical->link.stats.total.OctetsPerSecond);
|
||||
prompt_Printf(arg->prompt, "\n");
|
||||
}
|
||||
|
||||
t = &arg->bundle->ncp.mp.link.throughput;
|
||||
t = &arg->bundle->ncp.mp.link.stats.total;
|
||||
secs = t->downtime ? 0 : throughput_uptime(t);
|
||||
if (secs > t->SamplePeriod)
|
||||
secs = t->SamplePeriod;
|
||||
|
@ -2599,7 +2599,7 @@ ClearCommand(struct cmdargs const *arg)
|
||||
log_Printf(LogWARN, "A link must be specified for ``clear physical''\n");
|
||||
return 1;
|
||||
}
|
||||
t = &cx->physical->link.throughput;
|
||||
t = &cx->physical->link.stats.total;
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "ipcp") == 0)
|
||||
t = &arg->bundle->ncp.ipcp.throughput;
|
||||
else
|
||||
|
@ -67,16 +67,24 @@
|
||||
|
||||
static void Despatch(struct bundle *, struct link *, struct mbuf *, u_short);
|
||||
|
||||
void
|
||||
static inline void
|
||||
link_AddInOctets(struct link *l, int n)
|
||||
{
|
||||
throughput_addin(&l->throughput, n);
|
||||
if (l->stats.gather) {
|
||||
throughput_addin(&l->stats.total, n);
|
||||
if (l->stats.parent)
|
||||
throughput_addin(l->stats.parent, n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
static inline void
|
||||
link_AddOutOctets(struct link *l, int n)
|
||||
{
|
||||
throughput_addout(&l->throughput, n);
|
||||
if (l->stats.gather) {
|
||||
throughput_addout(&l->stats.total, n);
|
||||
if (l->stats.parent)
|
||||
throughput_addout(l->stats.parent, n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -41,7 +41,11 @@ struct link {
|
||||
int type; /* _LINK type */
|
||||
const char *name; /* Points to datalink::name */
|
||||
int len; /* full size of parent struct */
|
||||
struct pppThroughput throughput; /* Link throughput statistics */
|
||||
struct {
|
||||
unsigned gather : 1; /* Gather statistics ourself ? */
|
||||
struct pppThroughput total; /* Link throughput statistics */
|
||||
struct pppThroughput *parent; /* MP link throughput statistics */
|
||||
} stats;
|
||||
struct mqueue Queue[2]; /* Our output queue of mbufs */
|
||||
|
||||
u_long proto_in[NPROTOSTAT]; /* outgoing protocol stats */
|
||||
@ -57,9 +61,6 @@ struct link {
|
||||
#define LINK_QUEUES(link) (sizeof (link)->Queue / sizeof (link)->Queue[0])
|
||||
#define LINK_HIGHQ(link) ((link)->Queue + LINK_QUEUES(link) - 1)
|
||||
|
||||
extern void link_AddInOctets(struct link *, int);
|
||||
extern void link_AddOutOctets(struct link *, int);
|
||||
|
||||
extern void link_SequenceQueue(struct link *);
|
||||
extern void link_DeleteQueue(struct link *);
|
||||
extern size_t link_QueueLen(struct link *);
|
||||
|
@ -189,7 +189,7 @@ mp_UpDown(void *v)
|
||||
struct mp *mp = (struct mp *)v;
|
||||
int percent;
|
||||
|
||||
percent = mp->link.throughput.OctetsPerSecond * 800 / mp->bundle->bandwidth;
|
||||
percent = mp->link.stats.total.OctetsPerSecond * 800 / mp->bundle->bandwidth;
|
||||
if (percent >= mp->cfg.autoload.max) {
|
||||
log_Printf(LogDEBUG, "%d%% saturation - bring a link up ?\n", percent);
|
||||
bundle_AutoAdjust(mp->bundle, percent, AUTO_UP);
|
||||
@ -202,20 +202,20 @@ mp_UpDown(void *v)
|
||||
void
|
||||
mp_StopAutoloadTimer(struct mp *mp)
|
||||
{
|
||||
throughput_stop(&mp->link.throughput);
|
||||
throughput_stop(&mp->link.stats.total);
|
||||
}
|
||||
|
||||
void
|
||||
mp_CheckAutoloadTimer(struct mp *mp)
|
||||
{
|
||||
if (mp->link.throughput.SamplePeriod != mp->cfg.autoload.period) {
|
||||
throughput_destroy(&mp->link.throughput);
|
||||
throughput_init(&mp->link.throughput, mp->cfg.autoload.period);
|
||||
throughput_callback(&mp->link.throughput, mp_UpDown, mp);
|
||||
if (mp->link.stats.total.SamplePeriod != mp->cfg.autoload.period) {
|
||||
throughput_destroy(&mp->link.stats.total);
|
||||
throughput_init(&mp->link.stats.total, mp->cfg.autoload.period);
|
||||
throughput_callback(&mp->link.stats.total, mp_UpDown, mp);
|
||||
}
|
||||
|
||||
if (bundle_WantAutoloadTimer(mp->bundle))
|
||||
throughput_start(&mp->link.throughput, "MP throughput", 1);
|
||||
throughput_start(&mp->link.stats.total, "MP throughput", 1);
|
||||
else
|
||||
mp_StopAutoloadTimer(mp);
|
||||
}
|
||||
@ -223,10 +223,10 @@ mp_CheckAutoloadTimer(struct mp *mp)
|
||||
void
|
||||
mp_RestartAutoloadTimer(struct mp *mp)
|
||||
{
|
||||
if (mp->link.throughput.SamplePeriod != mp->cfg.autoload.period)
|
||||
if (mp->link.stats.total.SamplePeriod != mp->cfg.autoload.period)
|
||||
mp_CheckAutoloadTimer(mp);
|
||||
else
|
||||
throughput_clear(&mp->link.throughput, THROUGHPUT_OVERALL, NULL);
|
||||
throughput_clear(&mp->link.stats.total, THROUGHPUT_OVERALL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
@ -250,8 +250,10 @@ mp_Init(struct mp *mp, struct bundle *bundle)
|
||||
|
||||
mp->cfg.autoload.period = SAMPLE_PERIOD;
|
||||
mp->cfg.autoload.min = mp->cfg.autoload.max = 0;
|
||||
throughput_init(&mp->link.throughput, mp->cfg.autoload.period);
|
||||
throughput_callback(&mp->link.throughput, mp_UpDown, mp);
|
||||
throughput_init(&mp->link.stats.total, mp->cfg.autoload.period);
|
||||
throughput_callback(&mp->link.stats.total, mp_UpDown, mp);
|
||||
mp->link.stats.parent = NULL;
|
||||
mp->link.stats.gather = 0; /* Let the physical links gather stats */
|
||||
memset(mp->link.Queue, '\0', sizeof mp->link.Queue);
|
||||
memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in);
|
||||
memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out);
|
||||
@ -318,13 +320,16 @@ mp_Up(struct mp *mp, struct datalink *dl)
|
||||
mp->peer_is12bit = lcp->his_shortseq;
|
||||
mp->peer = dl->peer;
|
||||
|
||||
throughput_destroy(&mp->link.throughput);
|
||||
throughput_init(&mp->link.throughput, mp->cfg.autoload.period);
|
||||
throughput_callback(&mp->link.throughput, mp_UpDown, mp);
|
||||
throughput_destroy(&mp->link.stats.total);
|
||||
throughput_init(&mp->link.stats.total, mp->cfg.autoload.period);
|
||||
throughput_callback(&mp->link.stats.total, mp_UpDown, mp);
|
||||
memset(mp->link.Queue, '\0', sizeof mp->link.Queue);
|
||||
memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in);
|
||||
memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out);
|
||||
|
||||
/* Tell the link who it belongs to */
|
||||
dl->physical->link.stats.parent = &mp->link.stats.total;
|
||||
|
||||
mp->out.seq = 0;
|
||||
mp->out.link = 0;
|
||||
mp->seq.min_in = 0;
|
||||
|
@ -158,7 +158,10 @@ physical_Create(struct datalink *dl, int type)
|
||||
p->link.len = sizeof *p;
|
||||
|
||||
/* The sample period is fixed - see physical2iov() & iov2physical() */
|
||||
throughput_init(&p->link.throughput, SAMPLE_PERIOD);
|
||||
throughput_init(&p->link.stats.total, SAMPLE_PERIOD);
|
||||
p->link.stats.parent = dl->bundle->ncp.mp.active ?
|
||||
&dl->bundle->ncp.mp.link.stats.total : NULL;
|
||||
p->link.stats.gather = 1;
|
||||
|
||||
memset(p->link.Queue, '\0', sizeof p->link.Queue);
|
||||
memset(p->link.proto_in, '\0', sizeof p->link.proto_in);
|
||||
@ -336,8 +339,8 @@ physical_Close(struct physical *p)
|
||||
p->fd = -1;
|
||||
log_SetTtyCommandMode(p->dl);
|
||||
|
||||
throughput_stop(&p->link.throughput);
|
||||
throughput_log(&p->link.throughput, LogPHASE, p->link.name);
|
||||
throughput_stop(&p->link.stats.total);
|
||||
throughput_log(&p->link.stats.total, LogPHASE, p->link.name);
|
||||
|
||||
if (p->session_owner != (pid_t)-1) {
|
||||
log_Printf(LogPHASE, "%s: HUPing %d\n", p->link.name,
|
||||
@ -371,7 +374,7 @@ void
|
||||
physical_Destroy(struct physical *p)
|
||||
{
|
||||
physical_Close(p);
|
||||
throughput_destroy(&p->link.throughput);
|
||||
throughput_destroy(&p->link.stats.total);
|
||||
free(p);
|
||||
}
|
||||
|
||||
@ -492,7 +495,7 @@ physical_ShowStatus(struct cmdargs const *arg)
|
||||
}
|
||||
prompt_Printf(arg->prompt, "\n\n");
|
||||
|
||||
throughput_disp(&p->link.throughput, arg->prompt);
|
||||
throughput_disp(&p->link.stats.total, arg->prompt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -597,7 +600,10 @@ iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
|
||||
p->hdlc.lqm.timer.state = TIMER_STOPPED;
|
||||
|
||||
p->fd = fd;
|
||||
p->link.throughput.SampleOctets = (long long *)iov[(*niov)++].iov_base;
|
||||
p->link.stats.total.SampleOctets = (long long *)iov[(*niov)++].iov_base;
|
||||
p->link.stats.parent = dl->bundle->ncp.mp.active ?
|
||||
&dl->bundle->ncp.mp.link.stats.total : NULL;
|
||||
p->link.stats.gather = 1;
|
||||
|
||||
type = (long)p->handler;
|
||||
p->handler = NULL;
|
||||
@ -616,7 +622,7 @@ iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
|
||||
lqr_reStart(&p->link.lcp);
|
||||
hdlc_StartTimer(&p->hdlc);
|
||||
|
||||
throughput_restart(&p->link.throughput, "physical throughput",
|
||||
throughput_restart(&p->link.stats.total, "physical throughput",
|
||||
Enabled(dl->bundle, OPT_THROUGHPUT));
|
||||
|
||||
return p;
|
||||
@ -665,7 +671,7 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
|
||||
p->session_owner = getpid(); /* So I'll eventually get HUP'd */
|
||||
else
|
||||
p->session_owner = (pid_t)-1;
|
||||
timer_Stop(&p->link.throughput.Timer);
|
||||
timer_Stop(&p->link.stats.total.Timer);
|
||||
}
|
||||
|
||||
if (*niov + 2 >= maxiov) {
|
||||
@ -680,7 +686,7 @@ physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
|
||||
iov[*niov].iov_len = sizeof *p;
|
||||
(*niov)++;
|
||||
|
||||
iov[*niov].iov_base = p ? (void *)p->link.throughput.SampleOctets : NULL;
|
||||
iov[*niov].iov_base = p ? (void *)p->link.stats.total.SampleOctets : NULL;
|
||||
iov[*niov].iov_len = SAMPLE_PERIOD * sizeof(long long);
|
||||
(*niov)++;
|
||||
|
||||
@ -945,7 +951,7 @@ physical_Found(struct physical *p)
|
||||
#endif
|
||||
}
|
||||
|
||||
throughput_start(&p->link.throughput, "physical throughput",
|
||||
throughput_start(&p->link.stats.total, "physical throughput",
|
||||
Enabled(p->dl->bundle, OPT_THROUGHPUT));
|
||||
p->connect_count++;
|
||||
p->input.sz = 0;
|
||||
|
Loading…
Reference in New Issue
Block a user