diff --git a/sys/netpfil/ipfw/dn_aqm_codel.c b/sys/netpfil/ipfw/dn_aqm_codel.c --- a/sys/netpfil/ipfw/dn_aqm_codel.c +++ b/sys/netpfil/ipfw/dn_aqm_codel.c @@ -192,8 +192,9 @@ codel_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts) { struct m_tag *mtag; - struct mbuf *m = q->mq.head; + struct mbuf *m; +next: m = q->mq.head; if (m == NULL) return m; q->mq.head = m->m_nextpkt; @@ -213,6 +214,11 @@ *pkt_ts = *(aqm_time_t *)(mtag + 1); m_tag_delete(m,mtag); } + if (m->m_pkthdr.rcvif != NULL && + __predict_false(m_rcvif_restore(m) == NULL)) { + m_freem(m); + goto next; + } return m; } diff --git a/sys/netpfil/ipfw/dn_aqm_pie.c b/sys/netpfil/ipfw/dn_aqm_pie.c --- a/sys/netpfil/ipfw/dn_aqm_pie.c +++ b/sys/netpfil/ipfw/dn_aqm_pie.c @@ -328,8 +328,9 @@ pie_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts, int getts) { struct m_tag *mtag; - struct mbuf *m = q->mq.head; + struct mbuf *m; +next: m = q->mq.head; if (m == NULL) return m; q->mq.head = m->m_nextpkt; @@ -351,6 +352,11 @@ m_tag_delete(m,mtag); } } + if (m->m_pkthdr.rcvif != NULL && + __predict_false(m_rcvif_restore(m) == NULL)) { + m_freem(m); + goto next; + } return m; } diff --git a/sys/netpfil/ipfw/dn_sched.h b/sys/netpfil/ipfw/dn_sched.h --- a/sys/netpfil/ipfw/dn_sched.h +++ b/sys/netpfil/ipfw/dn_sched.h @@ -170,7 +170,10 @@ static __inline struct mbuf* dn_dequeue(struct dn_queue *q) { - struct mbuf *m = q->mq.head; + struct mbuf *m; + +next: + m = q->mq.head; if (m == NULL) return NULL; #ifdef NEW_AQM @@ -190,6 +193,11 @@ } if (q->ni.length == 0) /* queue is now idle */ q->q_time = V_dn_cfg.curr_time; + if (m->m_pkthdr.rcvif != NULL && + __predict_false(m_rcvif_restore(m) == NULL)) { + m_freem(m); + goto next; + } return m; } diff --git a/sys/netpfil/ipfw/dn_sched_fq_codel.h b/sys/netpfil/ipfw/dn_sched_fq_codel.h --- a/sys/netpfil/ipfw/dn_sched_fq_codel.h +++ b/sys/netpfil/ipfw/dn_sched_fq_codel.h @@ -138,8 +138,9 @@ __inline static struct mbuf * fq_codel_extract_head(struct fq_codel_flow *q, aqm_time_t *pkt_ts, struct fq_codel_si *si) { - struct mbuf *m = q->mq.head; + struct mbuf *m; +next: m = q->mq.head; if (m == NULL) return m; q->mq.head = m->m_nextpkt; @@ -159,7 +160,11 @@ *pkt_ts = *(aqm_time_t *)(mtag + 1); m_tag_delete(m,mtag); } - + if (m->m_pkthdr.rcvif != NULL && + __predict_false(m_rcvif_restore(m) == NULL)) { + m_freem(m); + goto next; + } return m; } diff --git a/sys/netpfil/ipfw/dn_sched_fq_pie.c b/sys/netpfil/ipfw/dn_sched_fq_pie.c --- a/sys/netpfil/ipfw/dn_sched_fq_pie.c +++ b/sys/netpfil/ipfw/dn_sched_fq_pie.c @@ -338,8 +338,9 @@ fq_pie_extract_head(struct fq_pie_flow *q, aqm_time_t *pkt_ts, struct fq_pie_si *si, int getts) { - struct mbuf *m = q->mq.head; + struct mbuf *m; +next: m = q->mq.head; if (m == NULL) return m; q->mq.head = m->m_nextpkt; @@ -361,6 +362,11 @@ m_tag_delete(m,mtag); } } + if (m->m_pkthdr.rcvif != NULL && + __predict_false(m_rcvif_restore(m) == NULL)) { + m_freem(m); + goto next; + } return m; } diff --git a/sys/netpfil/ipfw/ip_dn_io.c b/sys/netpfil/ipfw/ip_dn_io.c --- a/sys/netpfil/ipfw/ip_dn_io.c +++ b/sys/netpfil/ipfw/ip_dn_io.c @@ -500,6 +500,8 @@ goto drop; if (f->plr && random() < f->plr) goto drop; + if (m->m_pkthdr.rcvif != NULL) + m_rcvif_serialize(m); #ifdef NEW_AQM /* Call AQM enqueue function */ if (q->fs->aqmfp) @@ -548,7 +550,11 @@ break; dline->mq.head = m->m_nextpkt; dline->mq.count--; - mq_append(q, m); + if (m->m_pkthdr.rcvif != NULL && + __predict_false(m_rcvif_restore(m) == NULL)) + m_freem(m); + else + mq_append(q, m); } if (m != NULL) { dline->oid.subtype = 1; /* in heap */ @@ -617,6 +623,8 @@ si->credit -= len_scaled; /* Move packet in the delay line */ dn_tag_get(m)->output_time = V_dn_cfg.curr_time + s->link.delay ; + if (m->m_pkthdr.rcvif != NULL) + m_rcvif_serialize(m); mq_append(&si->dline.mq, m); }