13b3a8eb9SGleb Smirnoff /*
23b3a8eb9SGleb Smirnoff *
33b3a8eb9SGleb Smirnoff * library functions for userland testing of dummynet schedulers
43b3a8eb9SGleb Smirnoff */
53b3a8eb9SGleb Smirnoff
63b3a8eb9SGleb Smirnoff #include "dn_test.h"
73b3a8eb9SGleb Smirnoff
83b3a8eb9SGleb Smirnoff void
m_freem(struct mbuf * m)93b3a8eb9SGleb Smirnoff m_freem(struct mbuf *m)
103b3a8eb9SGleb Smirnoff {
113b3a8eb9SGleb Smirnoff printf("free %p\n", m);
123b3a8eb9SGleb Smirnoff }
133b3a8eb9SGleb Smirnoff
143b3a8eb9SGleb Smirnoff int
dn_sched_modevent(module_t mod,int cmd,void * arg)153b3a8eb9SGleb Smirnoff dn_sched_modevent(module_t mod, int cmd, void *arg)
163b3a8eb9SGleb Smirnoff {
1710d72ffcSLuigi Rizzo (void)mod;
1810d72ffcSLuigi Rizzo (void)cmd;
1910d72ffcSLuigi Rizzo (void)arg;
203b3a8eb9SGleb Smirnoff return 0;
213b3a8eb9SGleb Smirnoff }
223b3a8eb9SGleb Smirnoff
233b3a8eb9SGleb Smirnoff void
dn_free_pkts(struct mbuf * m)243b3a8eb9SGleb Smirnoff dn_free_pkts(struct mbuf *m)
253b3a8eb9SGleb Smirnoff {
263b3a8eb9SGleb Smirnoff struct mbuf *x;
273b3a8eb9SGleb Smirnoff while ( (x = m) ) {
283b3a8eb9SGleb Smirnoff m = m->m_nextpkt;
293b3a8eb9SGleb Smirnoff m_freem(x);
303b3a8eb9SGleb Smirnoff }
313b3a8eb9SGleb Smirnoff }
323b3a8eb9SGleb Smirnoff
333b3a8eb9SGleb Smirnoff int
dn_delete_queue(void * _q,void * do_free)343b3a8eb9SGleb Smirnoff dn_delete_queue(void *_q, void *do_free)
353b3a8eb9SGleb Smirnoff {
363b3a8eb9SGleb Smirnoff struct dn_queue *q = _q;
3710d72ffcSLuigi Rizzo
3810d72ffcSLuigi Rizzo (void)do_free;
393b3a8eb9SGleb Smirnoff if (q->mq.head)
403b3a8eb9SGleb Smirnoff dn_free_pkts(q->mq.head);
413b3a8eb9SGleb Smirnoff free(q);
423b3a8eb9SGleb Smirnoff return 0;
433b3a8eb9SGleb Smirnoff }
443b3a8eb9SGleb Smirnoff
453b3a8eb9SGleb Smirnoff /*
463b3a8eb9SGleb Smirnoff * This is a simplified function for testing purposes, which does
473b3a8eb9SGleb Smirnoff * not implement statistics or random loss.
483b3a8eb9SGleb Smirnoff * Enqueue a packet in q, subject to space and queue management policy
493b3a8eb9SGleb Smirnoff * (whose parameters are in q->fs).
503b3a8eb9SGleb Smirnoff * Update stats for the queue and the scheduler.
513b3a8eb9SGleb Smirnoff * Return 0 on success, 1 on drop. The packet is consumed anyways.
523b3a8eb9SGleb Smirnoff */
533b3a8eb9SGleb Smirnoff int
dn_enqueue(struct dn_queue * q,struct mbuf * m,int drop)543b3a8eb9SGleb Smirnoff dn_enqueue(struct dn_queue *q, struct mbuf* m, int drop)
553b3a8eb9SGleb Smirnoff {
563b3a8eb9SGleb Smirnoff if (drop)
573b3a8eb9SGleb Smirnoff goto drop;
583b3a8eb9SGleb Smirnoff if (q->ni.length >= 200)
593b3a8eb9SGleb Smirnoff goto drop;
603b3a8eb9SGleb Smirnoff mq_append(&q->mq, m);
613b3a8eb9SGleb Smirnoff q->ni.length++;
623b3a8eb9SGleb Smirnoff q->ni.tot_bytes += m->m_pkthdr.len;
63*1cdc5f0bSLuigi Rizzo q->ni.tot_pkts++;
643b3a8eb9SGleb Smirnoff return 0;
653b3a8eb9SGleb Smirnoff
663b3a8eb9SGleb Smirnoff drop:
673b3a8eb9SGleb Smirnoff q->ni.drops++;
683b3a8eb9SGleb Smirnoff return 1;
693b3a8eb9SGleb Smirnoff }
703b3a8eb9SGleb Smirnoff
713b3a8eb9SGleb Smirnoff int
ipdn_bound_var(int * v,int dflt,int lo,int hi,const char * msg)723b3a8eb9SGleb Smirnoff ipdn_bound_var(int *v, int dflt, int lo, int hi, const char *msg)
733b3a8eb9SGleb Smirnoff {
7410d72ffcSLuigi Rizzo (void)msg;
753b3a8eb9SGleb Smirnoff if (*v < lo) {
763b3a8eb9SGleb Smirnoff *v = dflt;
773b3a8eb9SGleb Smirnoff } else if (*v > hi) {
783b3a8eb9SGleb Smirnoff *v = hi;
793b3a8eb9SGleb Smirnoff }
803b3a8eb9SGleb Smirnoff return *v;
813b3a8eb9SGleb Smirnoff }
823b3a8eb9SGleb Smirnoff
833b3a8eb9SGleb Smirnoff #ifndef __FreeBSD__
843b3a8eb9SGleb Smirnoff int
fls(int mask)853b3a8eb9SGleb Smirnoff fls(int mask)
863b3a8eb9SGleb Smirnoff {
873b3a8eb9SGleb Smirnoff int bit;
883b3a8eb9SGleb Smirnoff
893b3a8eb9SGleb Smirnoff if (mask == 0)
903b3a8eb9SGleb Smirnoff return (0);
913b3a8eb9SGleb Smirnoff for (bit = 1; mask != 1; bit++)
923b3a8eb9SGleb Smirnoff mask = (unsigned int)mask >> 1;
933b3a8eb9SGleb Smirnoff return (bit);
943b3a8eb9SGleb Smirnoff }
953b3a8eb9SGleb Smirnoff #endif
96