diff --git a/sys/netpfil/ipfw/dn_aqm_codel.c b/sys/netpfil/ipfw/dn_aqm_codel.c index 79c6afd8b635..2f6d145485c6 100644 --- a/sys/netpfil/ipfw/dn_aqm_codel.c +++ b/sys/netpfil/ipfw/dn_aqm_codel.c @@ -192,8 +192,9 @@ struct mbuf * 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 @@ codel_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts) *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 index 746b9f031220..5eadf08a4860 100644 --- a/sys/netpfil/ipfw/dn_aqm_pie.c +++ b/sys/netpfil/ipfw/dn_aqm_pie.c @@ -328,8 +328,9 @@ static struct mbuf * 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 @@ pie_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts, int getts) 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 index 5c506c1d30ac..ef7242cd7355 100644 --- a/sys/netpfil/ipfw/dn_sched.h +++ b/sys/netpfil/ipfw/dn_sched.h @@ -170,7 +170,10 @@ int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg); 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 @@ dn_dequeue(struct dn_queue *q) } 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 index 2f82a63ca093..b84dfe7579fb 100644 --- a/sys/netpfil/ipfw/dn_sched_fq_codel.h +++ b/sys/netpfil/ipfw/dn_sched_fq_codel.h @@ -138,8 +138,9 @@ fq_update_stats(struct fq_codel_flow *q, struct fq_codel_si *si, int len, __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 @@ fq_codel_extract_head(struct fq_codel_flow *q, aqm_time_t *pkt_ts, struct fq_cod *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 index c3de665687a3..f589614be436 100644 --- a/sys/netpfil/ipfw/dn_sched_fq_pie.c +++ b/sys/netpfil/ipfw/dn_sched_fq_pie.c @@ -338,8 +338,9 @@ __inline static struct mbuf * 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 @@ fq_pie_extract_head(struct fq_pie_flow *q, aqm_time_t *pkt_ts, 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 index 11ad498505f4..824e7450fb8f 100644 --- a/sys/netpfil/ipfw/ip_dn_io.c +++ b/sys/netpfil/ipfw/ip_dn_io.c @@ -500,6 +500,8 @@ dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop) 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 @@ transmit_event(struct mq *q, struct delay_line *dline, uint64_t now) 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 @@ serve_sched(struct mq *q, struct dn_sch_inst *si, uint64_t now) 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); }