summaryrefslogtreecommitdiffstats
path: root/sys/net/ppp_tty.c
diff options
context:
space:
mode:
authorpeter <peter@FreeBSD.org>1997-08-19 14:10:50 +0000
committerpeter <peter@FreeBSD.org>1997-08-19 14:10:50 +0000
commit3970ef27019843920c6306bec80d164f8eee7e82 (patch)
tree34b2d5bc6895d2f3fc3464536dd15f5c6286c76f /sys/net/ppp_tty.c
parent813bc0386ea8626c9016862d4d8013c749e44ff6 (diff)
downloadFreeBSD-src-3970ef27019843920c6306bec80d164f8eee7e82.zip
FreeBSD-src-3970ef27019843920c6306bec80d164f8eee7e82.tar.gz
Update kernel parts of pppd from 2.2.0 to 2.3.0. I've yet to look at the
2.3.0 -> 2.3.1 changes, but I seem to recall that there are certain "issues" with 2.3.1 (I'm not sure if it's just pppd or the whole lot, I am not quite that far). The present pppd seems to work with it just fine for the time being. Among the changes are that zlib (aka LZ77 aka deflate aka gzip) compression is implemented as well as the original compress(1) LZW style.
Diffstat (limited to 'sys/net/ppp_tty.c')
-rw-r--r--sys/net/ppp_tty.c255
1 files changed, 143 insertions, 112 deletions
diff --git a/sys/net/ppp_tty.c b/sys/net/ppp_tty.c
index 422a360..c6f07ef 100644
--- a/sys/net/ppp_tty.c
+++ b/sys/net/ppp_tty.c
@@ -62,7 +62,7 @@
* Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
* Cleaned up a lot of the mbuf-related code to fix bugs that
* caused system crashes and packet corruption. Changed pppstart
- * so that it doesn't just give up with a collision if the whole
+ * so that it doesn't just give up with a "collision" if the whole
* packet doesn't fit in the output ring buffer.
*
* Added priority queueing for interactive IP packets, following
@@ -70,9 +70,7 @@
* Paul Mackerras (paulus@cs.anu.edu.au).
*/
-/* $Id: ppp_tty.c,v 1.20 1997/06/18 02:50:40 brian Exp $ */
-/* from Id: ppp_tty.c,v 1.3 1995/08/16 01:36:40 paulus Exp */
-/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
+/* $Id: ppp_tty.c,v 1.21 1997/06/22 02:19:52 brian Exp $ */
#include "ppp.h"
#if NPPP > 0
@@ -91,12 +89,13 @@
#include <sys/kernel.h>
#include <sys/conf.h>
+
#undef KERNEL /* so that vnode.h does not try to include vnode_if.h */
# include <sys/vnode.h>
#define KERNEL
-#ifdef i386 /* fiddle with the spl locking */
-# include <i386/isa/intr_machdep.h>
+#ifdef i386
+#include <i386/isa/intr_machdep.h>
#endif
#include <net/if.h>
@@ -109,6 +108,9 @@
#include <net/slcompress.h>
#endif
+#ifdef PPP_FILTER
+#include <net/bpf.h>
+#endif
#include <net/ppp_defs.h>
#include <net/if_ppp.h>
#include <net/if_pppvar.h>
@@ -158,6 +160,7 @@ void pppasyncattach __P((void *));
/* This is a FreeBSD-2.X kernel. */
#define CCOUNT(q) ((q)->c_cc)
+#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
/*
@@ -213,10 +216,10 @@ pppopen(dev, tp)
register struct ppp_softc *sc;
int error, s;
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
return (error);
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
if (tp->t_line == PPPDISC) {
sc = (struct ppp_softc *) tp->t_sc;
@@ -283,7 +286,7 @@ pppclose(tp, flag)
register struct ppp_softc *sc;
int s;
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
ttyflush(tp, FREAD | FWRITE);
clist_free_cblocks(&tp->t_canq);
clist_free_cblocks(&tp->t_outq);
@@ -309,7 +312,7 @@ pppasyncrelinq(sc)
{
int s;
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
if (sc->sc_outm) {
m_freem(sc->sc_outm);
sc->sc_outm = NULL;
@@ -335,7 +338,7 @@ register struct ppp_softc *sc;
register struct tty *tp = (struct tty *) sc->sc_devp;
int s;
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
if (tp != NULL)
clist_alloc_cblocks(&tp->t_outq, sc->sc_if.if_mtu + PPP_HIWAT,
sc->sc_if.if_mtu + PPP_HIWAT);
@@ -344,7 +347,7 @@ register struct ppp_softc *sc;
/*
* Line specific (tty) read routine.
- * called at no spl from the device driver in the response to user-level
+ * called at zero spl from the device driver in the response to user-level
* reads on the tty file descriptor (ie: pppd).
*/
static int
@@ -364,7 +367,7 @@ pppread(tp, uio, flag)
* Loop waiting for input, checking that nothing disasterous
* happens in the meantime.
*/
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
for (;;) {
if (tp != (struct tty *) sc->sc_devp || tp->t_line != PPPDISC) {
splx(s);
@@ -380,7 +383,7 @@ pppread(tp, uio, flag)
splx(s);
return (EWOULDBLOCK);
}
- error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, "pppin", 0);
+ error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI | PCATCH, "ttyin", 0);
if (error) {
splx(s);
return error;
@@ -395,7 +398,7 @@ pppread(tp, uio, flag)
splx(s);
for (m = m0; m && uio->uio_resid; m = m->m_next)
- if (error = uiomove(mtod(m, u_char *), m->m_len, uio))
+ if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
break;
m_freem(m0);
return (error);
@@ -403,7 +406,7 @@ pppread(tp, uio, flag)
/*
* Line specific (tty) write routine.
- * called at no spl from the device driver in the response to user-level
+ * called at zero spl from the device driver in the response to user-level
* writes on the tty file descriptor (ie: pppd).
*/
static int
@@ -427,7 +430,7 @@ pppwrite(tp, uio, flag)
uio->uio_resid < PPP_HDRLEN)
return (EMSGSIZE);
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
MGET(m, M_WAIT, MT_DATA);
if ((*mp = m) == NULL) {
@@ -441,7 +444,7 @@ pppwrite(tp, uio, flag)
len = M_TRAILINGSPACE(m);
if (len > uio->uio_resid)
len = uio->uio_resid;
- if (error = uiomove(mtod(m, u_char *), len, uio)) {
+ if ((error = uiomove(mtod(m, u_char *), len, uio)) != 0) {
m_freem(m0);
splx(s);
return (error);
@@ -468,8 +471,9 @@ pppwrite(tp, uio, flag)
static int
ppptioctl(tp, cmd, data, flag, p)
struct tty *tp;
+ int cmd;
caddr_t data;
- int cmd, flag;
+ int flag;
struct proc *p;
{
struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
@@ -481,7 +485,7 @@ ppptioctl(tp, cmd, data, flag, p)
error = 0;
switch (cmd) {
case PPPIOCSASYNCMAP:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
sc->sc_asyncmap[0] = *(u_int *)data;
break;
@@ -491,7 +495,7 @@ ppptioctl(tp, cmd, data, flag, p)
break;
case PPPIOCSRASYNCMAP:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
sc->sc_rasyncmap = *(u_int *)data;
break;
@@ -501,9 +505,9 @@ ppptioctl(tp, cmd, data, flag, p)
break;
case PPPIOCSXASYNCMAP:
- if (error = suser(p->p_ucred, &p->p_acflag))
+ if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
break;
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
@@ -577,70 +581,20 @@ pppfcs(fcs, cp, len)
}
/*
- * This gets called from pppoutput when a new packet is
- * put on a queue.
+ * This gets called at splsoftnet from if_ppp.c at various times
+ * when there is data ready to be sent.
*/
static void
pppasyncstart(sc)
register struct ppp_softc *sc;
{
register struct tty *tp = (struct tty *) sc->sc_devp;
- int s;
-
- s = spltty(); /* raise from splnet to spltty */
- pppstart(tp);
- splx(s);
-}
-
-/*
- * This gets called when a received packet is placed on
- * the inq. The pppd daemon is to be woken up to do a read().
- */
-static void
-pppasyncctlp(sc)
- struct ppp_softc *sc;
-{
- struct tty *tp;
- int s;
-
- /* Put a placeholder byte in canq for ttselect()/ttnread(). */
- s = spltty(); /* raise from splnet to spltty */
- tp = (struct tty *) sc->sc_devp;
- putc(0, &tp->t_canq);
- ttwakeup(tp);
- splx(s);
-}
-
-/*
- * Start output on async tty interface. Get another datagram
- * to send from the interface queue and start sending it.
- *
- * Called from tty system at splsofttty() or spltty().
- * Called from the upper half at softnet, raised to spltty via asyncstart.
- *
- * Harmless to be called while the upper netisr code is preempted, but we
- * do not want to be preempted by it again.
- */
-static int
-pppstart(tp)
- register struct tty *tp;
-{
- register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
register struct mbuf *m;
register int len;
register u_char *start, *stop, *cp;
- int n, s, ndone, done, idle;
+ int n, ndone, done, idle;
struct mbuf *m2;
-
- if ((tp->t_state & TS_CONNECTED) == 0
- || sc == NULL || tp != (struct tty *) sc->sc_devp
- || tp->t_line != PPPDISC) {
- if (tp->t_oproc != NULL)
- (*tp->t_oproc)(tp);
- return 0;
- }
-
- s = spltty(); /* in case.. do not want netisrs to preempt us */
+ int s;
idle = 0;
while (CCOUNT(&tp->t_outq) < PPP_HIWAT) {
@@ -665,12 +619,13 @@ pppstart(tp)
* the line may have been idle for some time.
*/
if (CCOUNT(&tp->t_outq) == 0) {
- ++sc->sc_bytessent;
+ ++sc->sc_stats.ppp_obytes;
(void) putc(PPP_FLAG, &tp->t_outq);
}
/* Calculate the FCS for the first mbuf's worth. */
sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
+ sc->sc_if.if_lastchange = time;
}
for (;;) {
@@ -691,24 +646,27 @@ pppstart(tp)
ndone = n - b_to_q(start, n, &tp->t_outq);
len -= ndone;
start += ndone;
- sc->sc_bytessent += ndone;
+ sc->sc_stats.ppp_obytes += ndone;
if (ndone < n)
break; /* packet doesn't fit */
}
/*
* If there are characters left in the mbuf,
- * the first one must be special..
+ * the first one must be special.
* Put it out in a different form.
*/
if (len) {
+ s = spltty();
if (putc(PPP_ESCAPE, &tp->t_outq))
break;
if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
(void) unputc(&tp->t_outq);
+ splx(s);
break;
}
- sc->sc_bytessent += 2;
+ splx(s);
+ sc->sc_stats.ppp_obytes += 2;
start++;
len--;
}
@@ -748,6 +706,7 @@ pppstart(tp)
* Try to output the FCS and flag. If the bytes
* don't all fit, back out.
*/
+ s = spltty();
for (q = endseq; q < p; ++q)
if (putc(*q, &tp->t_outq)) {
done = 0;
@@ -755,7 +714,9 @@ pppstart(tp)
unputc(&tp->t_outq);
break;
}
- sc->sc_bytessent += q - endseq;
+ splx(s);
+ if (done)
+ sc->sc_stats.ppp_obytes += q - endseq;
}
if (!done) {
@@ -770,28 +731,24 @@ pppstart(tp)
m = m2;
if (m == NULL) {
/* Finished a packet */
- sc->sc_if.if_opackets++;
- sc->sc_if.if_obytes = sc->sc_bytessent;
break;
}
sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
}
/*
- * Here we have either finished a packet (m == NULL)
- * or filled up the output queue (m != NULL).
+ * If m == NULL, we have finished a packet.
+ * If m != NULL, we've either done as much work this time
+ * as we need to, or else we've filled up the output queue.
*/
sc->sc_outm = m;
if (m)
break;
}
- /*
- * Call output process whether or not there is any output.
- * We are being called in lieu of ttstart and must do what it would.
- */
- if (tp->t_oproc != NULL)
- (*tp->t_oproc)(tp);
+ /* Call pppstart to start output again if necessary. */
+ s = spltty();
+ pppstart(tp);
/*
* This timeout is needed for operation on a pseudo-tty,
@@ -802,7 +759,58 @@ pppstart(tp)
timeout(ppp_timeout, (void *) sc, 1);
sc->sc_flags |= SC_TIMEOUT;
}
+
+ splx(s);
+}
+
+/*
+ * This gets called when a received packet is placed on
+ * the inq, at splsoftnet. The pppd daemon is to be woken up to do a read().
+ */
+static void
+pppasyncctlp(sc)
+ struct ppp_softc *sc;
+{
+ struct tty *tp;
+ int s;
+
+ /* Put a placeholder byte in canq for ttselect()/ttnread(). */
+ s = spltty();
+ tp = (struct tty *) sc->sc_devp;
+ putc(0, &tp->t_canq);
+ ttwakeup(tp);
splx(s);
+}
+
+/*
+ * Start output on async tty interface. If the transmit queue
+ * has drained sufficiently, arrange for pppasyncstart to be
+ * called later at splsoftnet.
+ * Called at spltty or higher.
+ */
+int
+pppstart(tp)
+ register struct tty *tp;
+{
+ register struct ppp_softc *sc = (struct ppp_softc *) tp->t_sc;
+
+ /*
+ * If there is stuff in the output queue, send it now.
+ * We are being called in lieu of ttstart and must do what it would.
+ */
+ if (tp->t_oproc != NULL)
+ (*tp->t_oproc)(tp);
+
+ /*
+ * If the transmit queue has drained and the tty has not hung up
+ * or been disconnected from the ppp unit, then tell if_ppp.c that
+ * we need more output.
+ */
+ if (CCOUNT(&tp->t_outq) < PPP_LOWAT
+ && !((tp->t_state & TS_CONNECTED) == 0)
+ && sc != NULL && tp == (struct tty *) sc->sc_devp) {
+ ppp_restart(sc);
+ }
return 0;
}
@@ -818,7 +826,7 @@ ppp_timeout(x)
struct tty *tp = (struct tty *) sc->sc_devp;
int s;
- s = spltty(); /* also netisr's, including NETISR_PPP */
+ s = spltty();
sc->sc_flags &= ~SC_TIMEOUT;
pppstart(tp);
splx(s);
@@ -833,9 +841,7 @@ pppgetm(sc)
{
struct mbuf *m, **mp;
int len;
- int s;
- s = spltty(); /* also netisr's, including NETISR_PPP */
mp = &sc->sc_m;
for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
if ((m = *mp) == NULL) {
@@ -848,7 +854,6 @@ pppgetm(sc)
len -= M_DATASIZE(m);
mp = &m->m_next;
}
- splx(s);
}
/*
@@ -877,9 +882,8 @@ pppinput(c, tp)
if (sc == NULL || tp != (struct tty *) sc->sc_devp)
return 0;
- s = spltty(); /* also netisr's, including NETISR_PPP */
++tk_nin;
- ++sc->sc_bytesrcvd;
+ ++sc->sc_stats.ppp_ibytes;
if ((tp->t_state & TS_CONNECTED) == 0) {
if (sc->sc_flags & SC_DEBUG)
@@ -897,6 +901,26 @@ pppinput(c, tp)
c &= TTY_CHARMASK;
+ /*
+ * Handle software flow control of output.
+ */
+ if (tp->t_iflag & IXON) {
+ if (c == tp->t_cc[VSTOP] && tp->t_cc[VSTOP] != _POSIX_VDISABLE) {
+ if ((tp->t_state & TS_TTSTOP) == 0) {
+ tp->t_state |= TS_TTSTOP;
+ (*cdevsw[major(tp->t_dev)]->d_stop)(tp, 0);
+ }
+ return 0;
+ }
+ if (c == tp->t_cc[VSTART] && tp->t_cc[VSTART] != _POSIX_VDISABLE) {
+ tp->t_state &= ~TS_TTSTOP;
+ if (tp->t_oproc != NULL)
+ (*tp->t_oproc)(tp);
+ return 0;
+ }
+ }
+
+ s = spltty();
if (c & 0x80)
sc->sc_flags |= SC_RCV_B7_1;
else
@@ -905,6 +929,7 @@ pppinput(c, tp)
sc->sc_flags |= SC_RCV_ODDP;
else
sc->sc_flags |= SC_RCV_EVNP;
+ splx(s);
if (sc->sc_flags & SC_LOG_RAWIN)
ppplogchar(sc, c);
@@ -912,7 +937,6 @@ pppinput(c, tp)
if (c == PPP_FLAG) {
ilen = sc->sc_ilen;
sc->sc_ilen = 0;
- sc->sc_if.if_ibytes = sc->sc_bytesrcvd;
if (sc->sc_rawin_count > 0)
ppplogchar(sc, -1);
@@ -922,13 +946,15 @@ pppinput(c, tp)
* abort sequence "}~".
*/
if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
- || ilen > 0 && sc->sc_fcs != PPP_GOODFCS) {
+ || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
+ s = spltty();
sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad fcs %x\n", sc->sc_if.if_unit,
- sc->sc_fcs);
+ printf("ppp%d: bad fcs %x, pkt len %d\n",
+ sc->sc_if.if_unit, sc->sc_fcs, ilen);
sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
} else
sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
splx(s);
@@ -939,10 +965,12 @@ pppinput(c, tp)
if (ilen) {
if (sc->sc_flags & SC_DEBUG)
printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
+ s = spltty();
sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
sc->sc_flags |= SC_PKTLOST;
+ splx(s);
}
- splx(s);
return 0;
}
@@ -963,25 +991,26 @@ pppinput(c, tp)
sc->sc_mc->m_next = NULL;
ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
- sc->sc_flags &= ~SC_PKTLOST;
+ if (sc->sc_flags & SC_PKTLOST) {
+ s = spltty();
+ sc->sc_flags &= ~SC_PKTLOST;
+ splx(s);
+ }
pppgetm(sc);
- splx(s);
return 0;
}
if (sc->sc_flags & SC_FLUSH) {
if (sc->sc_flags & SC_LOG_FLUSH)
ppplogchar(sc, c);
- splx(s);
return 0;
}
- if (c < 0x20 && (sc->sc_rasyncmap & (1 << c))) {
- splx(s);
+ if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
return 0;
- }
+ s = spltty();
if (sc->sc_flags & SC_ESCAPED) {
sc->sc_flags &= ~SC_ESCAPED;
c ^= PPP_TRANS;
@@ -990,6 +1019,7 @@ pppinput(c, tp)
splx(s);
return 0;
}
+ splx(s);
/*
* Initialize buffer on first octet received.
@@ -1075,17 +1105,18 @@ pppinput(c, tp)
++m->m_len;
*sc->sc_mp++ = c;
sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
- splx(s);
return 0;
flush:
if (!(sc->sc_flags & SC_FLUSH)) {
+ s = spltty();
sc->sc_if.if_ierrors++;
+ sc->sc_stats.ppp_ierrors++;
sc->sc_flags |= SC_FLUSH;
+ splx(s);
if (sc->sc_flags & SC_LOG_FLUSH)
ppplogchar(sc, c);
}
- splx(s);
return 0;
}
@@ -1099,7 +1130,7 @@ ppplogchar(sc, c)
if (c >= 0)
sc->sc_rawin[sc->sc_rawin_count++] = c;
if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
- || c < 0 && sc->sc_rawin_count > 0) {
+ || (c < 0 && sc->sc_rawin_count > 0)) {
printf("ppp%d input: %*D", sc->sc_if.if_unit,
sc->sc_rawin_count, sc->sc_rawin, " ");
sc->sc_rawin_count = 0;
OpenPOWER on IntegriCloud