Thanks to Murphy for help debugging this.
                del_switch_port(p);
        rcu_assign_pointer(dps[dp->dp_idx], NULL);
 
+       /* Kill off local_port dev references from buffered packets that have
+        * associated dst entries. */
+       synchronize_rcu();
+       fwd_discard_all();
+
        /* Destroy dp->netdev.  (Must follow deleting switch ports since
         * dp->local_port has a reference to it.) */
        dp_dev_destroy(dp);
 
        return skb;
 }
 
+void fwd_discard_all(void) 
+{
+       unsigned long int flags;
+       int i;
+
+       spin_lock_irqsave(&buffer_lock, flags);
+       for (i = 0; i < N_PKT_BUFFERS; i++) {
+               kfree_skb(buffers[i].skb);
+               buffers[i].skb = NULL;
+       }
+       spin_unlock_irqrestore(&buffer_lock, flags);
+}
+
 static void discard_skb(uint32_t id)
 {
        unsigned long int flags;
 
 void fwd_exit(void)
 {
-       int i;
-
-       for (i = 0; i < N_PKT_BUFFERS; i++)
-               kfree_skb(buffers[i].skb);
+       fwd_discard_all();
 }
 
 /* Utility functions. */
 
                      const void *, size_t);
 
 uint32_t fwd_save_skb(struct sk_buff *skb);
+void fwd_discard_all(void);
 
 void fwd_exit(void);