1 /*-
2 * Copyright (C) 2016 Centre for Advanced Internet Architectures,
3 * Swinburne University of Technology, Melbourne, Australia.
4 * Portions of this code were made possible in part by a gift from
5 * The Comcast Innovation Fund.
6 * Implemented by Rasool Al-Saadi <ralsaadi@swin.edu.au>
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30 /*
31 * API for writing an Active Queue Management algorithm for Dummynet
32 *
33 * $FreeBSD$
34 */
35
36 #ifndef _IP_DN_AQM_H
37 #define _IP_DN_AQM_H
38
39 #include <sys/ck.h>
40
41 /* NOW is the current time in millisecond*/
42 #define NOW ((V_dn_cfg.curr_time * tick) / 1000)
43
44 #define AQM_UNOW (V_dn_cfg.curr_time * tick)
45 #define AQM_TIME_1US ((aqm_time_t)(1))
46 #define AQM_TIME_1MS ((aqm_time_t)(1000))
47 #define AQM_TIME_1S ((aqm_time_t)(AQM_TIME_1MS * 1000))
48
49 /* aqm time allows to store up to 4294 seconds */
50 typedef uint32_t aqm_time_t;
51 typedef int32_t aqm_stime_t;
52
53 #define DN_AQM_MTAG_TS 55345
54
55 /* Macro for variable bounding */
56 #define BOUND_VAR(x,l,h) ((x) > (h)? (h) : ((x) > (l)? (x) : (l)))
57
58 /*
59 * Structure for holding data and function pointers that together represent a
60 * AQM algorithm.
61 */
62 struct dn_aqm {
63 #define DN_AQM_NAME_MAX 50
64 char name[DN_AQM_NAME_MAX]; /* name of AQM algorithm */
65 uint32_t type; /* AQM type number */
66
67 /* Methods implemented by AQM algorithm:
68 *
69 * enqueue enqueue packet 'm' on queue 'q'.
70 * Return 0 on success, 1 on drop.
71 *
72 * dequeue dequeue a packet from queue 'q'.
73 * Return a packet, NULL if no packet available.
74 *
75 * config configure AQM algorithm
76 * If required, this function should allocate space to store
77 * the configurations and set 'fs->aqmcfg' to point to this space.
78 * 'dn_extra_parms' includes array of parameters send
79 * from ipfw userland command.
80 * Return 0 on success, non-zero otherwise.
81 *
82 * deconfig deconfigure AQM algorithm.
83 * The allocated configuration memory space should be freed here.
84 * Return 0 on success, non-zero otherwise.
85 *
86 * init initialise AQM status variables of queue 'q'
87 * This function is used to allocate space and init AQM status for a
88 * queue and q->aqm_status to point to this space.
89 * Return 0 on success, non-zero otherwise.
90 *
91 * cleanup cleanup AQM status variables of queue 'q'
92 * The allocated memory space for AQM status should be freed here.
93 * Return 0 on success, non-zero otherwise.
94 *
95 * getconfig retrieve AQM configurations
96 * This function is used to return AQM parameters to userland
97 * command. The function should fill 'dn_extra_parms' struct with
98 * the AQM configurations using 'par' array.
99 *
100 */
101
102 int (*enqueue)(struct dn_queue *, struct mbuf *);
103 struct mbuf * (*dequeue)(struct dn_queue *);
104 int (*config)(struct dn_fsk *, struct dn_extra_parms *ep, int);
105 int (*deconfig)(struct dn_fsk *);
106 int (*init)(struct dn_queue *);
107 int (*cleanup)(struct dn_queue *);
108 int (*getconfig)(struct dn_fsk *, struct dn_extra_parms *);
109
110 int ref_count; /*Number of queues instances in the system */
111 int cfg_ref_count; /*Number of AQM instances in the system */
112 CK_LIST_ENTRY(dn_aqm) next; /* Next AQM in the list */
113 };
114
115 /* Helper function to update queue and scheduler statistics.
116 * negative len + drop -> drop
117 * negative len -> dequeue
118 * positive len -> enqueue
119 * positive len + drop -> drop during enqueue
120 */
121 __inline static void
122 update_stats(struct dn_queue *q, int len, int drop)
123 {
124 int inc = 0;
125 struct dn_flow *sni;
126 struct dn_flow *qni;
127
128 sni = &q->_si->ni;
129 qni = &q->ni;
130
131 if (len < 0)
132 inc = -1;
133 else if(len > 0)
134 inc = 1;
135
136 if (drop) {
137 qni->drops++;
138 sni->drops++;
139 V_dn_cfg.io_pkt_drop++;
140 } else {
141 /*update queue stats */
142 qni->length += inc;
143 qni->len_bytes += len;
144
145 /*update scheduler instance stats */
146 sni->length += inc;
147 sni->len_bytes += len;
148 }
149 /* tot_pkts is updated in dn_enqueue function */
150 }
151
152 /* kernel module related function */
153 int
154 dn_aqm_modevent(module_t mod, int cmd, void *arg);
155
156 #define DECLARE_DNAQM_MODULE(name, dnaqm) \
157 static moduledata_t name##_mod = { \
158 #name, dn_aqm_modevent, dnaqm \
159 }; \
160 DECLARE_MODULE(name, name##_mod, \
161 SI_SUB_PROTO_IFATTACHDOMAIN, SI_ORDER_ANY); \
162 MODULE_DEPEND(name, dummynet, 3, 3, 3)
163
164 #endif
Cache object: b028b46ba4b774418406bbe1aa839119
|