FreeBSD/sys/netpfil/ipfw/dn_sched_fq_codel.c
/*
 * Enqueue a packet into an appropriate queue according to
 * FQ_CODEL algorithm.
 */
Enqueue a packet into an appropriate queue according to
FQ_CODEL algorithm.
Enqueue a packet into an appropriate queue according to FQ_CODEL algorithm .
static int 
fq_codel_enqueue(struct dn_sch_inst *_si, struct dn_queue *_q, 
	struct mbuf *m)
{
	struct fq_codel_si *si;
	struct fq_codel_schk *schk;
	struct dn_sch_fq_codel_parms *param;
	struct dn_queue *mainq;
	int idx, drop, i, maxidx;
	mainq = (struct dn_queue *)(_si + 1);
	si = (struct fq_codel_si *)_si;
	schk = (struct fq_codel_schk *)(si->_si.sched+1);
	param = &schk->cfg;
	idx = fq_codel_classify_flow(m, param->flows_cnt, si);
	drop = codel_enqueue(&si->flows[idx], m, si);
	if (drop)
		return 1;
	if (!si->flows[idx].active ) {
		STAILQ_INSERT_TAIL(&si->newflows, &si->flows[idx], flowchain);
		si->flows[idx].deficit = param->quantum;
		si->flows[idx].cst.dropping = false;
		si->flows[idx].cst.first_above_time = 0;
		si->flows[idx].active = 1;
	}
	if (mainq->ni.length > schk->cfg.limit) { D("over limit");
		for (maxidx = 0; maxidx < schk->cfg.flows_cnt; maxidx++)
			if (si->flows[maxidx].active)
				break;
		if (maxidx < schk->cfg.flows_cnt) {
			for (i = maxidx + 1; i < schk->cfg.flows_cnt; i++) 
				if (si->flows[i].active && si->flows[i].stats.length >
					si->flows[maxidx].stats.length)
					maxidx = i;
			codel_drop_head(&si->flows[maxidx], si);
			D("maxidx = %d",maxidx);
			drop = 1;
		}
	}
	return drop;
}
static int fq_codel_enqueue ( struct dn_sch_inst * _si , struct dn_queue * _q , struct mbuf * m ) { struct fq_codel_si * si ; struct fq_codel_schk * schk ; struct dn_sch_fq_codel_parms * param ; struct dn_queue * mainq ; int idx , drop , i , maxidx ; mainq = ( struct dn_queue * ) ( _si + 1 ) ; si = ( struct fq_codel_si * ) _si ; schk = ( struct fq_codel_schk * ) ( si -> _si . sched + 1 ) ; param = & schk -> cfg ; idx = fq_codel_classify_flow ( m , param -> flows_cnt , si ) ; drop = codel_enqueue ( & si -> flows [ idx ] , m , si ) ; if ( drop ) return 1 ; if ( ! si -> flows [ idx ] . active ) { STAILQ_INSERT_TAIL ( & si -> newflows , & si -> flows [ idx ] , flowchain ) ; si -> flows [ idx ] . deficit = param -> quantum ; si -> flows [ idx ] . cst . dropping = false ; si -> flows [ idx ] . cst . first_above_time = 0 ; si -> flows [ idx ] . active = 1 ; } if ( mainq -> ni . length > schk -> cfg . limit ) { D ( " " ) ; for ( maxidx = 0 ; maxidx < schk -> cfg . flows_cnt ; maxidx ++ ) if ( si -> flows [ maxidx ] . active ) break ; if ( maxidx < schk -> cfg . flows_cnt ) { for ( i = maxidx + 1 ; i < schk -> cfg . flows_cnt ; i ++ ) if ( si -> flows [ i ] . active && si -> flows [ i ] . stats . length > si -> flows [ maxidx ] . stats . length ) maxidx = i ; codel_drop_head ( & si -> flows [ maxidx ] , si ) ; D ( " " , maxidx ) ; drop = 1 ; } } return drop ; }
Enqueue a packet into an appropriate queue according to
 FQ_CODEL algorithm.
Enqueue a packet into an appropriate queue according to FQ_CODEL algorithm .
/* classify a packet to queue number*/ /* enqueue packet into appropriate queue using CoDel AQM.
	 * Note: 'codel_enqueue' function returns 1 only when it unable to 
	 * add timestamp to packet (no limit check)*/ /* codel unable to timestamp a packet */ /* If the flow (sub-queue) is not active ,then add it to the tail of
	 * new flows list, initialize and activate it.
	 */ //D("activate %d",idx); /* check the limit for all queues and remove a packet from the
	 * largest one 
	 */ /* find first active flow */ /* find the largest sub- queue */