The synchronization between ng_l2tp_seq_recv_nr() and
ng_l2tp_seq_rack_timeout() is buggy. ng_l2tp_seq_recv_nr()
releases ack'ed packets from the transmit queue, stops the retransmit
callout, checks whether the queue is empty, and arms the callout again
if not. All of this is done with the node mutex held.
ng_l2tp_seq_rack_timeout() checks to see if it was cancelled by
ng_l2tp_seq_recv_nr(), and *then* acquires the node mutex and
retransmits outstanding packets. So there is a race:
CPU 1:
- clears send queue
CPU 2:
- schedules callout
- callout blocks on node mutex
CPU 1:
- stops callout
- finds that the send queue is empty
CPU 2:
- tries to transmit the first packet from the send queue
- panic()
Fix it by modifying the callout handler to check whether it has been
cancelled after aquiring the node lock. We could perhaps further
"harden" the code by making the handler check for an empty queue, but I
believe it should not be necessary.