summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2004-11-16 14:47:03 +0000
committerBrad Smith <brad@cvs.openbsd.org>2004-11-16 14:47:03 +0000
commit7ad6f0f560779f4f0de178a97b31b8943ede3185 (patch)
treef2ed6d5b03e4bc098d83274853e525349d675f41
parent1788bde8f096de74d4e10097ebcb19da6f6946f5 (diff)
Re-implement LQM, this time according to the rfc.
From FreeBSD ok deraadt@
-rw-r--r--usr.sbin/ppp/ppp/acf.c6
-rw-r--r--usr.sbin/ppp/ppp/async.c6
-rw-r--r--usr.sbin/ppp/ppp/hdlc.c16
-rw-r--r--usr.sbin/ppp/ppp/hdlc.h20
-rw-r--r--usr.sbin/ppp/ppp/link.c33
-rw-r--r--usr.sbin/ppp/ppp/link.h3
-rw-r--r--usr.sbin/ppp/ppp/lqr.c188
-rw-r--r--usr.sbin/ppp/ppp/lqr.h13
-rw-r--r--usr.sbin/ppp/ppp/mbuf.h3
-rw-r--r--usr.sbin/ppp/ppp/sync.c10
10 files changed, 219 insertions, 79 deletions
diff --git a/usr.sbin/ppp/ppp/acf.c b/usr.sbin/ppp/ppp/acf.c
index f209f78cab8..9b8cd0601ce 100644
--- a/usr.sbin/ppp/ppp/acf.c
+++ b/usr.sbin/ppp/ppp/acf.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: acf.c,v 1.5 2000/07/19 11:06:30 brian Exp $
+ * $OpenBSD: acf.c,v 1.6 2004/11/16 14:47:02 brad Exp $
*/
#include <sys/types.h>
@@ -85,14 +85,14 @@ acf_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto)
/* We expect the packet not to be compressed */
bp = mbuf_Read(bp, cp, 2);
if (cp[0] != HDLC_ADDR) {
- p->hdlc.lqm.SaveInErrors++;
+ p->hdlc.lqm.ifInErrors++;
p->hdlc.stats.badaddr++;
log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]);
m_freem(bp);
return NULL;
}
if (cp[1] != HDLC_UI) {
- p->hdlc.lqm.SaveInErrors++;
+ p->hdlc.lqm.ifInErrors++;
p->hdlc.stats.badcommand++;
log_Printf(LogDEBUG, "acf_LayerPull: control 0x%02x\n", cp[1]);
m_freem(bp);
diff --git a/usr.sbin/ppp/ppp/async.c b/usr.sbin/ppp/ppp/async.c
index 685bb4096e7..8e7825ff037 100644
--- a/usr.sbin/ppp/ppp/async.c
+++ b/usr.sbin/ppp/ppp/async.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: async.c,v 1.11 2002/03/31 02:38:49 brian Exp $
+ * $OpenBSD: async.c,v 1.12 2004/11/16 14:47:02 brad Exp $
*/
#include <sys/types.h>
@@ -104,6 +104,7 @@ async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
struct physical *p = link2physical(l);
u_char *cp, *sp, *ep;
struct mbuf *wp;
+ size_t oldcnt;
int cnt;
if (!p || m_length(bp) > HDLCSIZE) {
@@ -111,6 +112,8 @@ async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
return NULL;
}
+ oldcnt = m_length(bp);
+
cp = p->async.xbuff;
ep = cp + HDLCSIZE - 10;
wp = bp;
@@ -132,6 +135,7 @@ async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
m_freem(bp);
bp = m_get(cnt, MB_ASYNCOUT);
memcpy(MBUF_CTOP(bp), p->async.xbuff, cnt);
+ bp->priv = cnt - oldcnt;
log_DumpBp(LogASYNC, "Write", bp);
return bp;
diff --git a/usr.sbin/ppp/ppp/hdlc.c b/usr.sbin/ppp/ppp/hdlc.c
index 1848965e445..6feb992b51d 100644
--- a/usr.sbin/ppp/ppp/hdlc.c
+++ b/usr.sbin/ppp/ppp/hdlc.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: hdlc.c,v 1.13 2001/08/19 23:22:17 brian Exp $
+ * $OpenBSD: hdlc.c,v 1.14 2004/11/16 14:47:02 brad Exp $
*/
#include <sys/param.h>
@@ -317,22 +317,26 @@ hdlc_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
log_DumpBp(LogHDLC, "hdlc_LayerPull:", bp);
- fcs = hdlc_Fcs(MBUF_CTOP(bp), bp->m_len);
+ bp = m_pullup(bp);
+ len = m_length(bp);
+ fcs = hdlc_Fcs(MBUF_CTOP(bp), len);
log_Printf(LogDEBUG, "%s: hdlc_LayerPull: fcs = %04x (%s)\n",
p->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
+ p->hdlc.lqm.ifInOctets += len + 1; /* plus 1 flag octet! */
+
if (fcs != GOODFCS) {
- p->hdlc.lqm.SaveInErrors++;
+ p->hdlc.lqm.ifInErrors++;
p->hdlc.stats.badfcs++;
m_freem(bp);
return NULL;
}
- p->hdlc.lqm.SaveInOctets += bp->m_len + 1;
- p->hdlc.lqm.SaveInPackets++;
+ /* Either done here or by the sync layer */
+ p->hdlc.lqm.lqr.InGoodOctets += len + 1; /* plus 1 flag octet! */
+ p->hdlc.lqm.ifInUniPackets++;
- len = m_length(bp);
if (len < 4) { /* rfc1662 section 4.3 */
m_freem(bp);
bp = NULL;
diff --git a/usr.sbin/ppp/ppp/hdlc.h b/usr.sbin/ppp/ppp/hdlc.h
index faa35817309..fc5711153dd 100644
--- a/usr.sbin/ppp/ppp/hdlc.h
+++ b/usr.sbin/ppp/ppp/hdlc.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: hdlc.h,v 1.7 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: hdlc.h,v 1.8 2004/11/16 14:47:02 brad Exp $
*/
/*
@@ -73,16 +73,20 @@ struct hdlc {
struct pppTimer timer; /* When to send */
int method; /* bit-mask for LQM_* from lqr.h */
- u_int32_t OutPackets; /* Packets sent by me */
- u_int32_t OutOctets; /* Octets sent by me */
- u_int32_t SaveInPackets; /* Packets received from peer */
- u_int32_t SaveInDiscards; /* Discards */
- u_int32_t SaveInErrors; /* Errors */
- u_int32_t SaveInOctets; /* Octets received from peer */
+ u_int32_t ifOutUniPackets; /* Packets sent by me */
+ u_int32_t ifOutOctets; /* Octets sent by me */
+ u_int32_t ifInUniPackets; /* Packets received from peer */
+ u_int32_t ifInDiscards; /* Discards */
+ u_int32_t ifInErrors; /* Errors */
+ u_int32_t ifInOctets; /* Octets received from peer (unused) */
struct {
+ u_int32_t InGoodOctets; /* Good octets received from peer */
u_int32_t OutLQRs; /* LQRs sent by me */
- u_int32_t SaveInLQRs; /* LQRs received from peer */
+ u_int32_t InLQRs; /* LQRs received from peer */
+
+ struct lqrsavedata Save; /* Our last LQR */
+ struct lqrsavedata prevSave; /* Our last-but-one LQR (analysis) */
struct lqrdata peer; /* Last LQR from peer */
int peer_timeout; /* peers max lqr timeout */
int resent; /* Resent last packet `resent' times */
diff --git a/usr.sbin/ppp/ppp/link.c b/usr.sbin/ppp/ppp/link.c
index 176e080850a..7f6d6c5977f 100644
--- a/usr.sbin/ppp/ppp/link.c
+++ b/usr.sbin/ppp/ppp/link.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: link.c,v 1.13 2001/08/19 23:22:18 brian Exp $
+ * $OpenBSD: link.c,v 1.14 2004/11/16 14:47:02 brad Exp $
*
*/
@@ -146,6 +146,34 @@ link_QueueBytes(struct link *l)
return bytes;
}
+void
+link_PendingLowPriorityData(struct link *l, size_t *pkts, size_t *octets)
+{
+ struct mqueue *queue, *highest;
+ struct mbuf *m;
+ size_t len;
+
+ /*
+ * This is all rfc1989 stuff... because our LQR packet is going to bypass
+ * everything that's not in the highest priority queue, we must be able to
+ * subtract that data from our outgoing packet/octet counts. However,
+ * we've already async-encoded our data at this point, but the async
+ * encodings MUSTn't be a part of the LQR-reported payload :( So, we have
+ * the async layer record how much it's padded the packet in the mbuf's
+ * priv field, and when we calculate our outgoing LQR values we subtract
+ * this value for each packet from the octet count sent.
+ */
+
+ highest = LINK_HIGHQ(l);
+ *pkts = *octets = 0;
+ for (queue = l->Queue; queue < highest; queue++) {
+ len = queue->len;
+ *pkts += len;
+ for (m = queue->top; len--; m = m->m_nextpkt)
+ *octets += m_length(m) - m->priv;
+ }
+}
+
struct mbuf *
link_Dequeue(struct link *l)
{
@@ -231,6 +259,7 @@ link_PushPacket(struct link *l, struct mbuf *bp, struct bundle *b, int pri,
if(pri < 0 || pri >= LINK_QUEUES(l))
pri = 0;
+ bp->priv = 0; /* Adjusted by the async layer ! */
for (layer = l->nlayers; layer && bp; layer--)
if (l->layer[layer - 1]->push != NULL)
bp = (*l->layer[layer - 1]->push)(b, l, bp, pri, &proto);
@@ -359,7 +388,7 @@ Despatch(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short proto)
bp = m_pullup(proto_Prepend(bp, proto, 0, 0));
lcp_SendProtoRej(&l->lcp, MBUF_CTOP(bp), bp->m_len);
if (p) {
- p->hdlc.lqm.SaveInDiscards++;
+ p->hdlc.lqm.ifInDiscards++;
p->hdlc.stats.unknownproto++;
}
m_freem(bp);
diff --git a/usr.sbin/ppp/ppp/link.h b/usr.sbin/ppp/ppp/link.h
index deb08e8cdb7..be114c9d5bc 100644
--- a/usr.sbin/ppp/ppp/link.h
+++ b/usr.sbin/ppp/ppp/link.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: link.h,v 1.7 2000/08/15 10:08:50 brian Exp $
+ * $OpenBSD: link.h,v 1.8 2004/11/16 14:47:02 brad Exp $
*
*/
@@ -65,6 +65,7 @@ extern void link_SequenceQueue(struct link *);
extern void link_DeleteQueue(struct link *);
extern size_t link_QueueLen(struct link *);
extern size_t link_QueueBytes(struct link *);
+extern void link_PendingLowPriorityData(struct link *, size_t *, size_t *);
extern struct mbuf *link_Dequeue(struct link *);
extern void link_PushPacket(struct link *, struct mbuf *, struct bundle *,
diff --git a/usr.sbin/ppp/ppp/lqr.c b/usr.sbin/ppp/ppp/lqr.c
index 6b2e7d305bb..07ee20eb87e 100644
--- a/usr.sbin/ppp/ppp/lqr.c
+++ b/usr.sbin/ppp/ppp/lqr.c
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: lqr.c,v 1.14 2002/06/15 08:02:00 brian Exp $
+ * $OpenBSD: lqr.c,v 1.15 2004/11/16 14:47:02 brad Exp $
*/
#include <sys/param.h>
@@ -146,6 +146,14 @@ SendLqrData(struct lcp *lcp)
bp = m_get(sizeof(struct lqrdata) + extra, MB_LQROUT);
bp->m_len -= extra;
bp->m_offset += extra;
+
+ /*
+ * Send on the highest priority queue. We send garbage - the real data
+ * is written by lqr_LayerPush() where we know how to fill in all the
+ * fields. Note, lqr_LayerPush() ``knows'' that we're pushing onto the
+ * highest priority queue, and factors out packet & octet values from
+ * other queues!
+ */
link_PushPacket(lcp->fsm.link, bp, lcp->fsm.bundle,
LINK_QUEUES(lcp->fsm.link) - 1, PROTO_LQR);
}
@@ -202,8 +210,6 @@ lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
return NULL;
}
- p->hdlc.lqm.lqr.SaveInLQRs++;
-
len = m_length(bp);
if (len != sizeof(struct lqrdata))
log_Printf(LogWARN, "lqr_Input: Got packet size %d, expecting %ld !\n",
@@ -213,7 +219,6 @@ lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
lcp_SendProtoRej(lcp, MBUF_CTOP(bp), bp->m_len);
} else {
struct lqrdata *lqr;
- u_int32_t lastLQR;
bp = m_pullup(bp);
lqr = (struct lqrdata *)MBUF_CTOP(bp);
@@ -222,27 +227,32 @@ lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
" expecting 0x%08lx\n",
(u_long)ntohl(lqr->MagicNumber), (u_long)lcp->his_magic);
else {
- /*
- * Remember our PeerInLQRs, then convert byte order and save
- */
- lastLQR = p->hdlc.lqm.lqr.peer.PeerInLQRs;
-
+ struct lqrdata lastlqr;
+
+ memcpy(&lastlqr, &p->hdlc.lqm.lqr.peer, sizeof lastlqr);
lqr_ChangeOrder(lqr, &p->hdlc.lqm.lqr.peer);
lqr_Dump(l->name, "Input", &p->hdlc.lqm.lqr.peer);
- /* we have received an LQR from peer */
+ /* we have received an LQR from our peer */
p->hdlc.lqm.lqr.resent = 0;
+ /* Snapshot our state when the LQR packet was received */
+ memcpy(&p->hdlc.lqm.lqr.prevSave, &p->hdlc.lqm.lqr.Save,
+ sizeof p->hdlc.lqm.lqr.prevSave);
+ p->hdlc.lqm.lqr.Save.InLQRs = ++p->hdlc.lqm.lqr.InLQRs;
+ p->hdlc.lqm.lqr.Save.InPackets = p->hdlc.lqm.ifInUniPackets;
+ p->hdlc.lqm.lqr.Save.InDiscards = p->hdlc.lqm.ifInDiscards;
+ p->hdlc.lqm.lqr.Save.InErrors = p->hdlc.lqm.ifInErrors;
+ p->hdlc.lqm.lqr.Save.InOctets = p->hdlc.lqm.lqr.InGoodOctets;
+
+ lqr_Analyse(&p->hdlc, &lastlqr, &p->hdlc.lqm.lqr.peer);
+
/*
* 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.
+ * two successive LQR's PeerInLQRs are the same.
*/
- if (p->hdlc.lqm.timer.load == 0 ||
- !(p->hdlc.lqm.method & LQM_LQR) ||
- (lastLQR && lastLQR == p->hdlc.lqm.lqr.peer.PeerInLQRs) ||
- (p->hdlc.lqm.lqr.peer_timeout &&
- p->hdlc.lqm.timer.rest * 100 / SECTICKS >
- p->hdlc.lqm.lqr.peer_timeout))
+ if (p->hdlc.lqm.timer.load == 0 || !(p->hdlc.lqm.method & LQM_LQR) ||
+ (lastlqr.PeerInLQRs &&
+ lastlqr.PeerInLQRs == p->hdlc.lqm.lqr.peer.PeerInLQRs))
SendLqrData(lcp);
}
}
@@ -355,12 +365,57 @@ lqr_Dump(const char *link, const char *message, const struct lqrdata *lqr)
}
}
+void
+lqr_Analyse(const struct hdlc *hdlc, const struct lqrdata *oldlqr,
+ const struct lqrdata *newlqr)
+{
+ u_int32_t LQRs, transitLQRs, pkts, octets, disc, err;
+
+ if (!newlqr->PeerInLQRs) /* No analysis possible yet! */
+ return;
+
+ log_Printf(LogLQM, "Analysis:\n");
+
+ LQRs = (newlqr->LastOutLQRs - oldlqr->LastOutLQRs) -
+ (newlqr->PeerInLQRs - oldlqr->PeerInLQRs);
+ transitLQRs = hdlc->lqm.lqr.OutLQRs - newlqr->LastOutLQRs;
+ pkts = (newlqr->LastOutPackets - oldlqr->LastOutPackets) -
+ (newlqr->PeerInPackets - oldlqr->PeerInPackets);
+ octets = (newlqr->LastOutOctets - oldlqr->LastOutOctets) -
+ (newlqr->PeerInOctets - oldlqr->PeerInOctets);
+ log_Printf(LogLQM, " Outbound lossage: %d LQR%s (%d en route), %d packet%s,"
+ " %d octet%s\n", (int)LQRs, LQRs == 1 ? "" : "s", (int)transitLQRs,
+ (int)pkts, pkts == 1 ? "" : "s",
+ (int)octets, octets == 1 ? "" : "s");
+
+ pkts = (newlqr->PeerOutPackets - oldlqr->PeerOutPackets) -
+ (hdlc->lqm.lqr.Save.InPackets - hdlc->lqm.lqr.prevSave.InPackets);
+ octets = (newlqr->PeerOutOctets - oldlqr->PeerOutOctets) -
+ (hdlc->lqm.lqr.Save.InOctets - hdlc->lqm.lqr.prevSave.InOctets);
+ log_Printf(LogLQM, " Inbound lossage: %d packet%s, %d octet%s\n",
+ (int)pkts, pkts == 1 ? "" : "s",
+ (int)octets, octets == 1 ? "" : "s");
+
+ disc = newlqr->PeerInDiscards - oldlqr->PeerInDiscards;
+ err = newlqr->PeerInErrors - oldlqr->PeerInErrors;
+ if (disc && err)
+ log_Printf(LogLQM, " Likely due to both peer congestion"
+ " and physical errors\n");
+ else if (disc)
+ log_Printf(LogLQM, " Likely due to peer congestion\n");
+ else if (err)
+ log_Printf(LogLQM, " Likely due to physical errors\n");
+ else if (pkts)
+ log_Printf(LogLQM, " Likely due to transport "
+ "congestion\n");
+}
+
static struct mbuf *
lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
int pri, u_short *proto)
{
struct physical *p = link2physical(l);
- int len;
+ int len, layer, extra_async_bytes;
if (!p) {
/* Oops - can't happen :-] */
@@ -368,7 +423,10 @@ lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
return NULL;
}
- /*
+ bp = m_pullup(bp);
+ len = m_length(bp);
+
+ /*-
* From rfc1989:
*
* All octets which are included in the FCS calculation MUST be counted,
@@ -377,50 +435,72 @@ lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
* MUST be counted. All other octets (such as additional flag
* sequences, and escape bits or octets) MUST NOT be counted.
*
- * As we're stacked before the HDLC layer (otherwise HDLC wouldn't be
+ * As we're stacked higher than the HDLC layer (otherwise HDLC wouldn't be
* able to calculate the FCS), we must not forget about these additional
* bytes when we're asynchronous.
*
- * We're also expecting to be stacked *before* the proto and acf layers.
- * If we were after these, it makes alignment more of a pain, and we
- * don't do LQR without these layers.
+ * We're also expecting to be stacked *before* the likes of the proto and
+ * acf layers (to avoid alignment issues), so deal with this too.
*/
- bp = m_pullup(bp);
- len = m_length(bp);
-
- if (!physical_IsSync(p))
- p->hdlc.lqm.OutOctets += hdlc_WrapperOctets(&l->lcp, *proto);
- p->hdlc.lqm.OutOctets += acf_WrapperOctets(&l->lcp, *proto) +
- proto_WrapperOctets(&l->lcp, *proto) + len + 1;
- p->hdlc.lqm.OutPackets++;
+ extra_async_bytes = 0;
+ p->hdlc.lqm.ifOutUniPackets++;
+ p->hdlc.lqm.ifOutOctets += len + 1; /* plus 1 flag octet! */
+ for (layer = 0; layer < l->nlayers; layer++)
+ switch (l->layer[layer]->type) {
+ case LAYER_ACF:
+ p->hdlc.lqm.ifOutOctets += acf_WrapperOctets(&l->lcp, *proto);
+ break;
+ case LAYER_ASYNC:
+ /* Not included - see rfc1989 */
+ break;
+ case LAYER_HDLC:
+ p->hdlc.lqm.ifOutOctets += hdlc_WrapperOctets(&l->lcp, *proto);
+ break;
+ case LAYER_LQR:
+ layer = l->nlayers;
+ break;
+ case LAYER_PROTO:
+ p->hdlc.lqm.ifOutOctets += proto_WrapperOctets(&l->lcp, *proto);
+ break;
+ case LAYER_SYNC:
+ /* Nothing to add on */
+ break;
+ default:
+ log_Printf(LogWARN, "Oops, don't know how to do octets for %s layer\n",
+ l->layer[layer]->name);
+ break;
+ }
if (*proto == PROTO_LQR) {
/* Overwrite the entire packet (created in SendLqrData()) */
struct lqrdata lqr;
-
+ size_t pending_pkts, pending_octets;
+
+ p->hdlc.lqm.lqr.OutLQRs++;
+
+ /*
+ * We need to compensate for the fact that we're pushing our data
+ * onto the highest priority queue by factoring out packet & octet
+ * values from other queues!
+ */
+ link_PendingLowPriorityData(l, &pending_pkts, &pending_octets);
+
+ memset(&lqr, '\0', sizeof lqr);
lqr.MagicNumber = p->link.lcp.want_magic;
lqr.LastOutLQRs = p->hdlc.lqm.lqr.peer.PeerOutLQRs;
lqr.LastOutPackets = p->hdlc.lqm.lqr.peer.PeerOutPackets;
lqr.LastOutOctets = p->hdlc.lqm.lqr.peer.PeerOutOctets;
- lqr.PeerInLQRs = p->hdlc.lqm.lqr.SaveInLQRs;
- lqr.PeerInPackets = p->hdlc.lqm.SaveInPackets;
- lqr.PeerInDiscards = p->hdlc.lqm.SaveInDiscards;
- lqr.PeerInErrors = p->hdlc.lqm.SaveInErrors;
- lqr.PeerInOctets = p->hdlc.lqm.SaveInOctets;
- lqr.PeerOutPackets = p->hdlc.lqm.OutPackets;
- lqr.PeerOutOctets = p->hdlc.lqm.OutOctets;
- if (p->hdlc.lqm.lqr.peer.LastOutLQRs == p->hdlc.lqm.lqr.OutLQRs) {
- /*
- * only increment if it's the first time or we've got a reply
- * from the last one
- */
- lqr.PeerOutLQRs = ++p->hdlc.lqm.lqr.OutLQRs;
- lqr_Dump(l->name, "Output", &lqr);
- } else {
- lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
- lqr_Dump(l->name, "Output (again)", &lqr);
- }
+ lqr.PeerInLQRs = p->hdlc.lqm.lqr.Save.InLQRs;
+ lqr.PeerInPackets = p->hdlc.lqm.lqr.Save.InPackets;
+ lqr.PeerInDiscards = p->hdlc.lqm.lqr.Save.InDiscards;
+ lqr.PeerInErrors = p->hdlc.lqm.lqr.Save.InErrors;
+ lqr.PeerInOctets = p->hdlc.lqm.lqr.Save.InOctets;
+ lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
+ lqr.PeerOutPackets = p->hdlc.lqm.ifOutUniPackets - pending_pkts;
+ /* Don't forget our ``flag'' octets.... */
+ lqr.PeerOutOctets = p->hdlc.lqm.ifOutOctets - pending_octets - pending_pkts;
+ lqr_Dump(l->name, "Output", &lqr);
lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
}
@@ -431,9 +511,11 @@ static struct mbuf *
lqr_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto)
{
/*
- * We mark the packet as ours but don't do anything 'till it's dispatched
- * to lqr_Input()
+ * This is the ``Rx'' process from rfc1989, although a part of it is
+ * actually performed by sync_LayerPull() & hdlc_LayerPull() so that
+ * our octet counts are correct.
*/
+
if (*proto == PROTO_LQR)
m_settype(bp, MB_LQRIN);
return bp;
diff --git a/usr.sbin/ppp/ppp/lqr.h b/usr.sbin/ppp/ppp/lqr.h
index c6f1f600d79..535c761d87a 100644
--- a/usr.sbin/ppp/ppp/lqr.h
+++ b/usr.sbin/ppp/ppp/lqr.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: lqr.h,v 1.6 2001/06/13 21:33:41 brian Exp $
+ * $OpenBSD: lqr.h,v 1.7 2004/11/16 14:47:02 brad Exp $
*/
/*
@@ -46,6 +46,14 @@ struct lqrdata {
u_int32_t PeerOutOctets; /* Peers OutOctets (hdlc.h) */
};
+struct lqrsavedata { /* Saved on receipt of an LQR */
+ u_int32_t InLQRs; /* From ifInLQRs */
+ u_int32_t InPackets; /* From ifInPackets */
+ u_int32_t InDiscards; /* From ifInDiscards */
+ u_int32_t InErrors; /* From ifInErrors */
+ u_int32_t InOctets; /* From InGoodOctets ! */
+};
+
/*
* We support LQR and ECHO as LQM method
*/
@@ -56,10 +64,13 @@ struct mbuf;
struct physical;
struct lcp;
struct fsm;
+struct hdlc;
struct link;
struct bundle;
extern void lqr_Dump(const char *, const char *, const struct lqrdata *);
+extern void lqr_Analyse(const struct hdlc *, const struct lqrdata *,
+ const struct lqrdata *);
extern void lqr_ChangeOrder(struct lqrdata *, struct lqrdata *);
extern void lqr_Start(struct lcp *);
extern void lqr_reStart(struct lcp *);
diff --git a/usr.sbin/ppp/ppp/mbuf.h b/usr.sbin/ppp/ppp/mbuf.h
index c2cb484751c..f1d5bbc9707 100644
--- a/usr.sbin/ppp/ppp/mbuf.h
+++ b/usr.sbin/ppp/ppp/mbuf.h
@@ -25,7 +25,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: mbuf.h,v 1.11 2001/08/19 23:22:18 brian Exp $
+ * $OpenBSD: mbuf.h,v 1.12 2004/11/16 14:47:02 brad Exp $
*/
struct mbuf {
@@ -35,6 +35,7 @@ struct mbuf {
short m_type; /* MB_* below */
struct mbuf *m_next; /* link to next mbuf */
struct mbuf *m_nextpkt; /* link to next packet */
+ unsigned long priv; /* private data - holds HDLC escape count */
/* buffer space is malloc()d directly after the header */
};
diff --git a/usr.sbin/ppp/ppp/sync.c b/usr.sbin/ppp/ppp/sync.c
index 73fe78f78e4..a4d452c8280 100644
--- a/usr.sbin/ppp/ppp/sync.c
+++ b/usr.sbin/ppp/ppp/sync.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $OpenBSD: sync.c,v 1.5 2000/02/27 01:38:28 brian Exp $
+ * $OpenBSD: sync.c,v 1.6 2004/11/16 14:47:02 brad Exp $
*/
#include <sys/types.h>
@@ -54,6 +54,7 @@ sync_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
{
log_DumpBp(LogSYNC, "Write", bp);
m_settype(bp, MB_SYNCOUT);
+ bp->priv = 0;
return bp;
}
@@ -62,6 +63,7 @@ sync_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
u_short *proto)
{
struct physical *p = link2physical(l);
+ int len;
if (!p)
log_Printf(LogERROR, "Can't Pull a sync packet from a logical link\n");
@@ -69,8 +71,10 @@ sync_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
log_DumpBp(LogSYNC, "Read", bp);
/* Either done here or by the HDLC layer */
- p->hdlc.lqm.SaveInOctets += m_length(bp) + 1;
- p->hdlc.lqm.SaveInPackets++;
+ len = m_length(bp);
+ p->hdlc.lqm.ifInOctets += len + 1; /* plus 1 flag octet! */
+ p->hdlc.lqm.lqr.InGoodOctets += len + 1; /* plus 1 flag octet! */
+ p->hdlc.lqm.ifInUniPackets++;
m_settype(bp, MB_SYNCIN);
}