mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 00:32:25 -04:00
dummynet: use m_rcvif_serialize/restore when queueing packets
This fixed panic with interface being removed while packet was sitting on a queue. This allows to pass all dummynet tests including forthcoming dummynet:ipfw_interface_removal and dummynet:pf_interface_removal and demonstrates use of m_rcvif_serialize() and m_rcvif_restore(). Reviewed by: kp Differential revision: https://reviews.freebsd.org/D33267
This commit is contained in:
parent
e1882428dc
commit
165746f4e4
6 changed files with 46 additions and 7 deletions
|
|
@ -192,8 +192,9 @@ struct mbuf *
|
||||||
codel_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts)
|
codel_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts)
|
||||||
{
|
{
|
||||||
struct m_tag *mtag;
|
struct m_tag *mtag;
|
||||||
struct mbuf *m = q->mq.head;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
next: m = q->mq.head;
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return m;
|
return m;
|
||||||
q->mq.head = m->m_nextpkt;
|
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);
|
*pkt_ts = *(aqm_time_t *)(mtag + 1);
|
||||||
m_tag_delete(m,mtag);
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -328,8 +328,9 @@ static struct mbuf *
|
||||||
pie_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts, int getts)
|
pie_extract_head(struct dn_queue *q, aqm_time_t *pkt_ts, int getts)
|
||||||
{
|
{
|
||||||
struct m_tag *mtag;
|
struct m_tag *mtag;
|
||||||
struct mbuf *m = q->mq.head;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
next: m = q->mq.head;
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return m;
|
return m;
|
||||||
q->mq.head = m->m_nextpkt;
|
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);
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -170,7 +170,10 @@ int ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg);
|
||||||
static __inline struct mbuf*
|
static __inline struct mbuf*
|
||||||
dn_dequeue(struct dn_queue *q)
|
dn_dequeue(struct dn_queue *q)
|
||||||
{
|
{
|
||||||
struct mbuf *m = q->mq.head;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
next:
|
||||||
|
m = q->mq.head;
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
#ifdef NEW_AQM
|
#ifdef NEW_AQM
|
||||||
|
|
@ -190,6 +193,11 @@ dn_dequeue(struct dn_queue *q)
|
||||||
}
|
}
|
||||||
if (q->ni.length == 0) /* queue is now idle */
|
if (q->ni.length == 0) /* queue is now idle */
|
||||||
q->q_time = V_dn_cfg.curr_time;
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -138,8 +138,9 @@ fq_update_stats(struct fq_codel_flow *q, struct fq_codel_si *si, int len,
|
||||||
__inline static struct mbuf *
|
__inline static struct mbuf *
|
||||||
fq_codel_extract_head(struct fq_codel_flow *q, aqm_time_t *pkt_ts, struct fq_codel_si *si)
|
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)
|
if (m == NULL)
|
||||||
return m;
|
return m;
|
||||||
q->mq.head = m->m_nextpkt;
|
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);
|
*pkt_ts = *(aqm_time_t *)(mtag + 1);
|
||||||
m_tag_delete(m,mtag);
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -338,8 +338,9 @@ __inline static struct mbuf *
|
||||||
fq_pie_extract_head(struct fq_pie_flow *q, aqm_time_t *pkt_ts,
|
fq_pie_extract_head(struct fq_pie_flow *q, aqm_time_t *pkt_ts,
|
||||||
struct fq_pie_si *si, int getts)
|
struct fq_pie_si *si, int getts)
|
||||||
{
|
{
|
||||||
struct mbuf *m = q->mq.head;
|
struct mbuf *m;
|
||||||
|
|
||||||
|
next: m = q->mq.head;
|
||||||
if (m == NULL)
|
if (m == NULL)
|
||||||
return m;
|
return m;
|
||||||
q->mq.head = m->m_nextpkt;
|
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);
|
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;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -500,6 +500,8 @@ dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
|
||||||
goto drop;
|
goto drop;
|
||||||
if (f->plr && random() < f->plr)
|
if (f->plr && random() < f->plr)
|
||||||
goto drop;
|
goto drop;
|
||||||
|
if (m->m_pkthdr.rcvif != NULL)
|
||||||
|
m_rcvif_serialize(m);
|
||||||
#ifdef NEW_AQM
|
#ifdef NEW_AQM
|
||||||
/* Call AQM enqueue function */
|
/* Call AQM enqueue function */
|
||||||
if (q->fs->aqmfp)
|
if (q->fs->aqmfp)
|
||||||
|
|
@ -548,7 +550,11 @@ transmit_event(struct mq *q, struct delay_line *dline, uint64_t now)
|
||||||
break;
|
break;
|
||||||
dline->mq.head = m->m_nextpkt;
|
dline->mq.head = m->m_nextpkt;
|
||||||
dline->mq.count--;
|
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) {
|
if (m != NULL) {
|
||||||
dline->oid.subtype = 1; /* in heap */
|
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;
|
si->credit -= len_scaled;
|
||||||
/* Move packet in the delay line */
|
/* Move packet in the delay line */
|
||||||
dn_tag_get(m)->output_time = V_dn_cfg.curr_time + s->link.delay ;
|
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);
|
mq_append(&si->dline.mq, m);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue