summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>2000-08-17 14:14:54 +0000
committerbrian <brian@FreeBSD.org>2000-08-17 14:14:54 +0000
commitc2fd0b70003ffcc83c29eb19ed969d0f6c2aca73 (patch)
tree74a551df84f853975e4bbbf4bc5005be3001f6a3 /usr.sbin/ppp
parent0160624e0921c098464bc22950a006457e04d954 (diff)
downloadFreeBSD-src-c2fd0b70003ffcc83c29eb19ed969d0f6c2aca73.zip
FreeBSD-src-c2fd0b70003ffcc83c29eb19ed969d0f6c2aca73.tar.gz
If we're in MP mode with a single open link, MP link level compression
isn't open and the links MRU >= our MRRU, send outbound traffic as PROTO_IP rather than PROTO_MP. This shaves some bytes off the front of each packet 'till the second link is brought up. Idea obtained from: Cisco
Diffstat (limited to 'usr.sbin/ppp')
-rw-r--r--usr.sbin/ppp/README.changes3
-rw-r--r--usr.sbin/ppp/mp.c114
2 files changed, 83 insertions, 34 deletions
diff --git a/usr.sbin/ppp/README.changes b/usr.sbin/ppp/README.changes
index 1ebf3b4..e4f4634 100644
--- a/usr.sbin/ppp/README.changes
+++ b/usr.sbin/ppp/README.changes
@@ -106,3 +106,6 @@ o The ``!'' at the start of chat scripts and authkey can be made literal
(rather than meaning execute) by doubling it to ``!!''.
o MP autoload throughput measurements are now based on the maximum of input
and output averages rather than on the total.
+o When only one link is open in MP mode, MP link level compression is not
+ open and the peer MRU >= the peer MRRU, ppp sends outbound traffic as
+ PROTO_IP traffic rather than PROTO_MP.
diff --git a/usr.sbin/ppp/mp.c b/usr.sbin/ppp/mp.c
index 5397243..1b63174 100644
--- a/usr.sbin/ppp/mp.c
+++ b/usr.sbin/ppp/mp.c
@@ -693,45 +693,91 @@ mp_FillQueues(struct bundle *bundle)
continue;
add = link_QueueLen(&dl->physical->link);
- total += add;
- if (add)
+ if (add) {
/* this link has got stuff already queued. Let it continue */
+ total += add;
continue;
+ }
- if (!link_QueueLen(&mp->link) && !ip_PushPacket(&mp->link, bundle))
- /* Nothing else to send */
- break;
+ if (!link_QueueLen(&mp->link)) {
+ struct datalink *other;
+ int mrutoosmall;
+
+ /*
+ * If there's only a single open link in our bundle and we haven't got
+ * MP level link compression, queue outbound traffic directly via that
+ * link's protocol stack rather than using the MP link. This results
+ * in the outbound traffic going out as PROTO_IP rather than PROTO_MP.
+ */
+ for (other = dl->next; other; other = other->next)
+ if (other->state == DATALINK_OPEN)
+ break;
+
+ mrutoosmall = 0;
+ if (!other) {
+ if (dl->physical->link.lcp.his_mru < mp->peer_mrru) {
+ /*
+ * Actually, forget it. This test is done against the MRRU rather
+ * than the packet size so that we don't end up sending some data
+ * in MP fragments and some data in PROTO_IP packets. That's just
+ * too likely to upset some ppp implementations.
+ */
+ mrutoosmall = 1;
+ other = dl;
+ }
+ }
- m = link_Dequeue(&mp->link);
- len = m_length(m);
- begin = 1;
- end = 0;
-
- while (!end) {
- if (dl->state == DATALINK_OPEN) {
- /* Write at most his_mru bytes to the physical link */
- if (len <= dl->physical->link.lcp.his_mru) {
- mo = m;
- end = 1;
- m_settype(mo, MB_MPOUT);
- } else {
- /* It's > his_mru, chop the packet (`m') into bits */
- mo = m_get(dl->physical->link.lcp.his_mru, MB_MPOUT);
- len -= mo->m_len;
- m = mbuf_Read(m, MBUF_CTOP(mo), mo->m_len);
+ if (!ip_PushPacket(other ? &mp->link : &dl->physical->link, bundle))
+ /* Nothing else to send */
+ break;
+
+ if (mrutoosmall)
+ log_Printf(LogDEBUG, "Don't send data as PROTO_IP, MRU < MRRU\n");
+ else if (!other)
+ log_Printf(LogDEBUG, "Sending data as PROTO_IP, not PROTO_MP\n");
+
+ if (!other) {
+ add = link_QueueLen(&dl->physical->link);
+ if (add) {
+ /* this link has got stuff already queued. Let it continue */
+ total += add;
+ continue;
}
- mp_Output(mp, bundle, &dl->physical->link, mo, begin, end);
- begin = 0;
}
+ }
- if (!end) {
- nlinks--;
- dl = dl->next;
- if (!dl) {
- dl = bundle->links;
- thislink = 0;
- } else
- thislink++;
+ m = link_Dequeue(&mp->link);
+ if (m) {
+ len = m_length(m);
+ begin = 1;
+ end = 0;
+
+ while (!end) {
+ if (dl->state == DATALINK_OPEN) {
+ /* Write at most his_mru bytes to the physical link */
+ if (len <= dl->physical->link.lcp.his_mru) {
+ mo = m;
+ end = 1;
+ m_settype(mo, MB_MPOUT);
+ } else {
+ /* It's > his_mru, chop the packet (`m') into bits */
+ mo = m_get(dl->physical->link.lcp.his_mru, MB_MPOUT);
+ len -= mo->m_len;
+ m = mbuf_Read(m, MBUF_CTOP(mo), mo->m_len);
+ }
+ mp_Output(mp, bundle, &dl->physical->link, mo, begin, end);
+ begin = 0;
+ }
+
+ if (!end) {
+ nlinks--;
+ dl = dl->next;
+ if (!dl) {
+ dl = bundle->links;
+ thislink = 0;
+ } else
+ thislink++;
+ }
}
}
}
@@ -747,7 +793,7 @@ mp_SetDatalinkBandwidth(struct cmdargs const *arg)
if (arg->argc != arg->argn+1)
return -1;
-
+
val = atoi(arg->argv[arg->argn]);
if (val <= 0) {
log_Printf(LogWARN, "The link bandwidth must be greater than zero\n");
@@ -818,7 +864,7 @@ mp_ShowStatus(struct cmdargs const *arg)
mp->peer.enddisc.len));
prompt_Printf(arg->prompt, "\nDefaults:\n");
-
+
prompt_Printf(arg->prompt, " MRRU: ");
if (mp->cfg.mrru)
prompt_Printf(arg->prompt, "%d (multilink enabled)\n", mp->cfg.mrru);
OpenPOWER on IntegriCloud