Page MenuHomeFreeBSD

D7780.id20037.diff
No OneTemporary

D7780.id20037.diff

Index: sys/net/if_bridge.c
===================================================================
--- sys/net/if_bridge.c
+++ sys/net/if_bridge.c
@@ -333,7 +333,7 @@
#ifdef INET6
static int bridge_ip6_checkbasic(struct mbuf **mp);
#endif /* INET6 */
-static int bridge_fragment(struct ifnet *, struct mbuf *,
+static int bridge_fragment(struct ifnet *, struct mbuf **mp,
struct ether_header *, int, struct llc *);
static void bridge_linkstate(struct ifnet *ifp);
static void bridge_linkcheck(struct bridge_softc *sc);
@@ -1917,6 +1917,7 @@
m->m_flags &= ~M_VLANTAG;
}
+ M_ASSERTPKTHDR(m); /* We shouldn't transmit mbuf without pkthdr */
if ((err = dst_ifp->if_transmit(dst_ifp, m))) {
m_freem(m0);
if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1);
@@ -3234,10 +3235,12 @@
break;
/* check if we need to fragment the packet */
+ /* bridge_fragment generates a mbuf chain of packets */
+ /* that already include eth headers */
if (V_pfil_member && ifp != NULL && dir == PFIL_OUT) {
i = (*mp)->m_pkthdr.len;
if (i > ifp->if_mtu) {
- error = bridge_fragment(ifp, *mp, &eh2, snap,
+ error = bridge_fragment(ifp, mp, &eh2, snap,
&llc1);
return (error);
}
@@ -3476,13 +3479,13 @@
/*
* bridge_fragment:
*
- * Return a fragmented mbuf chain.
+ * Fragment mbuf chain in multiple packets and prepend ethernet header.
*/
static int
-bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh,
+bridge_fragment(struct ifnet *ifp, struct mbuf **mp, struct ether_header *eh,
int snap, struct llc *llc)
{
- struct mbuf *m0;
+ struct mbuf *m = *mp, *m0 = NULL, *mprev = NULL, *mcur = NULL;
struct ip *ip;
int error = -1;
@@ -3496,24 +3499,44 @@
if (error)
goto out;
- /* walk the chain and re-add the Ethernet header */
- for (m0 = m; m0; m0 = m0->m_nextpkt) {
+ /*
+ * walk the chain and re-add the Ethernet header for
+ * each mbuf packets
+ */
+
+ for (mcur = m; mcur; mcur = mcur->m_nextpkt) {
if (error == 0) {
if (snap) {
- M_PREPEND(m0, sizeof(struct llc), M_NOWAIT);
- if (m0 == NULL) {
+ M_PREPEND(mcur, sizeof(struct llc), M_NOWAIT);
+
+ if (mcur == NULL) {
error = ENOBUFS;
continue;
}
- bcopy(llc, mtod(m0, caddr_t),
+ bcopy(llc, mtod(mcur, caddr_t),
sizeof(struct llc));
}
- M_PREPEND(m0, ETHER_HDR_LEN, M_NOWAIT);
- if (m0 == NULL) {
+ m0 = mcur;
+ M_PREPEND(mcur, ETHER_HDR_LEN, M_NOWAIT);
+ if (mcur == NULL) {
error = ENOBUFS;
continue;
}
- bcopy(eh, mtod(m0, caddr_t), ETHER_HDR_LEN);
+ bcopy(eh, mtod(mcur, caddr_t), ETHER_HDR_LEN);
+ /* if M_PREPEND had create a new mbuf, we need to:
+ * update previous mbuf packet to use this new one
+ * moving m_nextpkt from the old mbuf to the new one */
+ if ( m0 != mcur ) {
+ mcur->m_nextpkt = mcur->m_next->m_nextpkt;
+ mcur->m_next->m_nextpkt = NULL;
+ if (mprev != NULL) { /* It's not the first packet in the chain*/
+ mprev->m_nextpkt = mcur;
+ } else { /* the first mbuf in the original chain need to be updated */
+ *mp = mcur;
+ }
+ }
+ mprev = mcur;
+
} else
m_freem(m);
}

File Metadata

Mime Type
text/plain
Expires
Fri, Oct 24, 3:45 AM (10 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24117020
Default Alt Text
D7780.id20037.diff (3 KB)

Event Timeline