diff options
Diffstat (limited to 'sys/net/if_ppp.c')
-rw-r--r-- | sys/net/if_ppp.c | 303 |
1 files changed, 160 insertions, 143 deletions
diff --git a/sys/net/if_ppp.c b/sys/net/if_ppp.c index 4e8dc87d27e..f8997836756 100644 --- a/sys/net/if_ppp.c +++ b/sys/net/if_ppp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ppp.c,v 1.7 1996/05/10 12:31:10 deraadt Exp $ */ +/* $OpenBSD: if_ppp.c,v 1.8 1996/07/25 14:20:50 joshd Exp $ */ /* $NetBSD: if_ppp.c,v 1.31 1996/05/07 02:40:36 thorpej Exp $ */ /* @@ -91,6 +91,10 @@ #include <sys/time.h> #include <sys/malloc.h> +#if NetBSD1_0 && defined(i386) +#include <machine/psl.h> +#endif + #include <net/if.h> #include <net/if_types.h> #include <net/netisr.h> @@ -119,13 +123,16 @@ #include <net/if_pppvar.h> #include <machine/cpu.h> +#if NetBSD1_0 +#define splsoftnet splnet +#endif + #ifdef PPP_COMPRESS #define PACKETPTR struct mbuf * #include <net/ppp-comp.h> #endif static void ppp_requeue __P((struct ppp_softc *)); -static void ppp_outpkt __P((struct ppp_softc *)); static void ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd)); static void ppp_ccp_closed __P((struct ppp_softc *)); static void ppp_inproc __P((struct ppp_softc *, struct mbuf *)); @@ -200,6 +207,19 @@ pppattach() bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN); #endif } + +#if NetBSD1_0 && defined(i386) + /* + * XXX kludge to fix the bug in the i386 interrupt handling code, + * where software interrupts could be taken while hardware + * interrupts were blocked. + */ + if ((imask[IPL_TTY] & (1 << SIR_NET)) == 0) { + imask[IPL_TTY] |= (1 << SIR_NET); + intr_calculatemasks(); + } +#endif + } /* @@ -839,190 +859,187 @@ ppp_requeue(sc) } /* - * Get a packet to send. This procedure is intended to be called at - * spltty or splimp, so it takes little time. If there isn't a packet - * waiting to go out, it schedules a software interrupt to prepare a - * new packet; the device start routine gets called again when a - * packet is ready. + * Transmitter has finished outputting some stuff; + * remember to call sc->sc_start later at splsoftnet. */ -struct mbuf * -ppp_dequeue(sc) +void +ppp_restart(sc) struct ppp_softc *sc; { - struct mbuf *m; - int s = splhigh(); + int s = splimp(); - m = sc->sc_togo; - if (m) { - /* - * Had a packet waiting - send it. - */ - sc->sc_togo = NULL; - sc->sc_flags |= SC_TBUSY; - splx(s); - return m; - } - /* - * Remember we wanted a packet and schedule a software interrupt. - */ sc->sc_flags &= ~SC_TBUSY; schednetisr(NETISR_PPP); splx(s); - return NULL; } -/* - * Software interrupt routine, called at splsoftnet. - */ -void -pppintr() -{ - struct ppp_softc *sc; - int i, s; - struct mbuf *m; - - sc = ppp_softc; - for (i = 0; i < NPPP; ++i, ++sc) { - if (!(sc->sc_flags & SC_TBUSY) && sc->sc_togo == NULL - && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) - ppp_outpkt(sc); - for (;;) { - s = splhigh(); - IF_DEQUEUE(&sc->sc_rawq, m); - splx(s); - if (m == NULL) - break; - ppp_inproc(sc, m); - } - } -} /* - * Grab another packet off a queue and apply VJ compression, - * packet compression, address/control and/or protocol compression - * if enabled. Should be called at splsoftnet. + * Get a packet to send. This procedure is intended to be called at + * splsoftnet, since it may involve time-consuming operations such as + * applying VJ compression, packet compression, address/control and/or + * protocol field compression to the packet. */ -static void -ppp_outpkt(sc) +struct mbuf * +ppp_dequeue(sc) struct ppp_softc *sc; { struct mbuf *m, *mp; u_char *cp; int address, control, protocol; - + int s = splhigh(); + /* * Grab a packet to send: first try the fast queue, then the * normal queue. */ IF_DEQUEUE(&sc->sc_fastq, m); - if (m == NULL) + if (m == NULL) IF_DEQUEUE(&sc->sc_if.if_snd, m); if (m == NULL) - return; - + { splx(s); + return NULL; + } + ++sc->sc_stats.ppp_opackets; /* * Extract the ppp header of the new packet. - * The ppp header will be in one mbuf. + * The ppp header will be in one mbuf. */ cp = mtod(m, u_char *); address = PPP_ADDRESS(cp); control = PPP_CONTROL(cp); protocol = PPP_PROTOCOL(cp); - + switch (protocol) { case PPP_IP: #ifdef VJC - /* - * If the packet is a TCP/IP packet, see if we can compress it. - */ - if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) { - struct ip *ip; - int type; - - mp = m; - ip = (struct ip *) (cp + PPP_HDRLEN); - if (mp->m_len <= PPP_HDRLEN) { - mp = mp->m_next; - if (mp == NULL) - break; - ip = mtod(mp, struct ip *); - } - /* this code assumes the IP/TCP header is in one non-shared mbuf */ - if (ip->ip_p == IPPROTO_TCP) { - type = sl_compress_tcp(mp, ip, sc->sc_comp, - !(sc->sc_flags & SC_NO_TCP_CCID)); - switch (type) { - case TYPE_UNCOMPRESSED_TCP: - protocol = PPP_VJC_UNCOMP; - break; - case TYPE_COMPRESSED_TCP: - protocol = PPP_VJC_COMP; - cp = mtod(m, u_char *); - cp[0] = address; /* header has moved */ - cp[1] = control; - cp[2] = 0; - break; - } - cp[3] = protocol; /* update protocol in PPP header */ - } - } -#endif /* VJC */ - break; - + /* + * If the packet is a TCP/IP packet, see if we can compress it. + */ + if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) { + struct ip *ip; + int type; + + mp = m; + ip = (struct ip *) (cp + PPP_HDRLEN); + if (mp->m_len <= PPP_HDRLEN) { + mp = mp->m_next; + if (mp == NULL) + break; + ip = mtod(mp, struct ip *); + } + /* this code assumes the IP/TCP header is in one non-shared +mbuf */ + if (ip->ip_p == IPPROTO_TCP) { + type = sl_compress_tcp(mp, ip, sc->sc_comp, + !(sc->sc_flags & SC_NO_TCP_CCID)); + switch (type) { + case TYPE_UNCOMPRESSED_TCP: + protocol = PPP_VJC_UNCOMP; + break; + case TYPE_COMPRESSED_TCP: + protocol = PPP_VJC_COMP; + cp = mtod(m, u_char *); + cp[0] = address; /* header has moved */ + cp[1] = control; + cp[2] = 0; + break; + } + cp[3] = protocol; /* update protocol in PPP header */ + } + } +#endif /* VJC */ + break; + #ifdef PPP_COMPRESS case PPP_CCP: - ppp_ccp(sc, m, 0); - break; -#endif /* PPP_COMPRESS */ + ppp_ccp(sc, m, 0); + break; +#endif /* PPP_COMPRESS */ } - + #ifdef PPP_COMPRESS if (protocol != PPP_LCP && protocol != PPP_CCP - && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) { - struct mbuf *mcomp = NULL; - int slen, clen; - - slen = 0; - for (mp = m; mp != NULL; mp = mp->m_next) - slen += mp->m_len; - clen = (*sc->sc_xcomp->compress) - (sc->sc_xc_state, &mcomp, m, slen, - (sc->sc_flags & SC_CCP_UP? sc->sc_if.if_mtu: 0)); - if (mcomp != NULL) { - m_freem(m); - m = mcomp; - cp = mtod(m, u_char *); - protocol = cp[3]; - } + && sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) { + struct mbuf *mcomp = NULL; + int slen, clen; + + slen = 0; + for (mp = m; mp != NULL; mp = mp->m_next) + slen += mp->m_len; + clen = (*sc->sc_xcomp->compress) + (sc->sc_xc_state, &mcomp, m, slen, + (sc->sc_flags & SC_CCP_UP? sc->sc_if.if_mtu: 0)); + if (mcomp != NULL) { + m_freem(m); + m = mcomp; + cp = mtod(m, u_char *); + protocol = cp[3]; + } } -#endif /* PPP_COMPRESS */ - +#endif /* PPP_COMPRESS */ + /* * Compress the address/control and protocol, if possible. */ if (sc->sc_flags & SC_COMP_AC && address == PPP_ALLSTATIONS && - control == PPP_UI && protocol != PPP_ALLSTATIONS && - protocol != PPP_LCP) { - /* can compress address/control */ - m->m_data += 2; - m->m_len -= 2; - } + control == PPP_UI && protocol != PPP_ALLSTATIONS && + protocol != PPP_LCP) { + /* can compress address/control */ + m->m_data += 2; + m->m_len -= 2; + } if (sc->sc_flags & SC_COMP_PROT && protocol < 0xFF) { - /* can compress protocol */ - if (mtod(m, u_char *) == cp) { - cp[2] = cp[1]; /* move address/control up */ - cp[1] = cp[0]; - } - ++m->m_data; - --m->m_len; + /* can compress protocol */ + if (mtod(m, u_char *) == cp) { + cp[2] = cp[1]; /* move address/control up */ + cp[1] = cp[0]; + } + ++m->m_data; + --m->m_len; } + splx(s); + return m; + +} - sc->sc_togo = m; - (*sc->sc_start)(sc); +/* + * Software interrupt routine, called at splsoftnet. + */ +void +pppintr() +{ + struct ppp_softc *sc; + int i, s, s2; + struct mbuf *m; + + sc = ppp_softc; + s = splsoftnet(); + for (i = 0; i < NPPP; ++i, ++sc) { + if (!(sc->sc_flags & SC_TBUSY) + && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) { + s2 = splimp(); + sc->sc_flags |= SC_TBUSY; + splx(s2); + (*sc->sc_start)(sc); + } + for (;;) { + s2 = splimp(); + IF_DEQUEUE(&sc->sc_rawq, m); + splx(s2); + if (m == NULL) + break; + ppp_inproc(sc, m); + } + } + splx(s); + } + + #ifdef PPP_COMPRESS /* * Handle a CCP packet. `rcvd' is 1 if the packet was received, @@ -1068,7 +1085,7 @@ ppp_ccp(sc, m, rcvd) case CCP_TERMACK: /* CCP must be going down - disable compression */ if (sc->sc_flags & SC_CCP_UP) { - s = splhigh(); + s = splimp(); sc->sc_flags &= ~(SC_CCP_UP | SC_COMP_RUN | SC_DECOMP_RUN); splx(s); } @@ -1084,7 +1101,7 @@ ppp_ccp(sc, m, rcvd) && (*sc->sc_xcomp->comp_init) (sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, sc->sc_unit, 0, sc->sc_flags & SC_DEBUG)) { - s = splhigh(); + s = splimp(); sc->sc_flags |= SC_COMP_RUN; splx(s); } @@ -1095,7 +1112,7 @@ ppp_ccp(sc, m, rcvd) (sc->sc_rc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN, sc->sc_unit, 0, sc->sc_mru, sc->sc_flags & SC_DEBUG)) { - s = splhigh(); + s = splimp(); sc->sc_flags |= SC_DECOMP_RUN; sc->sc_flags &= ~(SC_DC_ERROR | SC_DC_FERROR); splx(s); @@ -1152,7 +1169,7 @@ ppppktin(sc, m, lost) struct mbuf *m; int lost; { - int s = splhigh(); + int s = splimp(); if (lost) m->m_flags |= M_ERRMARK; @@ -1198,7 +1215,7 @@ ppp_inproc(sc, m) if (m->m_flags & M_ERRMARK) { m->m_flags &= ~M_ERRMARK; - s = splhigh(); + s = splimp(); sc->sc_flags |= SC_VJ_RESET; splx(s); } @@ -1230,7 +1247,7 @@ ppp_inproc(sc, m) */ if (sc->sc_flags & SC_DEBUG) printf("%s: decompress failed %d\n", ifp->if_xname, rv); - s = splhigh(); + s = splimp(); sc->sc_flags |= SC_VJ_RESET; if (rv == DECOMP_ERROR) sc->sc_flags |= SC_DC_ERROR; @@ -1261,7 +1278,7 @@ ppp_inproc(sc, m) */ if (sc->sc_comp) sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp); - s = splhigh(); + s = splimp(); sc->sc_flags &= ~SC_VJ_RESET; splx(s); } @@ -1417,7 +1434,7 @@ ppp_inproc(sc, m) /* * Put the packet on the appropriate input queue. */ - s = splhigh(); + s = splimp(); if (IF_QFULL(inq)) { IF_DROP(inq); splx(s); |