diff options
author | brian <brian@FreeBSD.org> | 1998-05-21 21:49:08 +0000 |
---|---|---|
committer | brian <brian@FreeBSD.org> | 1998-05-21 21:49:08 +0000 |
commit | 56df88b778aee0e60678672b107a48a8ea05cb48 (patch) | |
tree | 13b88ca17b38e787c84b0cd242677b3c3c0b93c3 /usr.sbin/ppp/lqr.c | |
parent | e077fa331b8a428923ded3a95d0b8d47084cf670 (diff) | |
download | FreeBSD-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.c | 339 |
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); } } |