X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=ultrix%2Fif_ppp.c;h=616a3841f532b52eed6e690cc3e2c795b2d74029;hp=9bfd22dae171a1b434662209e045d824ae85b4cf;hb=e5ad7e3dbf232955054ee90e54cebd6ee9533a85;hpb=a9bac5e43cdbbd044c71ed5bc7c6657d8f16f1ae diff --git a/ultrix/if_ppp.c b/ultrix/if_ppp.c index 9bfd22d..616a384 100644 --- a/ultrix/if_ppp.c +++ b/ultrix/if_ppp.c @@ -72,8 +72,9 @@ * Robert Olsson and Paul Mackerras. */ -/* $Id: if_ppp.c,v 1.5 1994/12/13 03:24:47 paulus Exp $ */ +/* $Id: if_ppp.c,v 1.11 1996/07/01 05:38:25 paulus Exp $ */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ +/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */ #include "ppp.h" #if NPPP > 0 @@ -89,6 +90,7 @@ #include "../h/socket.h" #include "../h/ioctl.h" #include "../h/systm.h" +#include "../h/time.h" #include "../net/net/if.h" #include "../net/net/netisr.h" @@ -105,13 +107,12 @@ #include "../machine/mtpr.h" #endif -#include "ppp_defs.h" -#include "if_ppp.h" - #ifdef VJC #include "slcompress.h" #endif +#include "ppp_defs.h" +#include "if_ppp.h" #include "if_pppvar.h" #ifdef PPP_COMPRESS @@ -119,17 +120,9 @@ #include "ppp-comp.h" #endif -void pppattach __P((void)); -int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag, - struct proc *)); -int pppoutput __P((struct ifnet *ifp, struct mbuf *m0, - struct sockaddr *dst)); -int pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data)); -void pppintr __P((void)); - static void ppp_requeue __P((struct ppp_softc *)); static void ppp_outpkt __P((struct ppp_softc *)); -static int ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd)); +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 *)); static void pppdumpm __P((struct mbuf *m0)); @@ -167,13 +160,20 @@ static u_short interactive_ports[8] = { */ extern struct compressor ppp_bsd_compress; +extern struct compressor ppp_deflate; struct compressor *ppp_compressors[] = { +#if DO_BSD_COMPRESS &ppp_bsd_compress, +#endif +#if DO_DEFLATE + &ppp_deflate, +#endif NULL }; #endif /* PPP_COMPRESS */ + /* * Called from boot code to establish ppp interfaces. */ @@ -189,6 +189,7 @@ pppattach() sc->sc_if.if_mtu = PPP_MTU; sc->sc_if.if_flags = IFF_POINTOPOINT; sc->sc_if.if_type = IFT_PPP; + sc->sc_if.if_hdrlen = PPP_HDRLEN; sc->sc_if.if_ioctl = pppsioctl; sc->sc_if.if_output = pppoutput; sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; @@ -226,8 +227,12 @@ pppalloc(pid) sc->sc_flags = 0; sc->sc_mru = PPP_MRU; sc->sc_relinq = NULL; + bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats)); #ifdef VJC - sl_compress_init(&sc->sc_comp); + KM_ALLOC(sc->sc_comp, struct slcompress *, sizeof(struct slcompress), + KM_DEVBUF, KM_NOARG); + if (sc->sc_comp) + sl_compress_init(sc->sc_comp, -1); #endif #ifdef PPP_COMPRESS sc->sc_xc_state = NULL; @@ -237,6 +242,7 @@ pppalloc(pid) sc->sc_npmode[i] = NPMODE_ERROR; sc->sc_npqueue = NULL; sc->sc_npqtail = &sc->sc_npqueue; + sc->sc_last_sent = sc->sc_last_recv = time.tv_sec; return sc; } @@ -285,6 +291,12 @@ pppdealloc(sc) sc->sc_xc_state = NULL; sc->sc_rc_state = NULL; #endif /* PPP_COMPRESS */ +#ifdef VJC + if (sc->sc_comp != 0) { + KM_FREE(sc->sc_comp, KM_DEVBUF); + sc->sc_comp = 0; + } +#endif } /* @@ -301,7 +313,10 @@ pppioctl(sc, cmd, data, flag) struct ppp_option_data *odp; struct compressor **cp; struct npioctl *npi; + time_t t; +#ifdef PPP_COMPRESS u_char ccp_option[CCP_MAX_OPTION_LENGTH]; +#endif switch (cmd) { case FIONREAD: @@ -321,8 +336,10 @@ pppioctl(sc, cmd, data, flag) return EPERM; flags = *(int *)data & SC_MASK; s = splnet(); +#ifdef PPP_COMPRESS if (sc->sc_flags & SC_CCP_OPEN && !(flags & SC_CCP_OPEN)) ppp_ccp_closed(sc); +#endif splimp(); sc->sc_flags = (sc->sc_flags & ~SC_MASK) | flags; splx(s); @@ -350,7 +367,7 @@ pppioctl(sc, cmd, data, flag) if (!suser()) return EPERM; mtu = *(int *) data; - if (mtu < PPP_MRU || mtu > PPP_MAXMRU) + if (mtu <= 0 || mtu > PPP_MAXMRU) return EINVAL; s = splimp(); sc->sc_if.if_mtu = mtu; @@ -365,9 +382,11 @@ pppioctl(sc, cmd, data, flag) case PPPIOCSMAXCID: if (!suser()) return EPERM; - s = splnet(); - sl_compress_setup(&sc->sc_comp, *(int *)data); - splx(s); + if (sc->sc_comp) { + s = splnet(); + sl_compress_init(sc->sc_comp, *(int *)data); + splx(s); + } break; #endif @@ -385,7 +404,7 @@ pppioctl(sc, cmd, data, flag) nb = odp->length; if (nb > sizeof(ccp_option)) nb = sizeof(ccp_option); - if (error = copyin(odp->ptr, ccp_option, nb)) + if ((error = copyin(odp->ptr, ccp_option, nb)) != 0) return (error); if (ccp_option[1] < 2) /* preliminary check on the length byte */ return (EINVAL); @@ -396,8 +415,8 @@ pppioctl(sc, cmd, data, flag) * 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; @@ -410,7 +429,9 @@ pppioctl(sc, cmd, data, flag) } 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; @@ -423,8 +444,8 @@ pppioctl(sc, cmd, data, flag) } splimp(); sc->sc_flags &= ~SC_DECOMP_RUN; + splx(s); } - splx(s); return (error); } if (sc->sc_flags & SC_DEBUG) @@ -450,7 +471,7 @@ pppioctl(sc, cmd, data, flag) if (!suser()) return EPERM; 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); @@ -461,6 +482,14 @@ pppioctl(sc, cmd, data, flag) } break; + case PPPIOCGIDLE: + 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; + splx(s); + break; + default: return (-1); } @@ -481,7 +510,9 @@ pppsioctl(ifp, cmd, data) register struct ifaddr *ifa = (struct ifaddr *)data; register struct ifreq *ifr = (struct ifreq *)data; struct ppp_stats *psp; +#ifdef PPP_COMPRESS struct ppp_comp_stats *pcp; +#endif int s = splimp(), error = 0; switch (cmd) { @@ -520,21 +551,18 @@ pppsioctl(ifp, cmd, data) case SIOCGPPPSTATS: psp = &((struct ifpppstatsreq *) data)->stats; bzero(psp, sizeof(*psp)); - psp->p.ppp_ibytes = sc->sc_bytesrcvd; - psp->p.ppp_ipackets = ifp->if_ipackets; - psp->p.ppp_ierrors = ifp->if_ierrors; - psp->p.ppp_obytes = sc->sc_bytessent; - psp->p.ppp_opackets = ifp->if_opackets; - psp->p.ppp_oerrors = ifp->if_oerrors; -#ifdef VJC - psp->vj.vjs_packets = sc->sc_comp.sls_packets; - psp->vj.vjs_compressed = sc->sc_comp.sls_compressed; - psp->vj.vjs_searches = sc->sc_comp.sls_searches; - psp->vj.vjs_misses = sc->sc_comp.sls_misses; - psp->vj.vjs_uncompressedin = sc->sc_comp.sls_uncompressedin; - psp->vj.vjs_compressedin = sc->sc_comp.sls_compressedin; - psp->vj.vjs_errorin = sc->sc_comp.sls_errorin; - psp->vj.vjs_tossed = sc->sc_comp.sls_tossed; + psp->p = sc->sc_stats; +#if defined(VJC) && !defined(SL_NO_STATS) + if (sc->sc_comp) { + psp->vj.vjs_packets = sc->sc_comp->sls_packets; + psp->vj.vjs_compressed = sc->sc_comp->sls_compressed; + psp->vj.vjs_searches = sc->sc_comp->sls_searches; + psp->vj.vjs_misses = sc->sc_comp->sls_misses; + psp->vj.vjs_uncompressedin = sc->sc_comp->sls_uncompressedin; + psp->vj.vjs_compressedin = sc->sc_comp->sls_compressedin; + psp->vj.vjs_errorin = sc->sc_comp->sls_errorin; + psp->vj.vjs_tossed = sc->sc_comp->sls_tossed; + } #endif /* VJC */ break; @@ -567,16 +595,17 @@ pppoutput(ifp, m0, dst) struct sockaddr *dst; { register struct ppp_softc *sc = &ppp_softc[ifp->if_unit]; - struct ppp_header *ph; int protocol, address, control; u_char *cp; int s, error; struct ip *ip; struct ifqueue *ifq; enum NPmode mode; + int len; + struct mbuf *m; if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0 - || (ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC) { + || ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) { error = ENETDOWN; /* sort of */ goto bad; } @@ -594,7 +623,7 @@ pppoutput(ifp, m0, dst) control = PPP_UI; protocol = PPP_IP; mode = sc->sc_npmode[NP_IP]; - + /* * If this is a TCP packet to or from an "interactive" port, * put the packet on the fastq instead. @@ -654,11 +683,22 @@ pppoutput(ifp, m0, dst) *cp++ = protocol & 0xff; m0->m_len += PPP_HDRLEN; + len = 0; + for (m = m0; m != 0; m = m->m_next) + len += m->m_len; + if (sc->sc_flags & SC_LOG_OUTPKT) { printf("ppp%d output: ", ifp->if_unit); pppdumpm(m0); } + if ((protocol & 0x8000) == 0) { + /* + * Update the time we sent the most recent data packet. + */ + sc->sc_last_sent = time.tv_sec; + } + #if NBPFILTER > 0 /* * See if bpf wants to look at the packet. @@ -670,7 +710,7 @@ pppoutput(ifp, m0, dst) /* * 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; @@ -678,16 +718,19 @@ pppoutput(ifp, m0, dst) sc->sc_npqtail = &m0->m_act; } else { ifq = m0->m_context? &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++; + sc->sc_stats.ppp_oerrors++; error = ENOBUFS; goto bad; } IF_ENQUEUE(ifq, m0); (*sc->sc_start)(sc); } + ifp->if_opackets++; + ifp->if_obytes += len; splx(s); return (0); @@ -700,7 +743,7 @@ bad: /* * 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) @@ -730,6 +773,7 @@ ppp_requeue(sc) if (IF_QFULL(ifq)) { IF_DROP(ifq); sc->sc_if.if_oerrors++; + sc->sc_stats.ppp_oerrors++; } else IF_ENQUEUE(ifq, m); break; @@ -749,78 +793,34 @@ 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. + * 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 = 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 splnet(). - */ -void -pppintr() -{ - struct ppp_softc *sc; - int i, s; - struct mbuf *m; - - s = splnet(); - 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 (;;) { - IF_DEQUEUE(&sc->sc_rawq, m); - if (m == NULL) - break; - ppp_inproc(sc, m); - } - } - splx(s); } /* - * Grab another packet off a queue and apply VJ compression, - * packet compression, address/control and/or protocol compression - * if enabled. Should be called at splnet. + * 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; { - int s; struct mbuf *m, *mp; u_char *cp; int address, control, protocol; - enum NPmode mode; + int s; /* * Grab a packet to send: first try the fast queue, then the @@ -830,7 +830,9 @@ ppp_outpkt(sc) if (m == NULL) IF_DEQUEUE(&sc->sc_if.if_snd, m); if (m == NULL) - return; + return NULL; + + ++sc->sc_stats.ppp_opackets; /* * Extract the ppp header of the new packet. @@ -842,12 +844,12 @@ ppp_outpkt(sc) protocol = PPP_PROTOCOL(cp); switch (protocol) { -#ifdef VJC 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) { + if ((sc->sc_flags & SC_COMP_TCP) && sc->sc_comp != NULL) { struct ip *ip; int type; @@ -861,7 +863,7 @@ ppp_outpkt(sc) } /* 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, + type = sl_compress_tcp(mp, ip, sc->sc_comp, !(sc->sc_flags & SC_NO_TCP_CCID)); switch (type) { case TYPE_UNCOMPRESSED_TCP: @@ -878,8 +880,8 @@ ppp_outpkt(sc) cp[3] = protocol; /* update protocol in PPP header */ } } - break; #endif /* VJC */ + break; #ifdef PPP_COMPRESS case PPP_CCP: @@ -891,7 +893,7 @@ ppp_outpkt(sc) #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; @@ -929,9 +931,38 @@ ppp_outpkt(sc) --m->m_len; } - s = splimp(); - sc->sc_togo = m; - (*sc->sc_start)(sc); + return m; +} + +/* + * 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); } @@ -940,7 +971,7 @@ ppp_outpkt(sc) * Handle a CCP packet. `rcvd' is 1 if the packet was received, * 0 if it is about to be transmitted. */ -static int +static void ppp_ccp(sc, m, rcvd) struct ppp_softc *sc; struct mbuf *m; @@ -949,7 +980,6 @@ ppp_ccp(sc, m, rcvd) u_char *dp, *ep; struct mbuf *mp; int slen, s; - struct bsd_db *db; /* * Get a pointer to the data after the PPP header. @@ -996,7 +1026,7 @@ ppp_ccp(sc, m, rcvd) 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); @@ -1075,6 +1105,7 @@ ppppktin(sc, m, lost) /* * 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) @@ -1084,17 +1115,21 @@ ppp_inproc(sc, m) struct ppp_softc *sc; struct mbuf *m; { + struct ifnet *ifp = &sc->sc_if; struct ifqueue *inq, *lock; int s, ilen, xlen, proto, rv; u_char *cp, adrs, ctrl; - struct mbuf *mp, *dmp, *pc; + struct mbuf *mp, *dmp = NULL, *pc; u_char *iphdr; u_int hlen; - sc->sc_if.if_ipackets++; + sc->sc_stats.ppp_ipackets++; if (sc->sc_flags & SC_LOG_INPKT) { - printf("ppp%d: got %d bytes\n", sc->sc_if.if_unit, ilen); + ilen = 0; + for (mp = m; mp != NULL; mp = mp->m_next) + ilen += mp->m_len; + printf("ppp%d: got %d bytes\n", ifp->if_unit, ilen); pppdumpm(m); } @@ -1118,32 +1153,30 @@ ppp_inproc(sc, 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); + printf("ppp%d: decompress failed %d\n", ifp->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); } @@ -1167,7 +1200,8 @@ ppp_inproc(sc, m) * If we've missed a packet, we must toss subsequent compressed * packets which don't have an explicit connection ID. */ - sl_uncompress_tcp(NULL, 0, TYPE_ERROR, &sc->sc_comp); + if (sc->sc_comp) + sl_uncompress_tcp(NULL, 0, TYPE_ERROR, sc->sc_comp); s = splimp(); sc->sc_flags &= ~SC_VJ_RESET; splx(s); @@ -1177,17 +1211,17 @@ ppp_inproc(sc, m) * See if we have a VJ-compressed packet to uncompress. */ if (proto == PPP_VJC_COMP) { - if (sc->sc_flags & SC_REJ_COMP_TCP) + if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0) goto bad; xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN, ilen - PPP_HDRLEN, TYPE_COMPRESSED_TCP, - &sc->sc_comp, &iphdr, &hlen); + sc->sc_comp, &iphdr, &hlen); if (xlen <= 0) { if (sc->sc_flags & SC_DEBUG) printf("ppp%d: VJ uncompress failed on type comp\n", - sc->sc_if.if_unit); + ifp->if_unit); goto bad; } @@ -1229,17 +1263,17 @@ ppp_inproc(sc, m) ilen += hlen - xlen; } else if (proto == PPP_VJC_UNCOMP) { - if (sc->sc_flags & SC_REJ_COMP_TCP) + if ((sc->sc_flags & SC_REJ_COMP_TCP) || sc->sc_comp == 0) goto bad; xlen = sl_uncompress_tcp_core(cp + PPP_HDRLEN, m->m_len - PPP_HDRLEN, ilen - PPP_HDRLEN, TYPE_UNCOMPRESSED_TCP, - &sc->sc_comp, &iphdr, &hlen); + sc->sc_comp, &iphdr, &hlen); if (xlen < 0) { if (sc->sc_flags & SC_DEBUG) printf("ppp%d: VJ uncompress failed on type uncomp\n", - sc->sc_if.if_unit); + ifp->if_unit); goto bad; } @@ -1262,6 +1296,13 @@ ppp_inproc(sc, m) } } + /* + * Record the time that we received this packet. + */ + if ((proto & 0x8000) == 0) { + sc->sc_last_recv = time.tv_sec; + } + #if NBPFILTER > 0 /* See if bpf wants to look at the packet. */ if (sc->sc_bpf) @@ -1275,7 +1316,7 @@ ppp_inproc(sc, m) /* * IP packet - take off the ppp header and pass it up to IP. */ - if ((sc->sc_if.if_flags & IFF_UP) == 0 + if ((ifp->if_flags & IFF_UP) == 0 || sc->sc_npmode[NP_IP] != NPMODE_PASS) { /* interface is down - drop the packet. */ m_freem(m); @@ -1305,15 +1346,17 @@ ppp_inproc(sc, m) smp_lock(&lock->lk_ifqueue, LK_RETRY); if (IF_QFULL(inq)) { IF_DROP(inq); - /* XXX should we unlock here? */ + smp_unlock(&lock->lk_ifqueue); splx(s); if (sc->sc_flags & SC_DEBUG) - printf("ppp%d: input queue full\n", sc->sc_if.if_unit); + printf("ppp%d: input queue full\n", ifp->if_unit); goto bad; } IF_ENQUEUEIF(inq, m, &sc->sc_if); smp_unlock(&lock->lk_ifqueue); splx(s); + ifp->if_ipackets++; + ifp->if_ibytes += ilen; if (rv) (*sc->sc_ctlp)(sc); @@ -1323,6 +1366,7 @@ ppp_inproc(sc, m) bad: m_freem(m); sc->sc_if.if_ierrors++; + sc->sc_stats.ppp_ierrors++; } #define MAX_DUMP_BYTES 128