Subject: Re: kern/30393: PF/ALTQ does not work on ppp(4) interfaces
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Christos Zoulas <christos@zoulas.com>
List: netbsd-bugs
Date: 06/01/2005 22:16:01
The following reply was made to PR kern/30393; it has been noted by GNATS.

From: christos@zoulas.com (Christos Zoulas)
To: gnats-bugs@netbsd.org, kern-bug-people@netbsd.org,
	gnats-admin@netbsd.org, netbsd-bugs@netbsd.org
Cc: 
Subject: Re: kern/30393: PF/ALTQ does not work on ppp(4) interfaces
Date: Wed, 1 Jun 2005 18:14:54 -0400

 On Jun 1,  9:38pm, carton@Ivy.NET (carton@Ivy.NET) wrote:
 -- Subject: kern/30393: PF/ALTQ does not work on ppp(4) interfaces
 
 Does this diff work for you?
 
 christos
 
 Index: ppp_tty.c
 ===================================================================
 RCS file: /cvsroot/src/sys/net/ppp_tty.c,v
 retrieving revision 1.37
 diff -u -u -r1.37 ppp_tty.c
 --- ppp_tty.c	29 May 2005 21:22:53 -0000	1.37
 +++ ppp_tty.c	1 Jun 2005 22:13:47 -0000
 @@ -373,7 +373,7 @@
      int flag;
  {
      struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
 -    struct mbuf *m, *m0, **mp;
 +    struct mbuf *m, *m0;
      struct sockaddr dst;
      int len, error;
  
 @@ -386,15 +386,19 @@
      if (uio->uio_resid > sc->sc_if.if_mtu + PPP_HDRLEN ||
  	uio->uio_resid < PPP_HDRLEN)
  	return (EMSGSIZE);
 -    for (mp = &m0; uio->uio_resid; mp = &m->m_next) {
 -	m = m_get(M_WAIT, MT_DATA);
 -	if ((*mp = m) == NULL) {
 -	    m_freem(m0);
 -	    return (ENOBUFS);
 -	}
 -	m->m_len = 0;
 -	if (uio->uio_resid >= MCLBYTES / 2)
 -	    MCLGET(m, M_DONTWAIT);
 +
 +    MGETHDR(m0, M_WAIT, MT_DATA);
 +    if (m0 == NULL)
 +	return ENOBUFS;
 +
 +    m0->m_len = 0;
 +    m0->m_pkthdr.len = uio->uio_resid;
 +    m0->m_pkthdr.rcvif = NULL;
 +
 +    if (uio->uio_resid >= MCLBYTES / 2)
 +	MCLGET(m0, M_DONTWAIT);
 +
 +    for (m = m0; uio->uio_resid;) {
  	len = M_TRAILINGSPACE(m);
  	if (len > uio->uio_resid)
  	    len = uio->uio_resid;
 @@ -403,11 +407,21 @@
  	    return (error);
  	}
  	m->m_len = len;
 +
 +	if (uio->uio_resid == 0)
 +	    break;
 +
 +	MGET(m->m_next, M_WAIT, MT_DATA);
 +	if (m->m_next == NULL) {
 +	    m_freem(m0);
 +	    return ENOBUFS;
 +	}
 +	m = m->m_next;
 +	m->m_len = 0;
      }
      dst.sa_family = AF_UNSPEC;
      bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
 -    m0->m_data += PPP_HDRLEN;
 -    m0->m_len -= PPP_HDRLEN;
 +    m_adj(m0, PPP_HDRLEN);
      return ((*sc->sc_if.if_output)(&sc->sc_if, m0, &dst, (struct rtentry *)0));
  }