From a352dd9a719d162e4738c24d99427ad100165098 Mon Sep 17 00:00:00 2001 From: Bosko Milekic Date: Thu, 23 Nov 2000 22:25:03 +0000 Subject: [PATCH] Fixup (hopefully) bridging + ipfw + dummynet together... * Some dummynet code incorrectly handled a malloc()-allocated pseudo-mbuf header structure, called "pkt," and could consequently pollute the mbuf free list if it was ever passed to m_freem(). The fix involved passing not pkt, but essentially pkt->m_next (which is a real mbuf) to the mbuf utility routines. * Also, for dummynet, in bdg_forward(), made the code copy the ethernet header back into the mbuf (prepended) because the dummynet code that follows expects it to be there but it is, unfortunately for dummynet, passed to bdg_forward as a seperate argument. PRs: kern/19551 ; misc/21534 ; kern/23010 Submitted by: Thomas Moestl Reviewed by: bmilekic Approved by: luigi --- sys/net/bridge.c | 18 ++++++++++++++++-- sys/netinet/ip_dummynet.c | 10 +++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/sys/net/bridge.c b/sys/net/bridge.c index 7116346170c2..72747f2f1c55 100644 --- a/sys/net/bridge.c +++ b/sys/net/bridge.c @@ -630,8 +630,14 @@ bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst) if (dst == BDG_DROP) { /* this should not happen */ printf("xx bdg_forward for BDG_DROP\n"); - m_freem(*m0) ; - *m0 = NULL ; +#ifdef DUMMYNET + if ((*m0)->m_type == MT_DUMMYNET) + /* XXX: Shouldn't have to be doing this. */ + m_freem((*m0)->m_next); + else +#endif + m_freem(*m0); + *m0 = NULL; return 0; } if (dst == BDG_LOCAL) { /* this should not happen as well */ @@ -757,7 +763,15 @@ bdg_forward(struct mbuf **m0, struct ether_header *const eh, struct ifnet *dst) /* * pass the pkt to dummynet. Need to include m, dst, rule. * Dummynet consumes the packet in all cases. + * Also need to prepend the ethernet header. */ + M_PREPEND(m, ETHER_HDR_LEN, M_DONTWAIT); + if (m == NULL) { + if (canfree) + *m0 = NULL; + return ENOBUFS; + } + bcopy(eh, mtod(m, struct ether_header *), ETHER_HDR_LEN); dummynet_io((off & 0xffff), DN_TO_BDG_FWD, m, dst, NULL, 0, rule, 0); if (canfree) /* dummynet has consumed the original one */ *m0 = NULL ; diff --git a/sys/netinet/ip_dummynet.c b/sys/netinet/ip_dummynet.c index 7b1163b53fa1..f8882bb5ea27 100644 --- a/sys/netinet/ip_dummynet.c +++ b/sys/netinet/ip_dummynet.c @@ -404,13 +404,13 @@ transmit_event(struct dn_pipe *pipe) struct mbuf *m = (struct mbuf *)pkt ; struct ether_header hdr; - if (m->m_len < ETHER_HDR_LEN - && (m = m_pullup(m, ETHER_HDR_LEN)) == NULL) { - m_freem(m); + if (pkt->dn_m->m_len < ETHER_HDR_LEN + && (pkt->dn_m = m_pullup(pkt->dn_m, ETHER_HDR_LEN)) == NULL) { + m_freem(pkt->dn_m); break; } - bcopy(mtod(m, struct ether_header *), &hdr, ETHER_HDR_LEN); - m_adj(m, ETHER_HDR_LEN); + bcopy(mtod(pkt->dn_m, struct ether_header *), &hdr, ETHER_HDR_LEN); + m_adj(pkt->dn_m, ETHER_HDR_LEN); bdg_forward(&m, &hdr, pkt->ifp); if (m) m_freem(m);