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 <tmoestl@gmx.net>
Reviewed by: bmilekic
Approved by: luigi
This commit is contained in:
Bosko Milekic 2000-11-23 22:25:03 +00:00
parent 232095104e
commit a352dd9a71
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=69099
2 changed files with 21 additions and 7 deletions

View File

@ -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 ;

View File

@ -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);