Page MenuHomeFreeBSD

D33064.id.diff
No OneTemporary

D33064.id.diff

Index: sys/netpfil/ipfw/dn_sched_qfq.c
===================================================================
--- sys/netpfil/ipfw/dn_sched_qfq.c
+++ sys/netpfil/ipfw/dn_sched_qfq.c
@@ -568,7 +568,8 @@
m = dn_dequeue(&cl->_q);
if (!m) {
- D("BUG/* non-workconserving leaf */");
+ /* This can happen if the packet has been purged, because it's
+ * destined for a removed interface. */
return NULL;
}
NO(q->queued--;)
Index: sys/netpfil/ipfw/dn_sched_wf2q.c
===================================================================
--- sys/netpfil/ipfw/dn_sched_wf2q.c
+++ sys/netpfil/ipfw/dn_sched_wf2q.c
@@ -242,8 +242,13 @@
/* ok we have at least one eligible pkt */
q = HEAP_TOP(sch)->object;
alg_fq = (struct wf2qp_queue *)q;
- m = dn_dequeue(q);
+ m= dn_dequeue(q);
heap_extract(sch, NULL); /* Remove queue from heap. */
+ if (m == NULL) {
+ /* Packet may have been purged. */
+ heap_insert(&si->idle_heap, alg_fq->F, q);
+ return (NULL);
+ }
si->V += (uint64_t)(m->m_pkthdr.len) * si->inv_wsum;
alg_fq->S = alg_fq->F; /* Update start time. */
if (q->mq.head == 0) { /* not backlogged any more. */
Index: sys/netpfil/ipfw/ip_dummynet.c
===================================================================
--- sys/netpfil/ipfw/ip_dummynet.c
+++ sys/netpfil/ipfw/ip_dummynet.c
@@ -45,6 +45,7 @@
#include <sys/param.h>
#include <sys/ck.h>
+#include <sys/eventhandler.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
@@ -64,6 +65,8 @@
#include <netinet/ip_var.h> /* ip_output(), IP_FORWARDING */
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
+#include <net/if.h>
+#include <net/if_var.h>
#include <net/vnet.h>
#include <netpfil/ipfw/ip_fw_private.h>
@@ -101,6 +104,8 @@
CK_LIST_HEAD(, dn_aqm) aqmlist; /* list of AQMs */
#endif
+static eventhandler_tag ip_dn_detach_cookie;
+
static void
dummynet(void *arg)
{
@@ -2593,6 +2598,8 @@
ip_dn_vnet_destroy(void)
{
DN_BH_WLOCK();
+ V_dn_cfg.init_done = 0;
+
dummynet_flush();
DN_BH_WUNLOCK();
@@ -2603,6 +2610,114 @@
DN_LOCK_DESTROY();
}
+static int
+ip_dn_mq_flush_ifnet(struct mq *mq, struct ifnet *ifp)
+{
+ struct mbuf *m, *tmp;
+ struct mbuf *mprev;
+ int removed = 0;
+
+ m = mq->head;
+ mprev = NULL;
+
+ while (m != NULL) {
+ struct dn_pkt_tag *p = dn_tag_get(m);
+ if (p->ifp != ifp && m->m_pkthdr.rcvif != ifp) {
+ mprev = m;
+ m = m->m_nextpkt;
+ continue;
+ }
+
+ if (mprev == NULL) {
+ /* We're removing the first element in the mq. */
+ mq->head = m->m_nextpkt;
+ } else {
+ MPASS(mprev->m_nextpkt == m);
+ mprev->m_nextpkt = m->m_nextpkt;
+ }
+ tmp = m;
+ m = m->m_nextpkt;
+
+ tmp->m_nextpkt = NULL;
+ m_freem(tmp);
+
+ removed++;
+ }
+
+ mq->tail = mprev;
+
+ return (removed);
+}
+
+static int
+ip_dn_q_flush_ifnet(void *_q, void *_arg)
+{
+ struct dn_queue *q = _q;
+ struct ifnet *ifp = _arg;
+ int removed;
+
+ removed = ip_dn_mq_flush_ifnet(&q->mq, ifp);
+ q->count -= removed;
+
+ return (0);
+}
+
+static int
+ip_dn_fs_flush_ifnet(void *_fs, void *_arg)
+{
+ struct dn_fsk *fs = _fs;
+
+ if (!fs->qht)
+ return (0);
+
+ if (fs->fs.flags & DN_QHT_HASH)
+ dn_ht_scan(fs->qht, ip_dn_q_flush_ifnet, _arg);
+ else
+ ip_dn_q_flush_ifnet(fs->qht, _arg);
+
+ return (0);
+}
+
+static int
+ip_dn_schi_flush_ifnet(void *_si, void *_arg)
+{
+ struct dn_sch_inst *si = _si;
+ struct ifnet *ifp = _arg;
+
+ ip_dn_mq_flush_ifnet(&si->dline.mq, ifp);
+
+ return (0);
+}
+
+static int
+ip_dn_sched_flush_ifnet(void *_s, void *_arg)
+{
+ struct dn_schk *s = _s;
+
+ if (s->siht == NULL)
+ return (0);
+
+ if (s->sch.flags & DN_HAVE_MASK)
+ dn_ht_scan(s->siht, ip_dn_schi_flush_ifnet, _arg);
+ else if (s->siht)
+ ip_dn_schi_flush_ifnet(s->siht, _arg);
+
+ return (0);
+}
+
+static void
+ip_dn_detach_ifnet_event(void *arg __unused, struct ifnet *ifp)
+{
+ if (! V_dn_cfg.init_done)
+ return;
+
+ DN_BH_WLOCK();
+ /* Purge all queued packets for this interface. */
+ dn_ht_scan(V_dn_cfg.fshash, ip_dn_fs_flush_ifnet, ifp);
+ dn_ht_scan(V_dn_cfg.schedhash, ip_dn_sched_flush_ifnet, ifp);
+ DN_BH_WUNLOCK();
+}
+
static void
ip_dn_init(void)
{
@@ -2617,6 +2732,9 @@
taskqueue_thread_enqueue, &dn_tq);
taskqueue_start_threads(&dn_tq, 1, PI_NET, "dummynet");
+ ip_dn_detach_cookie = EVENTHANDLER_REGISTER(ifnet_departure_event,
+ ip_dn_detach_ifnet_event, NULL, EVENTHANDLER_PRI_ANY);
+
CK_LIST_INIT(&schedlist);
callout_init(&dn_timeout, 1);
dn_reschedule();
@@ -2635,6 +2753,8 @@
ip_dn_io_ptr = NULL;
}
+ EVENTHANDLER_DEREGISTER(ifnet_departure_event, ip_dn_detach_cookie);
+
callout_drain(&dn_timeout);
taskqueue_drain(dn_tq, &dn_task);
taskqueue_free(dn_tq);

File Metadata

Mime Type
text/plain
Expires
Wed, Feb 25, 3:02 PM (1 h, 20 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28990264
Default Alt Text
D33064.id.diff (4 KB)

Event Timeline