Subject: Re: kern/30393: PF/ALTQ does not work on ppp(4) interfaces
To: None <gnats-bugs@netbsd.org, kern-bug-people@netbsd.org,>
From: Christos Zoulas <christos@zoulas.com>
List: netbsd-bugs
Date: 06/01/2005 18:14:54
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));
 }