* Paul Mackerras (paulus@cs.anu.edu.au).
*/
-/* $Id: if_ppp.c,v 1.2 1995/04/28 06:19:34 paulus Exp $ */
+/* $Id: if_ppp.c,v 1.6 1995/10/27 03:34:42 paulus Exp $ */
/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
#include "ppp.h"
#endif
void pppattach __P((void));
-int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag,
+int pppioctl __P((struct ppp_softc *sc, u_long cmd, caddr_t data, int flag,
struct proc *));
int pppoutput __P((struct ifnet *ifp, struct mbuf *m0,
struct sockaddr *dst, struct rtentry *rtp));
-int pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data));
+int pppsioctl __P((struct ifnet *ifp, u_long cmd, caddr_t data));
void pppintr __P((void));
static void ppp_requeue __P((struct ppp_softc *));
extern struct compressor ppp_bsd_compress;
struct compressor *ppp_compressors[8] = {
+#if DO_BSD_COMPRESS
&ppp_bsd_compress,
+#endif
NULL
};
#endif /* PPP_COMPRESS */
sc->sc_if.if_name = "ppp";
sc->sc_if.if_unit = i++;
sc->sc_if.if_mtu = PPP_MTU;
- sc->sc_if.if_flags = IFF_POINTOPOINT;
+ sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST;
sc->sc_if.if_type = IFT_PPP;
sc->sc_if.if_hdrlen = PPP_HDRLEN;
sc->sc_if.if_ioctl = pppsioctl;
bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
}
- netisrs[NETISR_PPP] = ppp_intr;
+ netisrs[NETISR_PPP] = pppintr;
}
/*
int
pppioctl(sc, cmd, data, flag, p)
struct ppp_softc *sc;
+ u_long cmd;
caddr_t data;
- int cmd, flag;
+ int flag;
struct proc *p;
{
int s, error, flags, mru, nb, npx;
* a compressor or decompressor.
*/
error = 0;
- s = splnet();
if (odp->transmit) {
+ s = splnet();
if (sc->sc_xc_state != NULL)
(*sc->sc_xcomp->comp_free)(sc->sc_xc_state);
sc->sc_xcomp = *cp;
}
splimp();
sc->sc_flags &= ~SC_COMP_RUN;
+ splx(s);
} else {
+ s = splnet();
if (sc->sc_rc_state != NULL)
(*sc->sc_rcomp->decomp_free)(sc->sc_rc_state);
sc->sc_rcomp = *cp;
}
splimp();
sc->sc_flags &= ~SC_DECOMP_RUN;
+ splx(s);
}
- splx(s);
return (error);
}
if (sc->sc_flags & SC_DEBUG)
if (error = suser(p->p_ucred, &p->p_acflag))
return (error);
if (npi->mode != sc->sc_npmode[npx]) {
- s = splimp();
+ s = splnet();
sc->sc_npmode[npx] = npi->mode;
if (npi->mode != NPMODE_QUEUE) {
ppp_requeue(sc);
break;
case PPPIOCGIDLE:
- s = splimp();
+ s = splnet();
t = time.tv_sec;
((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
int
pppsioctl(ifp, cmd, data)
register struct ifnet *ifp;
- int cmd;
+ u_long cmd;
caddr_t data;
{
struct proc *p = curproc; /* XXX */
ifr->ifr_mtu = sc->sc_if.if_mtu;
break;
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ switch(ifr->ifr_addr.sa_family) {
+#ifdef INET
+ case AF_INET:
+ break;
+#endif
+ default:
+ error = EAFNOSUPPORT;
+ break;
+ }
+ break;
+
case SIOCGPPPSTATS:
psp = &((struct ifpppstatsreq *) data)->stats;
bzero(psp, sizeof(*psp));
/*
* Put the packet on the appropriate queue.
*/
- s = splimp(); /* splnet should be OK now */
+ s = splnet();
if (mode == NPMODE_QUEUE) {
/* XXX we should limit the number of packets on this queue */
*sc->sc_npqtail = m0;
sc->sc_npqtail = &m0->m_nextpkt;
} else {
ifq = (m0->m_flags & M_HIGHPRI)? &sc->sc_fastq: &ifp->if_snd;
- if (IF_QFULL(ifq)) {
+ if (IF_QFULL(ifq) && dst->sa_family != AF_UNSPEC) {
IF_DROP(ifq);
splx(s);
sc->sc_if.if_oerrors++;
/*
* After a change in the NPmode for some NP, move packets from the
* npqueue to the send queue or the fast queue as appropriate.
- * Should be called at splimp (actually splnet would probably suffice).
+ * Should be called at splnet.
*/
static void
ppp_requeue(sc)
}
/*
- * Get a packet to send. This procedure is intended to be called
- * at spltty()/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.
+ * 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.
*/
struct mbuf *
ppp_dequeue(sc)
&& (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head))
ppp_outpkt(sc);
for (;;) {
+ s = splimp();
IF_DEQUEUE(&sc->sc_rawq, m);
+ splx(s);
if (m == NULL)
break;
ppp_inproc(sc, m);
#ifdef PPP_COMPRESS
if (protocol != PPP_LCP && protocol != PPP_CCP
&& sc->sc_xc_state && (sc->sc_flags & SC_COMP_RUN)) {
- struct mbuf *mcomp;
+ struct mbuf *mcomp = NULL;
int slen, clen;
slen = 0;
--m->m_len;
}
- s = splimp();
sc->sc_togo = m;
(*sc->sc_start)(sc);
- splx(s);
}
#ifdef PPP_COMPRESS
if (sc->sc_xc_state != NULL
&& (*sc->sc_xcomp->comp_init)
(sc->sc_xc_state, dp + CCP_HDRLEN, slen - CCP_HDRLEN,
- sc->sc_if.if_unit, sc->sc_flags & SC_DEBUG)) {
+ sc->sc_if.if_unit, 0, sc->sc_flags & SC_DEBUG)) {
s = splimp();
sc->sc_flags |= SC_COMP_RUN;
splx(s);
/*
* Process a received PPP packet, doing decompression as necessary.
+ * Should be called at splnet.
*/
#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
TYPE_UNCOMPRESSED_TCP)
struct ifqueue *inq;
int s, ilen, xlen, proto, rv;
u_char *cp, adrs, ctrl;
- struct mbuf *mp, *dmp;
+ struct mbuf *mp, *dmp = NULL;
u_char *iphdr;
u_int hlen;
sc->sc_if.if_ipackets++;
if (sc->sc_flags & SC_LOG_INPKT) {
+ ilen = 0;
+ for (mp = m; mp != NULL; mp = mp->m_next)
+ ilen += mp->m_len;
printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen);
pppdumpm(m);
}
&& !(sc->sc_flags & SC_DC_ERROR) && !(sc->sc_flags & SC_DC_FERROR)) {
/* decompress this packet */
rv = (*sc->sc_rcomp->decompress)(sc->sc_rc_state, m, &dmp);
- if (dmp != NULL) {
+ if (rv == DECOMP_OK) {
m_freem(m);
+ if (dmp == NULL) {
+ /* no error, but no decompressed packet produced */
+ return;
+ }
m = dmp;
cp = mtod(m, u_char *);
proto = PPP_PROTOCOL(cp);
} else {
- /* pass the compressed packet up to pppd, which may take
- CCP down or issue a Reset-Req. */
+ /*
+ * An error has occurred in decompression.
+ * Pass the compressed packet up to pppd, which may take
+ * CCP down or issue a Reset-Req.
+ */
if (sc->sc_flags & SC_DEBUG)
printf("ppp%d: decompress failed %d\n", sc->sc_if.if_unit, rv);
s = splimp();
sc->sc_flags |= SC_VJ_RESET;
- switch (rv) {
- case DECOMP_OK:
- /* no error, but no decompressed packet produced */
- splx(s);
- m_freem(m);
- return;
- case DECOMP_ERROR:
+ if (rv == DECOMP_ERROR)
sc->sc_flags |= SC_DC_ERROR;
- break;
- case DECOMP_FATALERROR:
+ else
sc->sc_flags |= SC_DC_FERROR;
- break;
- }
splx(s);
}