diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2002-02-07 23:50:21 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2002-02-07 23:50:21 +0000 |
commit | 94eca6a13d961abb0f391a606a3501826b53fd75 (patch) | |
tree | 78922eb21c520bdf8c16527fe615d6d410b85e0f /sys/net/if_bridge.c | |
parent | 2400fe027022bac672c169fb50ef380a2a7f0dbb (diff) |
bridge_output() needs a forcibly aligned copy just like bridge_broadcast()
because of calls it makes to altq; thanks to art for testing and kjc for
pointing that I forgot this case.
Diffstat (limited to 'sys/net/if_bridge.c')
-rw-r--r-- | sys/net/if_bridge.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index dafc14f408f..41723e023f8 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.83 2002/01/02 20:06:03 jason Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.84 2002/02/07 23:50:20 jason Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -912,11 +912,33 @@ bridge_output(ifp, m, sa, rt) used = 1; mc = m; } else { - mc = m_copym(m, 0, M_COPYALL, M_NOWAIT); - 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) { + m_freem(m1); sc->sc_if.if_oerrors++; continue; } + + for (mx = m1; mx->m_next != NULL; mx = mx->m_next) + /*EMPTY*/; + mx->m_next = m2; + + if (m1->m_flags & M_PKTHDR) { + len = 0; + for (mx = m1; mx != NULL; mx = m->m_next) + len += mx->m_len; + m1->m_pkthdr.len = len; + } + mc = m1; } len = mc->m_pkthdr.len; mflags = mc->m_flags; |