diff options
Diffstat (limited to '')
-rw-r--r-- | c/src/exec/libnetworking/net/if_ppp.c (renamed from c/src/libnetworking/modem/ppp.c) | 477 |
1 files changed, 343 insertions, 134 deletions
diff --git a/c/src/libnetworking/modem/ppp.c b/c/src/exec/libnetworking/net/if_ppp.c index 4ccecc85c1..8c8b58745d 100644 --- a/c/src/libnetworking/modem/ppp.c +++ b/c/src/exec/libnetworking/net/if_ppp.c @@ -75,10 +75,10 @@ #include "ppp.h" #if NPPP > 0 -/* temporarily we switch off the compression */ - -#include <rtems/rtems_bsdnet.h> /* to get right defines */ +#include <termios.h> +#include <rtems/termiostypes.h> +#include <rtems/rtems_bsdnet.h> #include <sys/param.h> #include <sys/systm.h> #include <sys/proc.h> @@ -89,9 +89,7 @@ #include <sys/time.h> #include <sys/malloc.h> -#include <rtems/rtems_bsdnet.h> #include <net/if.h> -#include <sys/errno.h> #include <net/if_types.h> #include <net/netisr.h> #include <net/route.h> @@ -99,14 +97,14 @@ #include <net/bpf.h> #endif -#ifdef INET +#if INET #include <netinet/in.h> #include <netinet/in_systm.h> #include <netinet/in_var.h> #include <netinet/ip.h> #endif -#include <bpfilter.h> +#include "bpfilter.h" #if NBPFILTER > 0 #include <net/bpf.h> #endif @@ -122,23 +120,18 @@ #define splsoftnet splnet -#ifndef NETISR_PPP -/* This definition should be moved to net/netisr.h */ -#define NETISR_PPP 26 /* PPP software interrupt */ -#endif - #ifdef PPP_COMPRESS #define PACKETPTR struct mbuf * #include <net/ppp-comp.h> #endif -extern struct ifqueue ipintrq; + static int pppsioctl __P((struct ifnet *, int, caddr_t)); static void ppp_requeue __P((struct ppp_softc *)); #ifdef PPP_COMPRESS static void ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd)); static void ppp_ccp_closed __P((struct ppp_softc *)); #endif -static void ppp_inproc __P((struct ppp_softc *, struct mbuf *)); +static struct mbuf *ppp_inproc __P((struct ppp_softc *, struct mbuf *)); static void pppdumpm __P((struct mbuf *m0)); /* @@ -171,7 +164,6 @@ static void pppdumpm __P((struct mbuf *m0)); extern struct compressor ppp_bsd_compress; extern struct compressor ppp_deflate, ppp_deflate_draft; - struct compressor *ppp_compressors[8] = { #if DO_BSD_COMPRESS &ppp_bsd_compress, @@ -183,20 +175,250 @@ struct compressor *ppp_compressors[8] = { NULL }; #endif /* PPP_COMPRESS */ -static struct timeval ppp_time; -TEXT_SET(pseudo_set, pppattach); +extern struct ifqueue ipintrq; +static struct timeval ppp_time; + +TEXT_SET(pseudo_set, ppp_rxdaemon); + + +static rtems_task ppp_rxdaemon(rtems_task_argument arg) +{ + rtems_event_set events; + rtems_interrupt_level level; + struct ppp_softc *sc = (struct ppp_softc *)arg; + struct mbuf *mp = (struct mbuf *)0; + struct mbuf *m; + + /* enter processing loop */ + while ( 1 ) { + /* wait for event */ + rtems_event_receive(RX_PACKET|RX_MBUF|RX_EMPTY,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events); + if ( events & RX_EMPTY ) { + printf("RX: QUEUE is EMPTY\n"); + events &= ~RX_EMPTY; + } + + if ( events ) { + /* get the network semaphore */ + rtems_bsdnet_semaphore_obtain(); + + /* check to see if new packet was received */ + if ( events & RX_PACKET ) { + /* get received packet mbuf chain */ + rtems_interrupt_disable(level); + IF_DEQUEUE(&sc->sc_rawq, m); + rtems_interrupt_enable(level); + + /* ensure packet was retrieved */ + if ( m != (struct mbuf *)0 ) { + /* process the received packet */ + mp = ppp_inproc(sc, m); + } + } + + /* allocate a new mbuf to replace one */ + if ( mp == NULL ) { + pppallocmbuf(sc, &mp); + } + + /* place mbuf on freeq */ + rtems_interrupt_disable(level); + IF_ENQUEUE(&sc->sc_freeq, mp); + rtems_interrupt_enable(level); + mp = (struct mbuf *)0; + + /* release the network semaphore */ + rtems_bsdnet_semaphore_release(); + + /* check to see if queue is empty */ + if ( sc->sc_rawq.ifq_head ) { + /* queue is not empty - post another event */ + rtems_event_send(sc->sc_rxtask, RX_PACKET); + } + } + } +} + +static rtems_task ppp_txdaemon(rtems_task_argument arg) +{ + rtems_event_set events; + char cFrame = (char )PPP_FLAG; + int iprocess = (int )0; + struct ppp_softc *sc = (struct ppp_softc *)arg; + struct mbuf *mp; + struct mbuf *mf; + struct mbuf *m; + struct rtems_termios_tty *tp; + + /* enter processing loop */ + while ( 1 ) { + /* wait for event */ + rtems_event_receive(TX_PACKET|TX_TRANSMIT,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events); + if ( events & TX_TRANSMIT ) { + /* received event from interrupt handler - free current mbuf */ + rtems_bsdnet_semaphore_obtain(); + m_freem(sc->sc_outm); + rtems_bsdnet_semaphore_release(); + + /* chain is done - clear the values */ + sc->sc_outm = (struct mbuf *)0; + sc->sc_outmc = (struct mbuf *)0; + + /* now set flag to fake receive of TX_PACKET event */ + /* this will check to see if we have any pending packets */ + events |= TX_PACKET; + } + + /* received event from pppasyncstart */ + if ( events & TX_PACKET ) { + /* ensure we are not busy */ + if ( sc->sc_outm == (struct mbuf *)0 ) { + /* try dequeuing a packet */ + sc->sc_outm = ppp_dequeue(sc); + if ( sc->sc_outm == NULL ) { + /* clear output flags */ + sc->sc_outflag = 0; + sc->sc_if.if_flags &= ~IFF_OACTIVE; + } + else { + /* set flag to start process */ + iprocess = 1; + sc->sc_outflag = SC_TX_BUSY; + sc->sc_if.if_flags |= IFF_OACTIVE; + } + } + } + + /* check to see if there is any processing required */ + if ( iprocess ) { + /* clear process flag */ + iprocess = (int)0; + + /* initialize output values */ + sc->sc_outfcs = PPP_INITFCS; + sc->sc_outbuf = (u_char *)0; + sc->sc_outlen = (short )0; + sc->sc_outoff = (short )0; + sc->sc_outfcslen = (short )0; + + /* loop over all mbufs in chain */ + mf = NULL; + mp = NULL; + m = sc->sc_outm; + while (( m != (struct mbuf *)0 ) && ( m->m_len > 0 )) { + /* check to see if first mbuf value has been set */ + if ( sc->sc_outmc == (struct mbuf *)0 ) { + /* set values to start with this mbuf */ + sc->sc_outmc = m; + sc->sc_outlen = m->m_len; + sc->sc_outbuf = mtod(m, u_char *); + } + + /* update the FCS value and then check next packet length */ + sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len); + + /* check next packet to see if it is empty */ + while (( m->m_next != NULL ) && ( m->m_next->m_len == 0 )) { + /* next mbuf is zero length */ + /* add empty mbuf to free chain */ + if ( mp == NULL ) { + /* item is head of free list */ + mf = m->m_next; + mp = mf; + } + else { + /* add item to end of the free list */ + mp->m_next = m->m_next; + mp = m->m_next; + } + + /* remove empty item from process chain */ + m->m_next = m->m_next->m_next; + mp->m_next = NULL; + } + + /* move to next packet */ + m = m->m_next; + } + + /* ensure there is data to be sent out */ + tp = (struct rtems_termios_tty *)sc->sc_devp; + if (( tp != NULL ) && ( sc->sc_outmc != (struct mbuf *)0 )) { + /* place FCS value into buffer */ + sc->sc_outfcsbuf[sc->sc_outfcslen++] = ~sc->sc_outfcs & 0xff; + sc->sc_outfcsbuf[sc->sc_outfcslen++] = (~sc->sc_outfcs >> 8) & 0xff; + microtime(&sc->sc_if.if_lastchange); + + /* write out frame byte to start the transmission */ + (*tp->device.write)(tp->minor, &cFrame, 1); + } + + /* check to see if we need to free some empty mbufs */ + if ( mf != (struct mbuf *)0 ) { + /* free empty mbufs */ + rtems_bsdnet_semaphore_obtain(); + m_freem(mf); + rtems_bsdnet_semaphore_release(); + } + } + } +} + +static void ppp_init(struct ppp_softc *sc) +{ + rtems_status_code status; + rtems_unsigned32 priority = 100; + + /* determine priority value */ + if ( rtems_bsdnet_config.network_task_priority ) { + priority = rtems_bsdnet_config.network_task_priority; + } + + /* check to see if we need to start up daemons */ + if ( sc->sc_rxtask == 0 ) { + /* start rx daemon task */ + status = rtems_task_create(rtems_build_name('R','x','P','0'), priority, 2048, + RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), + RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, + &sc->sc_rxtask); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + else { + status = rtems_task_start(sc->sc_rxtask, ppp_rxdaemon, (rtems_task_argument)sc); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + + /* start tx daemon task */ + status = rtems_task_create(rtems_build_name('T','x','P','0'), priority, 2048, + RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0), + RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL, + &sc->sc_txtask); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + else { + status = rtems_task_start(sc->sc_txtask, ppp_txdaemon, (rtems_task_argument)sc); + if (status != RTEMS_SUCCESSFUL) { + rtems_fatal_error_occurred(status); + } + } + } + + /* mark driver running and output inactive */ + sc->sc_if.if_flags |= IFF_RUNNING; +} /* * Called from boot code to establish ppp interfaces. */ -int rtems_ppp_driver_attach (struct rtems_bsdnet_ifconfig *config, - int attaching) +int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching) { - register struct ppp_softc *sc; - register int i = 0; -/* XXX unused in rtems - extern void (*netisrs[])__P((void)); */ + int i = (int)0; + struct ppp_softc *sc; for (sc = ppp_softc; i < NPPP; sc++) { sc->sc_if.if_name = "ppp"; @@ -211,14 +433,17 @@ int rtems_ppp_driver_attach (struct rtems_bsdnet_ifconfig *config, sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN; + sc->sc_freeq.ifq_maxlen = NUM_MBUFQ; + + /* initialize and attach */ + ppp_init(sc); if_attach(&sc->sc_if); #if NBPFILTER > 0 bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN); #endif } -/* hardcoded in rtems_glue.c - netisrs[NETISR_PPP] = pppintr; */ - return 1; + + return ( 1 ); } /* @@ -230,6 +455,7 @@ pppalloc(pid) { int nppp, i; struct ppp_softc *sc; + for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++) if (sc->sc_xfer == pid) { sc->sc_xfer = 0; @@ -246,7 +472,8 @@ pppalloc(pid) sc->sc_relinq = NULL; bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats)); #ifdef VJC - sc->sc_comp=malloc(sizeof(struct vjcompress),M_DEVBUF, M_NOWAIT); + MALLOC(sc->sc_comp, struct vjcompress *, sizeof(struct vjcompress), + M_DEVBUF, M_NOWAIT); if (sc->sc_comp) vj_compress_init(sc->sc_comp, -1); #endif @@ -258,7 +485,7 @@ pppalloc(pid) sc->sc_npmode[i] = NPMODE_ERROR; sc->sc_npqueue = NULL; sc->sc_npqtail = &sc->sc_npqueue; - microtime(&ppp_time); + microtime(&ppp_time); sc->sc_last_sent = sc->sc_last_recv = ppp_time.tv_sec; return sc; @@ -272,17 +499,38 @@ pppdealloc(sc) struct ppp_softc *sc; { struct mbuf *m; + rtems_interrupt_level level; if_down(&sc->sc_if); sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); sc->sc_devp = NULL; sc->sc_xfer = 0; - for (;;) { - IF_DEQUEUE(&sc->sc_rawq, m); - if (m == NULL) - break; - m_freem(m); + + rtems_interrupt_disable(level); + if ( sc->sc_m != NULL ) { + m_freem(sc->sc_m); + sc->sc_m = (struct mbuf *)0; + } + if ( sc->sc_outm != NULL ) { + m_freem(sc->sc_outm); + sc->sc_outm = (struct mbuf *)0; + sc->sc_outmc = (struct mbuf *)0; + sc->sc_outflag = 0; } + do { + IF_DEQUEUE(&sc->sc_freeq, m); + if (m != NULL) { + m_freem(m); + } + } while ( m != NULL ); + do { + IF_DEQUEUE(&sc->sc_rawq, m); + if (m != NULL) { + m_freem(m); + } + } while ( m != NULL ); + rtems_interrupt_enable(level); + for (;;) { IF_DEQUEUE(&sc->sc_inq, m); if (m == NULL) @@ -299,10 +547,6 @@ pppdealloc(sc) sc->sc_npqueue = m->m_nextpkt; m_freem(m); } - if (sc->sc_togo != NULL) { - m_freem(sc->sc_togo); - sc->sc_togo = NULL; - } #ifdef PPP_COMPRESS ppp_ccp_closed(sc); sc->sc_xc_state = NULL; @@ -310,19 +554,19 @@ pppdealloc(sc) #endif /* PPP_COMPRESS */ #ifdef PPP_FILTER if (sc->sc_pass_filt.bf_insns != 0) { - free(sc->sc_pass_filt.bf_insns, M_DEVBUF); + FREE(sc->sc_pass_filt.bf_insns, M_DEVBUF); sc->sc_pass_filt.bf_insns = 0; sc->sc_pass_filt.bf_len = 0; } if (sc->sc_active_filt.bf_insns != 0) { - free(sc->sc_active_filt.bf_insns, M_DEVBUF); + FREE(sc->sc_active_filt.bf_insns, M_DEVBUF); sc->sc_active_filt.bf_insns = 0; sc->sc_active_filt.bf_len = 0; } #endif /* PPP_FILTER */ #ifdef VJC if (sc->sc_comp != 0) { - free(sc->sc_comp, M_DEVBUF); + FREE(sc->sc_comp, M_DEVBUF); sc->sc_comp = 0; } #endif @@ -339,7 +583,7 @@ pppioctl(sc, cmd, data, flag, p) int flag; struct proc *p; { - int s, flags, mru, npx; + int s, flags, mru, npx, taskid; struct npioctl *npi; time_t t; #ifdef PPP_FILTER @@ -360,6 +604,11 @@ pppioctl(sc, cmd, data, flag, p) *(int *)data = sc->sc_inq.ifq_len; break; + case PPPIOCSTASK: + taskid = *(int *)data; + sc->sc_pppdtask = taskid; + break; + case PPPIOCGUNIT: *(int *)data = sc->sc_if.if_unit; break; @@ -382,8 +631,17 @@ pppioctl(sc, cmd, data, flag, p) case PPPIOCSMRU: mru = *(int *)data; - if (mru >= PPP_MRU && mru <= PPP_MAXMRU) - sc->sc_mru = mru; + if ( mru >= MCLBYTES ) { + /* error - currently only handle 1 culster sized MRU */ + /* if we want to handle up to PPP_MAXMRU then we */ + /* need to reallocate all mbufs on the freeq */ + /* this can only be done with iterrupts disabled */ + return ( -1 ); + } + else if ( mru >= PPP_MRU ) { + /* update the size */ + sc->sc_mru = mru; + } break; case PPPIOCGMRU: @@ -488,7 +746,7 @@ pppioctl(sc, cmd, data, flag, p) case PPPIOCGIDLE: s = splsoftnet(); - microtime(&ppp_time); + microtime(&ppp_time); t = ppp_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; @@ -503,17 +761,17 @@ pppioctl(sc, cmd, data, flag, p) return EINVAL; newcodelen = nbp->bf_len * sizeof(struct bpf_insn); if (newcodelen != 0) { - newcode=(struct bpf_insn *) malloc (newcodelen, M_DEVBUF, M_WAITOK); + MALLOC(newcode, struct bpf_insn *, newcodelen, M_DEVBUF, M_WAITOK); if (newcode == 0) { return EINVAL; /* or sumpin */ } if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode, newcodelen)) != 0) { - free(newcode, M_DEVBUF); + FREE(newcode, M_DEVBUF); return error; } if (!bpf_validate(newcode, nbp->bf_len)) { - free(newcode, M_DEVBUF); + FREE(newcode, M_DEVBUF); return EINVAL; } } else @@ -525,7 +783,7 @@ pppioctl(sc, cmd, data, flag, p) bp->bf_insns = newcode; splx(s); if (oldcode != 0) - free(oldcode, M_DEVBUF); + FREE(oldcode, M_DEVBUF); break; #endif @@ -544,7 +802,7 @@ pppsioctl(ifp, cmd, data) int cmd; caddr_t data; { -/* struct proc *p = curproc; *//* XXX */ + /*struct proc *p = curproc;*/ /* XXX */ register struct ppp_softc *sc = &ppp_softc[ifp->if_unit]; register struct ifaddr *ifa = (struct ifaddr *)data; register struct ifreq *ifr = (struct ifreq *)data; @@ -594,17 +852,16 @@ pppsioctl(ifp, cmd, data) break; } break; - case SIO_RTEMS_SHOW_STATS: - printf (" MRU:%-8lu", sc->sc_mru); - printf (" Bytes received:%-8lu", sc->sc_stats.ppp_ibytes); - printf (" Packets received:%-8lu", sc->sc_stats.ppp_ipackets); - printf (" Receive errors:%-8lu\n", sc->sc_stats.ppp_ierrors); - printf (" Bytes sent:%-8lu", sc->sc_stats.ppp_obytes); - printf (" Packets sent:%-8lu", sc->sc_stats.ppp_opackets); - printf (" Transmit errors:%-8lu\n", sc->sc_stats.ppp_oerrors); - + + case SIO_RTEMS_SHOW_STATS: + printf(" MRU:%-8u", sc->sc_mru); + printf(" Bytes received:%-8u", sc->sc_stats.ppp_ibytes); + printf(" Packets received:%-8u", sc->sc_stats.ppp_ipackets); + printf(" Receive errors:%-8u\n", sc->sc_stats.ppp_ierrors); + printf(" Bytes sent:%-8u", sc->sc_stats.ppp_obytes); + printf(" Packets sent:%-8u", sc->sc_stats.ppp_opackets); + printf(" Transmit errors:%-8u\n", sc->sc_stats.ppp_oerrors); break; - case SIOCGPPPSTATS: psp = &((struct ifpppstatsreq *) data)->stats; @@ -662,6 +919,7 @@ pppoutput(ifp, m0, dst, rtp) 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)) { error = ENETDOWN; /* sort of */ @@ -762,17 +1020,14 @@ pppoutput(ifp, m0, dst, rtp) */ if (sc->sc_active_filt.bf_insns == 0 || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m0, len, 0)) - { - microtime(&ppp_time); - sc->sc_last_sent = ppp_time.tv_sec; - } + sc->sc_last_sent = time.tv_sec; *mtod(m0, u_char *) = address; #else /* * Update the time we sent the most recent data packet. */ - microtime(&ppp_time); + microtime(&ppp_time); sc->sc_last_sent = ppp_time.tv_sec; #endif /* PPP_FILTER */ } @@ -788,6 +1043,7 @@ pppoutput(ifp, m0, dst, rtp) /* * Put the packet on the appropriate queue. */ + s = splsoftnet(); if (mode == NPMODE_QUEUE) { /* XXX we should limit the number of packets on this queue */ *sc->sc_npqtail = m0; @@ -806,11 +1062,11 @@ pppoutput(ifp, m0, dst, rtp) IF_ENQUEUE(ifq, m0); (*sc->sc_start)(sc); } - microtime(&ppp_time); ifp->if_lastchange = ppp_time; ifp->if_opackets++; ifp->if_obytes += len; + splx(s); return (0); bad: @@ -871,19 +1127,6 @@ ppp_requeue(sc) } /* - * Transmitter has finished outputting some stuff; - * remember to call sc->sc_start later at splsoftnet. - */ -void -ppp_restart(sc) - struct ppp_softc *sc; -{ - - sc->sc_flags &= ~SC_TBUSY; -/* schednetisr(NETISR_PPP); -*/} - -/* * 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 @@ -901,9 +1144,12 @@ ppp_dequeue(sc) * Grab a packet to send: first try the fast queue, then the * normal queue. */ + rtems_bsdnet_semaphore_obtain(); IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) IF_DEQUEUE(&sc->sc_if.if_snd, m); + rtems_bsdnet_semaphore_release(); + if (m == NULL) return NULL; @@ -1018,28 +1264,8 @@ ppp_dequeue(sc) * Software interrupt routine, called at splsoftnet. */ void -pppintr() +pppintr(void) { - struct ppp_softc *sc; - int i, s2; - struct mbuf *m; - - sc = ppp_softc; - 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 (;;) { - IF_DEQUEUE(&sc->sc_rawq, m); - if (m == NULL) - break; - ppp_inproc(sc, m); - } - } } #ifdef PPP_COMPRESS @@ -1160,43 +1386,25 @@ ppp_ccp_closed(sc) #endif /* PPP_COMPRESS */ /* - * PPP packet input routine. - * The caller has checked and removed the FCS and has inserted - * the address/control bytes and the protocol high byte if they - * were omitted. - */ -void -ppppktin(sc, m, lost) - struct ppp_softc *sc; - struct mbuf *m; - int lost; -{ - - if (lost) - m->m_flags |= M_ERRMARK; - IF_ENQUEUE(&sc->sc_rawq, m); - pppintr(); -} - -/* * Process a received PPP packet, doing decompression as necessary. * Should be called at splsoftnet. */ #define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \ TYPE_UNCOMPRESSED_TCP) -static void +static struct mbuf * ppp_inproc(sc, m) struct ppp_softc *sc; struct mbuf *m; { + struct mbuf *mf = (struct mbuf *)0; struct ifnet *ifp = &sc->sc_if; struct ifqueue *inq; - int s, ilen, xlen, proto, rv; + int s, ilen, xlen, proto, rv; u_char *cp, adrs, ctrl; struct mbuf *mp; #ifdef PPP_COMPRESS - *dmp = NULL; + struct mbuf *dmp = NULL; #endif u_char *iphdr; u_int hlen; @@ -1236,7 +1444,7 @@ ppp_inproc(sc, m) m_freem(m); if (dmp == NULL) { /* no error, but no decompressed packet produced */ - return; + return mf; } m = dmp; cp = mtod(m, u_char *); @@ -1369,7 +1577,9 @@ ppp_inproc(sc, m) MGETHDR(mp, M_DONTWAIT, MT_DATA); if (mp != NULL) { m_copydata(m, 0, ilen, mtod(mp, caddr_t)); - m_freem(m); + /* instead of freeing - return cluster mbuf so it can be reused */ + /* m_freem(m); */ + mf = m; m = mp; m->m_len = ilen; } @@ -1390,15 +1600,11 @@ ppp_inproc(sc, m) ilen, 0) == 0) { /* drop this packet */ m_freem(m); - return; + return mf; } if (sc->sc_active_filt.bf_insns == 0 || bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m, ilen, 0)) - { - microtime(&ppp_time); - - sc->sc_last_recv = ppp_time.tv_sec; - } + sc->sc_last_recv = time.tv_sec; *mtod(m, u_char *) = adrs; #else @@ -1427,7 +1633,7 @@ ppp_inproc(sc, m) || sc->sc_npmode[NP_IP] != NPMODE_PASS) { /* interface is down - drop the packet. */ m_freem(m); - return; + return mf; } m->m_pkthdr.len -= PPP_HDRLEN; m->m_data += PPP_HDRLEN; @@ -1460,20 +1666,23 @@ ppp_inproc(sc, m) } IF_ENQUEUE(inq, m); splx(s); + ifp->if_ipackets++; ifp->if_ibytes += ilen; - microtime(&ppp_time); + microtime(&ppp_time); ifp->if_lastchange = ppp_time; - if (rv) - (*sc->sc_ctlp)(sc); + if (rv) { + (*sc->sc_ctlp)(sc); + } - return; + return mf; bad: m_freem(m); sc->sc_if.if_ierrors++; sc->sc_stats.ppp_ierrors++; + return mf; } #define MAX_DUMP_BYTES 128 |