diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-03-14 17:08:18 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2012-03-14 17:08:18 +0000 |
commit | d436d9eb485e6fb27d45d78e3af671fc0450ec58 (patch) | |
tree | 552bad1a4d1eede9f30b961d2254612be0529793 /sys/dev | |
parent | 2b07680e9ba2ff5194fee834d60aceff02562fbc (diff) |
ubsec gets stuck after receiving a packet of a particular length
and stops processing any further packets. this is believed to be
a result of the inconsistency of the destination mbuf chain as a
a copy acquired via m_copym2 works fine. so far only one problem
was discovered with the optimized inline version of m_copym2: a
cluster has to be allocated if source chain had one.
unfortunately, this solves the problem only for some packet sizes
so apply a larger hammer and call m_copym2 for now.
the problem was reported and diffs were patiently tested by Joosep
<joosepm-at-gmail-dot-com>, thanks!
deraadt agrees to this temporary measure.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/ubsec.c | 101 |
1 files changed, 7 insertions, 94 deletions
diff --git a/sys/dev/pci/ubsec.c b/sys/dev/pci/ubsec.c index 2abd2abfd06..beb97dba68b 100644 --- a/sys/dev/pci/ubsec.c +++ b/sys/dev/pci/ubsec.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ubsec.c,v 1.154 2012/01/13 09:53:24 mikeb Exp $ */ +/* $OpenBSD: ubsec.c,v 1.155 2012/03/14 17:08:17 mikeb Exp $ */ /* * Copyright (c) 2000 Jason L. Wright (jason@thought.net) @@ -87,7 +87,6 @@ int ubsec_freesession(u_int64_t); int ubsec_process(struct cryptop *); void ubsec_callback(struct ubsec_softc *, struct ubsec_q *); void ubsec_feed(struct ubsec_softc *); -void ubsec_mcopy(struct mbuf *, struct mbuf *, int, int); void ubsec_callback2(struct ubsec_softc *, struct ubsec_q2 *); void ubsec_feed2(struct ubsec_softc *); void ubsec_feed4(struct ubsec_softc *); @@ -1140,61 +1139,12 @@ ubsec_process(struct cryptop *crp) q->q_dst_m = q->q_src_m; q->q_dst_map = q->q_src_map; } else { - int totlen, len; - struct mbuf *m, *top, **mp; - - totlen = q->q_src_map->dm_mapsize; - if (q->q_src_m->m_flags & M_PKTHDR) { - len = MHLEN; - MGETHDR(m, M_DONTWAIT, MT_DATA); - } else { - len = MLEN; - MGET(m, M_DONTWAIT, MT_DATA); - } - if (m == NULL) { - err = ENOMEM; - goto errout; - } - if (len == MHLEN) { - err = m_dup_pkthdr(m, q->q_src_m, - M_DONTWAIT); - if (err) { - m_freem(m); - goto errout; - } - } - if (totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) - len = MCLBYTES; - } - m->m_len = len; - top = NULL; - mp = ⊤ - - while (totlen > 0) { - if (top) { - MGET(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - m_freem(top); - err = ENOMEM; - goto errout; - } - len = MLEN; - } - if (top && totlen >= MINCLSIZE) { - MCLGET(m, M_DONTWAIT); - if (m->m_flags & M_EXT) - len = MCLBYTES; - } - m->m_len = len = min(totlen, len); - totlen -= len; - *mp = m; - mp = &m->m_next; - } - q->q_dst_m = top; - ubsec_mcopy(q->q_src_m, q->q_dst_m, - cpskip, cpoffset); + q->q_dst_m = m_copym2(q->q_src_m, 0, M_COPYALL, + M_NOWAIT); + if (q->q_dst_m == NULL) { + err = ENOMEM; + goto errout; + } if (bus_dmamap_create(sc->sc_dmat, 0xfff0, UBS_MAX_SCATTER, 0xfff0, 0, BUS_DMA_NOWAIT, &q->q_dst_map) != 0) { @@ -1457,43 +1407,6 @@ ubsec_callback(struct ubsec_softc *sc, struct ubsec_q *q) crypto_done(crp); } -void -ubsec_mcopy(struct mbuf *srcm, struct mbuf *dstm, int hoffset, int toffset) -{ - int i, j, dlen, slen; - caddr_t dptr, sptr; - - j = 0; - sptr = srcm->m_data; - slen = srcm->m_len; - dptr = dstm->m_data; - dlen = dstm->m_len; - - while (1) { - for (i = 0; i < min(slen, dlen); i++) { - if (j < hoffset || j >= toffset) - *dptr++ = *sptr++; - slen--; - dlen--; - j++; - } - if (slen == 0) { - srcm = srcm->m_next; - if (srcm == NULL) - return; - sptr = srcm->m_data; - slen = srcm->m_len; - } - if (dlen == 0) { - dstm = dstm->m_next; - if (dstm == NULL) - return; - dptr = dstm->m_data; - dlen = dstm->m_len; - } - } -} - /* * feed the key generator, must be called at splnet() or higher. */ |