summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/lqr.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
committerbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
commit56df88b778aee0e60678672b107a48a8ea05cb48 (patch)
tree13b88ca17b38e787c84b0cd242677b3c3c0b93c3 /usr.sbin/ppp/lqr.c
parente077fa331b8a428923ded3a95d0b8d47084cf670 (diff)
downloadFreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.zip
FreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.tar.gz
MFMP: Make ppp multilink capable.
See the file README.changes, and re-read the man page.
Diffstat (limited to 'usr.sbin/ppp/lqr.c')
-rw-r--r--usr.sbin/ppp/lqr.c339
1 files changed, 188 insertions, 151 deletions
diff --git a/usr.sbin/ppp/lqr.c b/usr.sbin/ppp/lqr.c
index d83c6c5..0d63322 100644
--- a/usr.sbin/ppp/lqr.c
+++ b/usr.sbin/ppp/lqr.c
@@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: lqr.c,v 1.23 1998/03/12 02:23:40 brian Exp $
+ * $Id: lqr.c,v 1.22.2.30 1998/05/08 01:15:08 brian Exp $
*
* o LQR based on RFC1333
*
@@ -25,36 +25,34 @@
* o LQM policy
* o Allow user to configure LQM method and interval.
*/
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <stdio.h>
+#include <sys/types.h>
+#include <sys/un.h>
+
#include <string.h>
+#include <termios.h>
-#include "command.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
#include "timer.h"
#include "fsm.h"
#include "lcpproto.h"
+#include "lcp.h"
#include "lqr.h"
#include "hdlc.h"
-#include "lcp.h"
-#include "loadalias.h"
-#include "vars.h"
-
-struct lqrdata MyLqrData, HisLqrData;
-struct lqrsave HisLqrSave;
-
-static struct pppTimer LqrTimer;
-
-static u_long lastpeerin = (u_long) - 1;
-
-static int lqmmethod;
-static u_int32_t echoseq;
-static u_int32_t gotseq;
-static int lqrsendcnt;
+#include "async.h"
+#include "throughput.h"
+#include "ccp.h"
+#include "link.h"
+#include "descriptor.h"
+#include "physical.h"
+#include "mp.h"
+#include "chat.h"
+#include "auth.h"
+#include "chap.h"
+#include "command.h"
+#include "datalink.h"
struct echolqr {
u_int32_t magic;
@@ -65,43 +63,44 @@ struct echolqr {
#define SIGNATURE 0x594e4f54
static void
-SendEchoReq(void)
+SendEchoReq(struct lcp *lcp)
{
- struct fsm *fp = &LcpFsm;
- struct echolqr *lqr, lqrdata;
-
- if (fp->state == ST_OPENED) {
- lqr = &lqrdata;
- lqr->magic = htonl(LcpInfo.want_magic);
- lqr->signature = htonl(SIGNATURE);
- LogPrintf(LogLQM, "Send echo LQR [%d]\n", echoseq);
- lqr->sequence = htonl(echoseq++);
- FsmOutput(fp, CODE_ECHOREQ, fp->reqid++,
- (u_char *) lqr, sizeof(struct echolqr));
- }
+ struct hdlc *hdlc = &link2physical(lcp->fsm.link)->hdlc;
+ struct echolqr echo;
+
+ echo.magic = htonl(lcp->want_magic);
+ echo.signature = htonl(SIGNATURE);
+ echo.sequence = htonl(hdlc->lqm.echo.seq_sent);
+ fsm_Output(&lcp->fsm, CODE_ECHOREQ, hdlc->lqm.echo.seq_sent++,
+ (u_char *)&echo, sizeof echo);
}
void
-RecvEchoLqr(struct mbuf * bp)
+lqr_RecvEcho(struct fsm *fp, struct mbuf * bp)
{
+ struct hdlc *hdlc = &link2physical(fp->link)->hdlc;
struct echolqr *lqr;
u_int32_t seq;
- if (plength(bp) == sizeof(struct echolqr)) {
+ if (mbuf_Length(bp) == sizeof(struct echolqr)) {
lqr = (struct echolqr *) MBUF_CTOP(bp);
- if (htonl(lqr->signature) == SIGNATURE) {
+ if (ntohl(lqr->signature) == SIGNATURE) {
seq = ntohl(lqr->sequence);
- LogPrintf(LogLQM, "Got echo LQR [%d]\n", ntohl(lqr->sequence));
- /* careful not to update gotseq with older values */
- if ((gotseq > (u_int32_t)0 - 5 && seq < 5) ||
- (gotseq <= (u_int32_t)0 - 5 && seq > gotseq))
- gotseq = seq;
- }
- }
+ /* careful not to update lqm.echo.seq_recv with older values */
+ if ((hdlc->lqm.echo.seq_recv > (u_int32_t)0 - 5 && seq < 5) ||
+ (hdlc->lqm.echo.seq_recv <= (u_int32_t)0 - 5 &&
+ seq > hdlc->lqm.echo.seq_recv))
+ hdlc->lqm.echo.seq_recv = seq;
+ } else
+ log_Printf(LogERROR, "lqr_RecvEcho: Got sig 0x%08x, expecting 0x%08x !\n",
+ (unsigned)ntohl(lqr->signature), (unsigned)SIGNATURE);
+ } else
+ log_Printf(LogERROR, "lqr_RecvEcho: Got packet size %d, expecting %d !\n",
+ mbuf_Length(bp), sizeof(struct echolqr));
}
void
-LqrChangeOrder(struct lqrdata * src, struct lqrdata * dst)
+lqr_ChangeOrder(struct lqrdata * src, struct lqrdata * dst)
{
u_long *sp, *dp;
int n;
@@ -113,169 +112,207 @@ LqrChangeOrder(struct lqrdata * src, struct lqrdata * dst)
}
static void
-SendLqrReport(void *v)
+SendLqrData(struct lcp *lcp)
{
struct mbuf *bp;
- StopTimer(&LqrTimer);
+ bp = mbuf_Alloc(sizeof(struct lqrdata), MB_LQR);
+ hdlc_Output(lcp->fsm.link, PRI_LINK, PROTO_LQR, bp);
+}
- if (lqmmethod & LQM_LQR) {
- if (lqrsendcnt > 5) {
- /*
- * XXX: Should implement LQM strategy
- */
- LogPrintf(LogPHASE, "** Too many LQR packets lost **\n");
- LogPrintf(LogLQM, "LqrOutput: Too many LQR packets lost\n");
- lqmmethod = 0; /* Prevent recursion via LcpClose() */
- reconnect(RECON_TRUE);
- LcpClose();
+static void
+SendLqrReport(void *v)
+{
+ struct lcp *lcp = (struct lcp *)v;
+ struct physical *p = link2physical(lcp->fsm.link);
+
+ timer_Stop(&p->hdlc.lqm.timer);
+
+ if (p->hdlc.lqm.method & LQM_LQR) {
+ if (p->hdlc.lqm.lqr.resent > 5) {
+ /* XXX: Should implement LQM strategy */
+ log_Printf(LogPHASE, "%s: ** Too many LQR packets lost **\n",
+ lcp->fsm.link->name);
+ log_Printf(LogLQM, "%s: Too many LQR packets lost\n",
+ lcp->fsm.link->name);
+ p->hdlc.lqm.method = 0;
+ datalink_Down(p->dl, 0);
} else {
- bp = mballoc(sizeof(struct lqrdata), MB_LQR);
- HdlcOutput(PRI_LINK, PROTO_LQR, bp);
- lqrsendcnt++;
+ SendLqrData(lcp);
+ p->hdlc.lqm.lqr.resent++;
}
- } else if (lqmmethod & LQM_ECHO) {
- if ((echoseq > 5 && echoseq - 5 > gotseq) ||
- (echoseq <= 5 && echoseq > gotseq + 5)) {
- LogPrintf(LogPHASE, "** Too many ECHO LQR packets lost **\n");
- LogPrintf(LogLQM, "LqrOutput: Too many ECHO LQR packets lost\n");
- lqmmethod = 0; /* Prevent recursion via LcpClose() */
- reconnect(RECON_TRUE);
- LcpClose();
+ } else if (p->hdlc.lqm.method & LQM_ECHO) {
+ if ((p->hdlc.lqm.echo.seq_sent > 5 &&
+ p->hdlc.lqm.echo.seq_sent - 5 > p->hdlc.lqm.echo.seq_recv) ||
+ (p->hdlc.lqm.echo.seq_sent <= 5 &&
+ p->hdlc.lqm.echo.seq_sent > p->hdlc.lqm.echo.seq_recv + 5)) {
+ log_Printf(LogPHASE, "%s: ** Too many ECHO LQR packets lost **\n",
+ lcp->fsm.link->name);
+ log_Printf(LogLQM, "%s: Too many ECHO LQR packets lost\n",
+ lcp->fsm.link->name);
+ p->hdlc.lqm.method = 0;
+ datalink_Down(p->dl, 0);
} else
- SendEchoReq();
+ SendEchoReq(lcp);
}
- if (lqmmethod && LqrTimer.load)
- StartTimer(&LqrTimer);
+ if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load)
+ timer_Start(&p->hdlc.lqm.timer);
}
void
-LqrInput(struct mbuf * bp)
+lqr_Input(struct physical *physical, struct mbuf *bp)
{
int len;
- u_char *cp;
- struct lqrdata *lqr;
- len = plength(bp);
- if (len != sizeof(struct lqrdata)) {
- pfree(bp);
- return;
- }
- if (!Acceptable(ConfLqr)) {
+ len = mbuf_Length(bp);
+ if (len != sizeof(struct lqrdata))
+ log_Printf(LogERROR, "lqr_Input: Got packet size %d, expecting %d !\n",
+ len, sizeof(struct lqrdata));
+ else if (!IsAccepted(physical->link.lcp.cfg.lqr) &&
+ !(physical->hdlc.lqm.method & LQM_LQR)) {
bp->offset -= 2;
bp->cnt += 2;
-
- cp = MBUF_CTOP(bp);
- LcpSendProtoRej(cp, bp->cnt);
+ lcp_SendProtoRej(physical->hdlc.lqm.owner, MBUF_CTOP(bp), bp->cnt);
} else {
- cp = MBUF_CTOP(bp);
- lqr = (struct lqrdata *) cp;
- if (ntohl(lqr->MagicNumber) != LcpInfo.his_magic) {
- LogPrintf(LogERROR, "LqrInput: magic %x != expecting %x\n",
- ntohl(lqr->MagicNumber), LcpInfo.his_magic);
- pfree(bp);
- return;
- }
+ struct lqrdata *lqr;
+ struct lcp *lcp;
+ u_int32_t lastLQR;
- /*
- * Convert byte order and save into our strage
- */
- LqrChangeOrder(lqr, &HisLqrData);
- LqrDump("LqrInput", &HisLqrData);
- lqrsendcnt = 0; /* we have received LQR from peer */
-
- /*
- * Generate an LQR response to peer we're not running LQR timer OR
- * two successive LQR's PeerInLQRs are same OR we're not going to
- * send our next one before the peers max timeout.
- */
- if (LqrTimer.load == 0 || lastpeerin == HisLqrData.PeerInLQRs ||
- (LqrTimer.arg &&
- LqrTimer.rest * 100 / SECTICKS > (u_int32_t)LqrTimer.arg)) {
- lqmmethod |= LQM_LQR;
- SendLqrReport(LqrTimer.arg);
+ lqr = (struct lqrdata *)MBUF_CTOP(bp);
+ lcp = physical->hdlc.lqm.owner;
+ if (ntohl(lqr->MagicNumber) != physical->hdlc.lqm.owner->his_magic)
+ log_Printf(LogERROR, "lqr_Input: magic %x != expecting %x\n",
+ (unsigned)ntohl(lqr->MagicNumber),
+ physical->hdlc.lqm.owner->his_magic);
+ else {
+ /*
+ * Remember our PeerInLQRs, then convert byte order and save
+ */
+ lastLQR = physical->hdlc.lqm.lqr.peer.PeerInLQRs;
+
+ lqr_ChangeOrder(lqr, &physical->hdlc.lqm.lqr.peer);
+ lqr_Dump(physical->link.name, "Input", &physical->hdlc.lqm.lqr.peer);
+ /* we have received an LQR from peer */
+ physical->hdlc.lqm.lqr.resent = 0;
+
+ /*
+ * Generate an LQR response if we're not running an LQR timer OR
+ * two successive LQR's PeerInLQRs are the same OR we're not going to
+ * send our next one before the peers max timeout.
+ */
+ if (physical->hdlc.lqm.timer.load == 0 ||
+ !(physical->hdlc.lqm.method & LQM_LQR) ||
+ (lastLQR && lastLQR == physical->hdlc.lqm.lqr.peer.PeerInLQRs) ||
+ (physical->hdlc.lqm.lqr.peer_timeout &&
+ physical->hdlc.lqm.timer.rest * 100 / SECTICKS >
+ physical->hdlc.lqm.lqr.peer_timeout))
+ SendLqrData(physical->hdlc.lqm.owner);
}
- lastpeerin = HisLqrData.PeerInLQRs;
}
- pfree(bp);
+ mbuf_Free(bp);
}
/*
* When LCP is reached to opened state, We'll start LQM activity.
*/
-void
-StartLqm()
+
+static void
+lqr_Setup(struct lcp *lcp)
{
- struct lcpstate *lcp = &LcpInfo;
+ struct physical *physical = link2physical(lcp->fsm.link);
- lqrsendcnt = 0; /* start waiting all over for ECHOs */
- echoseq = 0;
- gotseq = 0;
- memset(&HisLqrData, '\0', sizeof HisLqrData);
+ physical->hdlc.lqm.lqr.resent = 0;
+ physical->hdlc.lqm.echo.seq_sent = 0;
+ physical->hdlc.lqm.echo.seq_recv = 0;
+ memset(&physical->hdlc.lqm.lqr.peer, '\0',
+ sizeof physical->hdlc.lqm.lqr.peer);
- lqmmethod = LQM_ECHO;
- if (Enabled(ConfLqr) && !REJECTED(lcp, TY_QUALPROTO))
- lqmmethod |= LQM_LQR;
- StopTimer(&LqrTimer);
+ physical->hdlc.lqm.method = LQM_ECHO;
+ if (IsEnabled(lcp->cfg.lqr) && !REJECTED(lcp, TY_QUALPROTO))
+ physical->hdlc.lqm.method |= LQM_LQR;
+ timer_Stop(&physical->hdlc.lqm.timer);
+ physical->hdlc.lqm.lqr.peer_timeout = lcp->his_lqrperiod;
if (lcp->his_lqrperiod)
- LogPrintf(LogLQM, "Expecting LQR every %d.%02d secs\n",
- lcp->his_lqrperiod / 100, lcp->his_lqrperiod % 100);
+ log_Printf(LogLQM, "%s: Expecting LQR every %d.%02d secs\n",
+ physical->link.name, lcp->his_lqrperiod / 100,
+ lcp->his_lqrperiod % 100);
if (lcp->want_lqrperiod) {
- LogPrintf(LogLQM, "Will send %s every %d.%02d secs\n",
- lqmmethod & LQM_LQR ? "LQR" : "ECHO LQR",
- lcp->want_lqrperiod / 100, lcp->want_lqrperiod % 100);
- LqrTimer.state = TIMER_STOPPED;
- LqrTimer.load = lcp->want_lqrperiod * SECTICKS / 100;
- LqrTimer.func = SendLqrReport;
- LqrTimer.arg = (void *)lcp->his_lqrperiod;
- SendLqrReport(LqrTimer.arg);
+ log_Printf(LogLQM, "%s: Will send %s every %d.%02d secs\n",
+ physical->link.name,
+ physical->hdlc.lqm.method & LQM_LQR ? "LQR" : "ECHO LQR",
+ lcp->want_lqrperiod / 100, lcp->want_lqrperiod % 100);
+ physical->hdlc.lqm.timer.load = lcp->want_lqrperiod * SECTICKS / 100;
+ physical->hdlc.lqm.timer.func = SendLqrReport;
+ physical->hdlc.lqm.timer.name = "lqm";
+ physical->hdlc.lqm.timer.arg = lcp;
} else {
- LqrTimer.load = 0;
+ physical->hdlc.lqm.timer.load = 0;
if (!lcp->his_lqrperiod)
- LogPrintf(LogLQM, "LQR/ECHO LQR not negotiated\n");
+ log_Printf(LogLQM, "%s: LQR/ECHO LQR not negotiated\n",
+ physical->link.name);
}
}
void
-StopLqrTimer()
+lqr_Start(struct lcp *lcp)
{
- StopTimer(&LqrTimer);
+ struct physical *p = link2physical(lcp->fsm.link);
+
+ lqr_Setup(lcp);
+ if (p->hdlc.lqm.timer.load)
+ SendLqrReport(lcp);
}
void
-StopLqr(int method)
+lqr_reStart(struct lcp *lcp)
{
- LogPrintf(LogLQM, "StopLqr method = %x\n", method);
+ struct physical *p = link2physical(lcp->fsm.link);
+ lqr_Setup(lcp);
+ if (p->hdlc.lqm.timer.load)
+ timer_Start(&p->hdlc.lqm.timer);
+}
+
+void
+lqr_StopTimer(struct physical *physical)
+{
+ timer_Stop(&physical->hdlc.lqm.timer);
+}
+
+void
+lqr_Stop(struct physical *physical, int method)
+{
if (method == LQM_LQR)
- LogPrintf(LogLQM, "Stop sending LQR, Use LCP ECHO instead.\n");
+ log_Printf(LogLQM, "%s: Stop sending LQR, Use LCP ECHO instead.\n",
+ physical->link.name);
if (method == LQM_ECHO)
- LogPrintf(LogLQM, "Stop sending LCP ECHO.\n");
- lqmmethod &= ~method;
- if (lqmmethod)
- SendLqrReport(LqrTimer.arg);
+ log_Printf(LogLQM, "%s: Stop sending LCP ECHO.\n",
+ physical->link.name);
+ physical->hdlc.lqm.method &= ~method;
+ if (physical->hdlc.lqm.method)
+ SendLqrReport(physical->hdlc.lqm.owner);
else
- StopTimer(&LqrTimer);
+ timer_Stop(&physical->hdlc.lqm.timer);
}
void
-LqrDump(const char *message, const struct lqrdata * lqr)
+lqr_Dump(const char *link, const char *message, const struct lqrdata *lqr)
{
- if (LogIsKept(LogLQM)) {
- LogPrintf(LogLQM, "%s:\n", message);
- LogPrintf(LogLQM, " Magic: %08x LastOutLQRs: %08x\n",
+ if (log_IsKept(LogLQM)) {
+ log_Printf(LogLQM, "%s: %s:\n", link, message);
+ log_Printf(LogLQM, " Magic: %08x LastOutLQRs: %08x\n",
lqr->MagicNumber, lqr->LastOutLQRs);
- LogPrintf(LogLQM, " LastOutPackets: %08x LastOutOctets: %08x\n",
+ log_Printf(LogLQM, " LastOutPackets: %08x LastOutOctets: %08x\n",
lqr->LastOutPackets, lqr->LastOutOctets);
- LogPrintf(LogLQM, " PeerInLQRs: %08x PeerInPackets: %08x\n",
+ log_Printf(LogLQM, " PeerInLQRs: %08x PeerInPackets: %08x\n",
lqr->PeerInLQRs, lqr->PeerInPackets);
- LogPrintf(LogLQM, " PeerInDiscards: %08x PeerInErrors: %08x\n",
+ log_Printf(LogLQM, " PeerInDiscards: %08x PeerInErrors: %08x\n",
lqr->PeerInDiscards, lqr->PeerInErrors);
- LogPrintf(LogLQM, " PeerInOctets: %08x PeerOutLQRs: %08x\n",
+ log_Printf(LogLQM, " PeerInOctets: %08x PeerOutLQRs: %08x\n",
lqr->PeerInOctets, lqr->PeerOutLQRs);
- LogPrintf(LogLQM, " PeerOutPackets: %08x PeerOutOctets: %08x\n",
+ log_Printf(LogLQM, " PeerOutPackets: %08x PeerOutOctets: %08x\n",
lqr->PeerOutPackets, lqr->PeerOutOctets);
}
}
OpenPOWER on IntegriCloud