X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=ultrix%2Fif_ppp.c;h=76725fea0d3e6e003218d602da3cb82ae708c60b;hp=981d1318129b7a26261d5f6e821dec0e53e2d6dc;hb=7a5ed5db7be1276d8625fc462fd36e728806a9e3;hpb=a471bdc20d7f993fc126b765c8c3dacbc902fa68 diff --git a/ultrix/if_ppp.c b/ultrix/if_ppp.c index 981d131..76725fe 100644 --- a/ultrix/if_ppp.c +++ b/ultrix/if_ppp.c @@ -72,7 +72,7 @@ * Robert Olsson and Paul Mackerras. */ -/* $Id: if_ppp.c,v 1.4 1994/12/08 00:32:59 paulus Exp $ */ +/* $Id: if_ppp.c,v 1.9 1995/10/27 03:59:42 paulus Exp $ */ /* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */ #include "ppp.h" @@ -120,8 +120,7 @@ #endif void pppattach __P((void)); -int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag, - struct proc *)); +int pppioctl __P((struct ppp_softc *sc, int cmd, caddr_t data, int flag)); int pppoutput __P((struct ifnet *ifp, struct mbuf *m0, struct sockaddr *dst)); int pppsioctl __P((struct ifnet *ifp, int cmd, caddr_t data)); @@ -169,7 +168,9 @@ static u_short interactive_ports[8] = { extern struct compressor ppp_bsd_compress; struct compressor *ppp_compressors[] = { +#if DO_BSD_COMPRESS &ppp_bsd_compress, +#endif NULL }; #endif /* PPP_COMPRESS */ @@ -237,6 +238,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; } @@ -273,7 +275,7 @@ pppdealloc(sc) m_freem(m); } while ((m = sc->sc_npqueue) != NULL) { - sc->sc_npqueue = m->m_nextpkt; + sc->sc_npqueue = m->m_act; m_freem(m); } if (sc->sc_togo != NULL) { @@ -297,11 +299,14 @@ pppioctl(sc, cmd, data, flag) int cmd, flag; { struct proc *p = u.u_procp; - int s, error, flags, mru, nb, npx; + int s, error, flags, mru, mtu, nb, npx; 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 +326,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); @@ -340,6 +347,27 @@ pppioctl(sc, cmd, data, flag) *(int *)data = sc->sc_mru; break; + /* + * PPPIOC[GS]MTU are implemented here, instead of supporting + * SIOC[GS]IFMTU in pppsioctl, because under Ultrix, we can't get an + * interface ioctl through to the interface until it has an IP + * address set. + */ + case PPPIOCSMTU: + if (!suser()) + return EPERM; + mtu = *(int *) data; + if (mtu <= 0 || mtu > PPP_MAXMRU) + return EINVAL; + s = splimp(); + sc->sc_if.if_mtu = mtu; + splx(s); + break; + + case PPPIOCGMTU: + *(int *) data = sc->sc_if.if_mtu; + break; + #ifdef VJC case PPPIOCSMAXCID: if (!suser()) @@ -375,8 +403,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; @@ -389,7 +417,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; @@ -402,8 +432,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) @@ -429,7 +459,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); @@ -440,6 +470,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); } @@ -460,7 +498,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) { @@ -479,6 +519,12 @@ pppsioctl(ifp, cmd, data) error = EAFNOSUPPORT; break; +/* + * Ioctls other than the above don't get through until the + * interface has its IP addresses set :-( + */ + +#if 0 case SIOCSIFMTU: if (!suser()) return EPERM; @@ -488,6 +534,7 @@ pppsioctl(ifp, cmd, data) case SIOCGIFMTU: ifr->ifr_mtu = sc->sc_if.if_mtu; break; +#endif case SIOCGPPPSTATS: psp = &((struct ifpppstatsreq *) data)->stats; @@ -566,7 +613,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. @@ -642,15 +689,15 @@ 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; - m0->m_nextpkt = NULL; - sc->sc_npqtail = &m0->m_nextpkt; + m0->m_act = NULL; + 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++; @@ -672,7 +719,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) @@ -696,9 +743,9 @@ ppp_requeue(sc) /* * This packet can now go on one of the queues to be sent. */ - *mpp = m->m_nextpkt; - m->m_nextpkt = NULL; - ifq = (m->m_flags & M_HIGHPRI)? &sc->sc_fastq: &sc->sc_if.if_snd; + *mpp = m->m_act; + m->m_act = NULL; + ifq = m->m_context? &sc->sc_fastq: &sc->sc_if.if_snd; if (IF_QFULL(ifq)) { IF_DROP(ifq); sc->sc_if.if_oerrors++; @@ -708,12 +755,12 @@ ppp_requeue(sc) case NPMODE_DROP: case NPMODE_ERROR: - *mpp = m->m_nextpkt; + *mpp = m->m_act; m_freem(m); break; case NPMODE_QUEUE: - mpp = &m->m_nextpkt; + mpp = &m->m_act; break; } } @@ -721,11 +768,11 @@ 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) @@ -754,7 +801,7 @@ ppp_dequeue(sc) } /* - * Software interrupt routine, called at splnet(). + * Software interrupt routine, called at splnet. */ void pppintr() @@ -770,7 +817,9 @@ pppintr() && (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); @@ -814,8 +863,13 @@ ppp_outpkt(sc) protocol = PPP_PROTOCOL(cp); switch (protocol) { -#ifdef VJC case PPP_IP: + /* + * Update the time we sent the most recent packet. + */ + sc->sc_last_sent = time.tv_sec; + +#ifdef VJC /* * If the packet is a TCP/IP packet, see if we can compress it. */ @@ -850,8 +904,8 @@ ppp_outpkt(sc) cp[3] = protocol; /* update protocol in PPP header */ } } - break; #endif /* VJC */ + break; #ifdef PPP_COMPRESS case PPP_CCP: @@ -901,10 +955,8 @@ ppp_outpkt(sc) --m->m_len; } - s = splimp(); sc->sc_togo = m; (*sc->sc_start)(sc); - splx(s); } #ifdef PPP_COMPRESS @@ -921,7 +973,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. @@ -968,7 +1019,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); @@ -1047,6 +1098,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) @@ -1056,7 +1108,7 @@ ppp_inproc(sc, m) struct ppp_softc *sc; struct mbuf *m; { - struct ifqueue *inq; + struct ifqueue *inq, *lock; int s, ilen, xlen, proto, rv; u_char *cp, adrs, ctrl; struct mbuf *mp, *dmp, *pc; @@ -1066,6 +1118,9 @@ ppp_inproc(sc, m) 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); } @@ -1090,32 +1145,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); - s = splimp(); + s = splhigh(); 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); } @@ -1257,6 +1310,7 @@ ppp_inproc(sc, m) m->m_len -= PPP_HDRLEN; schednetisr(NETISR_IP); inq = &ipintrq; + sc->sc_last_recv = time.tv_sec; /* update time of last pkt rcvd */ break; #endif @@ -1277,7 +1331,7 @@ 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);