ubsec gets stuck after receiving a packet of a particular length. for example, in my tests it was a tcp packet with 59 bytes of payload. interestingly, something breaks horribly in the hardware and it stops processing any other packets.
the exact cause is believed to be a difference between the structure of a source mbuf and a destination mbuf chains. ubsec has alignment requirements that sometimes prevent it from performing crypto in place. to be precise, all of the input network packets look like mhdr->cluster. currently, the code does it like this instead: mhdr->mhdr->cluster. the patch makes it prefer the former. i have verified it with a m_copym2 which wouldn't allocate an intermediate mhdr and it works fine as well. the problem was reported and diffs were patiently tested by Joosep <joosepm-at-gmail-dot-com>, thanks! [we both have the same 5862 model, so no other one was tested, but given the nature of the diff, this shouldn't be a problem.] OK? Index: dev/pci/ubsec.c =================================================================== RCS file: /home/cvs/src/sys/dev/pci/ubsec.c,v retrieving revision 1.154 diff -u -p -U10 -r1.154 ubsec.c --- dev/pci/ubsec.c 13 Jan 2012 09:53:24 -0000 1.154 +++ dev/pci/ubsec.c 12 Mar 2012 14:11:19 -0000 @@ -1156,21 +1156,22 @@ ubsec_process(struct cryptop *crp) 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) { + if (q->q_src_m->m_flags & M_EXT || + 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) {