Subject: pppoe & mbuf chain
To: None <martin@netbsd.org>
From: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
List: tech-net
Date: 06/21/2002 23:54:41
----Next_Part(Fri_Jun_21_23:54:42_2002_961)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
in-kernel pppoe have an assumption that
input packets are a single mbuf.
(ie. no mbuf chain)
attached diff will fix it.
---
YAMAMOTO Takashi<yamt@mwd.biglobe.ne.jp>
----Next_Part(Fri_Jun_21_23:54:42_2002_961)--
Content-Type: Text/Plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="pppoe.diff"
Index: if_pppoe.c
===================================================================
RCS file: /cvs/cvsroot/syssrc/sys/net/if_pppoe.c,v
retrieving revision 1.24
diff -u -p -r1.24 if_pppoe.c
--- if_pppoe.c 2002/04/14 12:24:28 1.24
+++ if_pppoe.c 2002/06/21 14:43:43
@@ -523,13 +523,21 @@ pppoe_disc_input(struct mbuf *m)
/* avoid error messages if there is not a single pppoe instance */
if (!LIST_EMPTY(&pppoe_softc_list)) {
+ KASSERT(m->m_flags & M_PKTHDR);
eh = mtod(m, struct ether_header*);
m_adj(m, sizeof(struct ether_header));
+ /* should be in a single mbuf */
+ if (m->m_next != NULL) {
+ m = m_pullup(m, m->m_len);
+ if (m == NULL)
+ goto drop;
+ }
p = mtod(m, u_int8_t*);
- KASSERT(m->m_flags & M_PKTHDR);
pppoe_dispatch_disc_pkt(p, m->m_len, m->m_pkthdr.rcvif, eh);
}
- m_free(m);
+
+drop:
+ m_freem(m);
}
static void
@@ -547,6 +555,10 @@ pppoe_data_input(struct mbuf *m)
goto drop;
}
+ if (m->m_len < PPPOE_HEADERLEN) {
+ if ((m = m_pullup(m, PPPOE_HEADERLEN)) == 0)
+ goto drop;
+ }
p = mtod(m, u_int8_t*);
vertype = *p++;
@@ -601,7 +613,7 @@ pppoe_data_input(struct mbuf *m)
return;
drop:
- m_free(m);
+ m_freem(m);
}
static int
@@ -737,8 +749,7 @@ pppoe_get_mbuf(size_t len)
if (len+sizeof(struct ether_header) > MHLEN) {
MCLGET(m, M_DONTWAIT);
if ((m->m_flags & M_EXT) == 0) {
- struct mbuf *n;
- MFREE(m, n);
+ m_free(m);
return 0;
}
}
@@ -1062,10 +1073,8 @@ pppoe_start(struct ifnet *ifp)
while ((m = sppp_dequeue(ifp)) != NULL) {
len = m->m_pkthdr.len;
M_PREPEND(m, PPPOE_HEADERLEN, M_DONTWAIT);
- if (m == NULL) {
- m_free(m);
+ if (m == NULL)
break;
- }
p = mtod(m, u_int8_t*);
PPPOE_ADD_HEADER(p, 0, sc->sc_session, len);
----Next_Part(Fri_Jun_21_23:54:42_2002_961)----