aboutsummaryrefslogtreecommitdiff
path: root/sys/net/if_ppp.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/net/if_ppp.c')
-rw-r--r--sys/net/if_ppp.c108
1 files changed, 66 insertions, 42 deletions
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c
index efda46dbe54a..18beb9a345cd 100644
--- a/sys/net/if_ppp.c
+++ b/sys/net/if_ppp.c
@@ -70,7 +70,7 @@
*/
/*
- * $Id: if_ppp.c,v 1.7 1993/12/20 19:31:30 wollman Exp $
+ * $Id: if_ppp.c,v 1.13 1994/05/30 03:37:47 ache Exp $
* From: if_ppp.c,v 1.22 1993/08/31 23:20:40 paulus Exp
* From: if_ppp.c,v 1.21 1993/08/29 11:22:37 paulus Exp
* From: if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp
@@ -92,6 +92,7 @@
#include "kernel.h"
#include "conf.h"
#include "dkstat.h"
+#include "pppdefs.h"
#include "if.h"
#include "if_types.h"
@@ -117,11 +118,11 @@
#ifndef RB_LEN
/* NetBSD, 4.3-Reno or similar */
#define CCOUNT(q) ((q)->c_cc)
+#define TSA_HUP_OR_INPUT(tp) ((caddr_t)&tp->t_rawq)
#else
/* 386BSD, Jolitz-style ring buffers */
#define t_outq t_out
-#define t_rawq t_raw
#define t_canq t_can
#define CCOUNT(q) (RB_LEN(q))
#endif
@@ -249,7 +250,7 @@ pppopen(dev, tp)
if (sc->sc_ttyp == NULL)
break;
if (nppp >= NPPP)
- return ENXIO;
+ return (ENXIO);
sc->sc_flags = 0;
sc->sc_ilen = 0;
@@ -344,33 +345,40 @@ pppread(tp, uio, flag)
{
register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
struct mbuf *m, *m0;
- register int s;
- int error = 0;
+ int s;
+ int error;
- if ((tp->t_state & TS_CARR_ON)==0)
- return (EIO);
s = splimp();
- while (sc->sc_inq.ifq_head == NULL && tp->t_line == PPPDISC) {
+ for (;;) {
+ if (tp->t_line != PPPDISC) {
+ splx(s);
+ return (ENXIO);
+ }
+ if (!CAN_DO_IO(tp)) {
+ splx(s);
+ return (EIO);
+ }
+ if (sc->sc_inq.ifq_head != NULL)
+ break;
if (tp->t_state & TS_ASYNC) {
splx(s);
return (EWOULDBLOCK);
}
- error = ttysleep(tp, (caddr_t)&tp->t_rawq, TTIPRI|PCATCH, ttyin, 0);
- if (error)
- return error;
- }
- if (tp->t_line != PPPDISC) {
- splx(s);
- return (-1);
+ error = ttysleep(tp, TSA_HUP_OR_INPUT(tp), TTIPRI | PCATCH, "pppin", 0);
+ if (error) {
+ splx(s);
+ return (error);
+ }
}
/* Pull place-holder byte out of canonical queue */
- getc(&tp->t_canq);
+ getc(tp->t_canq);
/* Get the packet from the input queue */
IF_DEQUEUE(&sc->sc_inq, m0);
splx(s);
+ error = 0;
for (m = m0; m && uio->uio_resid; m = m->m_next)
if (error = uiomove(mtod(m, u_char *), m->m_len, uio))
break;
@@ -391,19 +399,33 @@ pppwrite(tp, uio, flag)
struct mbuf *m, *m0, **mp;
struct sockaddr dst;
struct ppp_header *ph1, *ph2;
- int len, error;
+ int len, error, s;
- if ((tp->t_state & TS_CARR_ON)==0)
- return (EIO);
if (tp->t_line != PPPDISC)
- return (EINVAL);
+ return (ENXIO);
+
+ /*
+ * XXX the locking is probably too strong, and/or the order of checking
+ * for errors requires an inconvenient number of splx()'s. pppoutput()
+ * does its own locking, but we must hold at least an spltty() lock to
+ * preserve the validity of the test of TS_CARR_ON in CAN_DO_IO().
+ */
+ s = splimp();
+
+ if (!CAN_DO_IO(tp)) {
+ splx(s);
+ return (EIO);
+ }
if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HEADER_LEN ||
- uio->uio_resid < PPP_HEADER_LEN)
+ uio->uio_resid < PPP_HEADER_LEN) {
+ splx(s);
return (EMSGSIZE);
+ }
for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
MGET(m, M_WAIT, MT_DATA);
if ((*mp = m) == NULL) {
m_freem(m0);
+ splx(s);
return (ENOBUFS);
}
if (uio->uio_resid >= MCLBYTES / 2)
@@ -411,6 +433,7 @@ pppwrite(tp, uio, flag)
len = MIN(M_TRAILINGSPACE(m), uio->uio_resid);
if (error = uiomove(mtod(m, u_char *), len, uio)) {
m_freem(m0);
+ splx(s);
return (error);
}
m->m_len = len;
@@ -421,7 +444,9 @@ pppwrite(tp, uio, flag)
*ph1 = *ph2;
m0->m_data += PPP_HEADER_LEN;
m0->m_len -= PPP_HEADER_LEN;
- return (pppoutput(&sc->sc_if, m0, &dst, 0));
+ error = pppoutput(&sc->sc_if, m0, &dst, 0);
+ splx(s);
+ return (error);
}
/*
@@ -589,7 +614,7 @@ pppoutput(ifp, m0, dst, rt)
error = ENETDOWN; /* sort of */
goto bad;
}
- if ((sc->sc_ttyp->t_state & TS_CARR_ON) == 0) {
+ if (!CAN_DO_IO(sc->sc_ttyp)) {
error = EHOSTUNREACH;
goto bad;
}
@@ -711,15 +736,14 @@ pppstart(tp)
for (;;) {
/*
- * If there is more in the output queue, just send it now.
+ * 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 (CCOUNT(&tp->t_outq) != 0 && tp->t_oproc != NULL) {
- (*tp->t_oproc)(tp);
- if (CCOUNT(&tp->t_outq) > PPP_HIWAT)
- return;
- }
+ (*tp->t_oproc)(tp);
+ if (CCOUNT(tp->t_outq) > PPP_HIWAT)
+ return;
+
/*
* This happens briefly when the line shuts down.
*/
@@ -809,9 +833,9 @@ pppstart(tp)
* will flush any accumulated garbage. We do this whenever
* the line may have been idle for some time.
*/
- if (CCOUNT(&tp->t_outq) == 0) {
+ if (CCOUNT(tp->t_outq) == 0) {
++sc->sc_bytessent;
- (void) putc(PPP_FLAG, &tp->t_outq);
+ (void) putc(PPP_FLAG, tp->t_outq);
}
/* Calculate the FCS for the first mbuf's worth. */
@@ -834,7 +858,7 @@ pppstart(tp)
if (n) {
#ifndef RB_LEN
/* NetBSD (0.9 or later), 4.3-Reno or similar. */
- ndone = n - b_to_q(start, n, &tp->t_outq);
+ ndone = n - b_to_q(start, n, tp->t_outq);
#else
#ifdef NetBSD
/* NetBSD with 2-byte ring buffer entries */
@@ -843,12 +867,12 @@ pppstart(tp)
/* 386BSD, FreeBSD */
int cc, nleft;
for (nleft = n; nleft > 0; nleft -= cc) {
- if ((cc = RB_CONTIGPUT(&tp->t_out)) == 0)
+ if ((cc = RB_CONTIGPUT(tp->t_out)) == 0)
break;
cc = min (cc, nleft);
- bcopy((char *)start + n - nleft, tp->t_out.rb_tl, cc);
- tp->t_out.rb_tl = RB_ROLLOVER(&tp->t_out,
- tp->t_out.rb_tl + cc);
+ bcopy((char *)start + n - nleft, tp->t_out->rb_tl, cc);
+ tp->t_out->rb_tl = RB_ROLLOVER(tp->t_out,
+ tp->t_out->rb_tl + cc);
}
ndone = n - nleft;
#endif /* NetBSD */
@@ -866,10 +890,10 @@ pppstart(tp)
* Put it out in a different form.
*/
if (len) {
- if (putc(PPP_ESCAPE, &tp->t_outq))
+ if (putc(PPP_ESCAPE, tp->t_outq))
break;
- if (putc(*start ^ PPP_TRANS, &tp->t_outq)) {
- (void) unputc(&tp->t_outq);
+ if (putc(*start ^ PPP_TRANS, tp->t_outq)) {
+ (void) unputc(tp->t_outq);
break;
}
sc->sc_bytessent += 2;
@@ -912,10 +936,10 @@ pppstart(tp)
* don't all fit, back out.
*/
for (q = endseq; q < p; ++q)
- if (putc(*q, &tp->t_outq)) {
+ if (putc(*q, tp->t_outq)) {
done = 0;
for (; q > endseq; --q)
- unputc(&tp->t_outq);
+ unputc(tp->t_outq);
break;
}
}
@@ -1213,7 +1237,7 @@ pppinput(c, tp)
* Some other protocol - place on input queue for read().
* Put a placeholder byte in canq for ttselect()/ttnread().
*/
- putc(0, &tp->t_canq);
+ putc(0, tp->t_canq);
ttwakeup(tp);
inq = &sc->sc_inq;
break;