summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Wright <jason@cvs.openbsd.org>2002-01-01 22:39:46 +0000
committerJason Wright <jason@cvs.openbsd.org>2002-01-01 22:39:46 +0000
commitce5d09a9ccafbd43f6f028fde6d380804d13f010 (patch)
treed031231ca2e8eaabab2feedee65d8655bb2dc6cf
parent8e13e9d66a8be4419979f782867e2b39331fcca1 (diff)
This is ugly: make a specialized deep copy in bridge_broadcast() that
ensures that the payload after the ethernet header is nicely aligned (basically this is two copies, one for the ethernet header and one for the payload) and glue the two copies together. bridge_filter() assumes it has been handed a nicely aligned packet. This should address pr#2248.
-rw-r--r--sys/net/if_bridge.c28
1 files changed, 25 insertions, 3 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 37325dc4b95..5818f423f13 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.81 2001/12/15 08:40:56 jason Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.82 2002/01/01 22:39:45 jason Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -1415,11 +1415,33 @@ bridge_broadcast(sc, ifp, eh, m)
mc = m;
used = 1;
} else {
- mc = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
- if (mc == NULL) {
+ struct mbuf *m1, *m2, *mx;
+
+ m1 = m_copym2(m, 0, sizeof(struct ether_header),
+ M_DONTWAIT);
+ if (m1 == NULL) {
+ sc->sc_if.if_oerrors++;
+ continue;
+ }
+ m2 = m_copym2(m, sizeof(struct ether_header),
+ M_COPYALL, M_DONTWAIT);
+ if (m2 == NULL) {
sc->sc_if.if_oerrors++;
continue;
}
+
+ for (mx = m1; mx->m_next != NULL; mx = mx->m_next)
+ ;
+ mx->m_next = m2;
+
+ if (m1->m_flags & M_PKTHDR) {
+ int len = 0;
+
+ for (mx = m1; mx != NULL; mx = mx->m_next)
+ len += mx->m_len;
+ m1->m_pkthdr.len = len;
+ }
+ mc = m1;
}
#if NPF > 0