From 0a70aaf8f5d93454d0940a09b94deecd7aa5fa0d Mon Sep 17 00:00:00 2001 From: Luiz Otavio O Souza Date: Fri, 21 Aug 2015 22:02:22 +0000 Subject: Add ALTQ(9) support for the CoDel algorithm. CoDel is a parameterless queue discipline that handles variable bandwidth and RTT. It can be used as the single queue discipline on an interface or as a sub discipline of existing queue disciplines such as PRIQ, CBQ, HFSC, FAIRQ. Differential Revision: https://reviews.freebsd.org/D3272 Reviewd by: rpaulo, gnn (previous version) Obtained from: pfSense Sponsored by: Rubicon Communications (Netgate) --- sys/net/altq/altq_fairq.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'sys/net/altq/altq_fairq.c') diff --git a/sys/net/altq/altq_fairq.c b/sys/net/altq/altq_fairq.c index f7ea8e7689e1..c808bdb12ad2 100644 --- a/sys/net/altq/altq_fairq.c +++ b/sys/net/altq/altq_fairq.c @@ -318,6 +318,14 @@ fairq_class_create(struct fairq_if *pif, int pri, int qlimit, #endif return (NULL); } +#endif +#ifndef ALTQ_CODEL + if (flags & FARF_CODEL) { +#ifdef ALTQ_DEBUG + printf("fairq_class_create: CODEL not configured for FAIRQ!\n"); +#endif + return (NULL); + } #endif if (nbuckets == 0) nbuckets = 256; @@ -340,6 +348,10 @@ fairq_class_create(struct fairq_if *pif, int pri, int qlimit, #ifdef ALTQ_RED if (cl->cl_qtype == Q_RED) red_destroy(cl->cl_red); +#endif +#ifdef ALTQ_CODEL + if (cl->cl_qtype == Q_CODEL) + codel_destroy(cl->cl_codel); #endif } else { cl = malloc(sizeof(struct fairq_class), @@ -407,6 +419,13 @@ fairq_class_create(struct fairq_if *pif, int pri, int qlimit, } } #endif /* ALTQ_RED */ +#ifdef ALTQ_CODEL + if (flags & FARF_CODEL) { + cl->cl_codel = codel_alloc(5, 100, 0); + if (cl->cl_codel != NULL) + cl->cl_qtype = Q_CODEL; + } +#endif return (cl); } @@ -445,6 +464,10 @@ fairq_class_destroy(struct fairq_class *cl) #ifdef ALTQ_RED if (cl->cl_qtype == Q_RED) red_destroy(cl->cl_red); +#endif +#ifdef ALTQ_CODEL + if (cl->cl_qtype == Q_CODEL) + codel_destroy(cl->cl_codel); #endif } free(cl->cl_buckets, M_DEVBUF); @@ -639,6 +662,10 @@ fairq_addq(struct fairq_class *cl, struct mbuf *m, u_int32_t bucketid) #ifdef ALTQ_RED if (cl->cl_qtype == Q_RED) return red_addq(cl->cl_red, &b->queue, m, cl->cl_pktattr); +#endif +#ifdef ALTQ_CODEL + if (cl->cl_qtype == Q_CODEL) + return codel_addq(cl->cl_codel, &b->queue, m); #endif if (qlen(&b->queue) >= qlimit(&b->queue)) { m_freem(m); @@ -669,6 +696,10 @@ fairq_getq(struct fairq_class *cl, uint64_t cur_time) #ifdef ALTQ_RED else if (cl->cl_qtype == Q_RED) m = red_getq(cl->cl_red, &b->queue); +#endif +#ifdef ALTQ_CODEL + else if (cl->cl_qtype == Q_CODEL) + m = codel_getq(cl->cl_codel, &b->queue); #endif else m = _getq(&b->queue); @@ -851,6 +882,10 @@ get_class_stats(struct fairq_classstats *sp, struct fairq_class *cl) if (cl->cl_qtype == Q_RIO) rio_getstats((rio_t *)cl->cl_red, &sp->red[0]); #endif +#ifdef ALTQ_CODEL + if (cl->cl_qtype == Q_CODEL) + codel_getstats(cl->cl_codel, &sp->codel); +#endif } /* convert a class handle to the corresponding class pointer */ -- cgit v1.2.3