1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa 5 * Portions Copyright (c) 2000 Akamba Corp. 6 * All rights reserved 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 * $FreeBSD$ 30 */ 31 32 #ifndef _IP_DUMMYNET_H 33 #define _IP_DUMMYNET_H 34 #define NEW_AQM 35 /* 36 * Definition of the kernel-userland API for dummynet. 37 * 38 * Setsockopt() and getsockopt() pass a batch of objects, each 39 * of them starting with a "struct dn_id" which should fully identify 40 * the object and its relation with others in the sequence. 41 * The first object in each request should have 42 * type= DN_CMD_*, id = DN_API_VERSION. 43 * For other objects, type and subtype specify the object, len indicates 44 * the total length including the header, and 'id' identifies the specific 45 * object. 46 * 47 * Most objects are numbered with an identifier in the range 1..65535. 48 * DN_MAX_ID indicates the first value outside the range. 49 */ 50 51 #define DN_API_VERSION 12500000 52 #define DN_MAX_ID 0x10000 53 54 struct dn_id { 55 uint16_t len; /* total obj len including this header */ 56 uint8_t type; 57 uint8_t subtype; 58 uint32_t id; /* generic id */ 59 }; 60 61 /* 62 * These values are in the type field of struct dn_id. 63 * To preserve the ABI, never rearrange the list or delete 64 * entries with the exception of DN_LAST 65 */ 66 enum { 67 DN_NONE = 0, 68 DN_LINK = 1, 69 DN_FS, 70 DN_SCH, 71 DN_SCH_I, 72 DN_QUEUE, 73 DN_DELAY_LINE, 74 DN_PROFILE, 75 DN_FLOW, /* struct dn_flow */ 76 DN_TEXT, /* opaque text is the object */ 77 78 DN_CMD_CONFIG = 0x80, /* objects follow */ 79 DN_CMD_DELETE, /* subtype + list of entries */ 80 DN_CMD_GET, /* subtype + list of entries */ 81 DN_CMD_FLUSH, 82 /* for compatibility with FreeBSD 7.2/8 */ 83 DN_COMPAT_PIPE, 84 DN_COMPAT_QUEUE, 85 DN_GET_COMPAT, 86 87 /* special commands for emulation of sysctl variables */ 88 DN_SYSCTL_GET, 89 DN_SYSCTL_SET, 90 #ifdef NEW_AQM 91 /* subtypes used for setting/getting extra parameters. 92 * these subtypes used with IP_DUMMYNET3 command (get) 93 * and DN_TEXT (set). */ 94 DN_AQM_PARAMS, /* AQM extra params */ 95 DN_SCH_PARAMS, /* scheduler extra params */ 96 #endif 97 DN_LAST, 98 }; 99 100 enum { /* subtype for schedulers, flowset and the like */ 101 DN_SCHED_UNKNOWN = 0, 102 DN_SCHED_FIFO = 1, 103 DN_SCHED_WF2QP = 2, 104 /* others are in individual modules */ 105 }; 106 107 enum { /* user flags */ 108 DN_HAVE_MASK = 0x0001, /* fs or sched has a mask */ 109 DN_NOERROR = 0x0002, /* do not report errors */ 110 DN_QHT_HASH = 0x0004, /* qht is a hash table */ 111 DN_QSIZE_BYTES = 0x0008, /* queue size is in bytes */ 112 DN_HAS_PROFILE = 0x0010, /* a link has a profile */ 113 DN_IS_RED = 0x0020, 114 DN_IS_GENTLE_RED= 0x0040, 115 DN_IS_ECN = 0x0080, 116 #ifdef NEW_AQM 117 DN_IS_AQM = 0x0100, /* AQMs: e.g Codel & PIE */ 118 #endif 119 DN_PIPE_CMD = 0x1000, /* pipe config... */ 120 }; 121 122 /* 123 * link template. 124 */ 125 struct dn_link { 126 struct dn_id oid; 127 128 /* 129 * Userland sets bw and delay in bits/s and milliseconds. 130 * The kernel converts this back and forth to bits/tick and ticks. 131 * XXX what about burst ? 132 */ 133 int32_t link_nr; 134 int bandwidth; /* bit/s or bits/tick. */ 135 int delay; /* ms and ticks */ 136 uint64_t burst; /* scaled. bits*Hz XXX */ 137 }; 138 139 /* 140 * A flowset, which is a template for flows. Contains parameters 141 * from the command line: id, target scheduler, queue sizes, plr, 142 * flow masks, buckets for the flow hash, and possibly scheduler- 143 * specific parameters (weight, quantum and so on). 144 */ 145 struct dn_fs { 146 struct dn_id oid; 147 uint32_t fs_nr; /* the flowset number */ 148 uint32_t flags; /* userland flags */ 149 int qsize; /* queue size in slots or bytes */ 150 int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ 151 uint32_t buckets; /* buckets used for the queue hash table */ 152 153 struct ipfw_flow_id flow_mask; 154 uint32_t sched_nr; /* the scheduler we attach to */ 155 /* generic scheduler parameters. Leave them at -1 if unset. 156 * Now we use 0: weight, 1: lmax, 2: priority 157 */ 158 int par[4]; 159 160 /* RED/GRED parameters. 161 * weight and probabilities are in the range 0..1 represented 162 * in fixed point arithmetic with SCALE_RED decimal bits. 163 */ 164 #define SCALE_RED 16 165 #define SCALE(x) ( (x) << SCALE_RED ) 166 #define SCALE_VAL(x) ( (x) >> SCALE_RED ) 167 #define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) 168 int w_q ; /* queue weight (scaled) */ 169 int max_th ; /* maximum threshold for queue (scaled) */ 170 int min_th ; /* minimum threshold for queue (scaled) */ 171 int max_p ; /* maximum value for p_b (scaled) */ 172 173 }; 174 175 /* 176 * dn_flow collects flow_id and stats for queues and scheduler 177 * instances, and is used to pass these info to userland. 178 * oid.type/oid.subtype describe the object, oid.id is number 179 * of the parent object. 180 */ 181 struct dn_flow { 182 struct dn_id oid; 183 struct ipfw_flow_id fid; 184 uint64_t tot_pkts; /* statistics counters */ 185 uint64_t tot_bytes; 186 uint32_t length; /* Queue length, in packets */ 187 uint32_t len_bytes; /* Queue length, in bytes */ 188 uint32_t drops; 189 }; 190 191 192 /* 193 * Scheduler template, mostly indicating the name, number, 194 * sched_mask and buckets. 195 */ 196 struct dn_sch { 197 struct dn_id oid; 198 uint32_t sched_nr; /* N, scheduler number */ 199 uint32_t buckets; /* number of buckets for the instances */ 200 uint32_t flags; /* have_mask, ... */ 201 202 char name[16]; /* null terminated */ 203 /* mask to select the appropriate scheduler instance */ 204 struct ipfw_flow_id sched_mask; /* M */ 205 }; 206 207 208 /* A delay profile is attached to a link. 209 * Note that a profile, as any other object, cannot be longer than 2^16 210 */ 211 #define ED_MAX_SAMPLES_NO 1024 212 struct dn_profile { 213 struct dn_id oid; 214 /* fields to simulate a delay profile */ 215 #define ED_MAX_NAME_LEN 32 216 char name[ED_MAX_NAME_LEN]; 217 int link_nr; 218 int loss_level; 219 int bandwidth; // XXX use link bandwidth? 220 int samples_no; /* actual len of samples[] */ 221 int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */ 222 }; 223 224 #ifdef NEW_AQM 225 /* Extra parameters for AQM and scheduler. 226 * This struct is used to pass and retrieve parameters (configurations) 227 * to/from AQM and Scheduler. 228 */ 229 struct dn_extra_parms { 230 struct dn_id oid; 231 char name[16]; 232 uint32_t nr; 233 #define DN_MAX_EXTRA_PARM 10 234 int64_t par[DN_MAX_EXTRA_PARM]; 235 }; 236 #endif 237 238 /* 239 * Overall structure of dummynet 240 241 In dummynet, packets are selected with the firewall rules, and passed 242 to two different objects: PIPE or QUEUE (bad name). 243 244 A QUEUE defines a classifier, which groups packets into flows 245 according to a 'mask', puts them into independent queues (one 246 per flow) with configurable size and queue management policy, 247 and passes flows to a scheduler: 248 249 (flow_mask|sched_mask) sched_mask 250 +---------+ weight Wx +-------------+ 251 | |->-[flow]-->--| |-+ 252 -->--| QUEUE x | ... | | | 253 | |->-[flow]-->--| SCHEDuler N | | 254 +---------+ | | | 255 ... | +--[LINK N]-->-- 256 +---------+ weight Wy | | +--[LINK N]-->-- 257 | |->-[flow]-->--| | | 258 -->--| QUEUE y | ... | | | 259 | |->-[flow]-->--| | | 260 +---------+ +-------------+ | 261 +-------------+ 262 263 Many QUEUE objects can connect to the same scheduler, each 264 QUEUE object can have its own set of parameters. 265 266 In turn, the SCHEDuler 'forks' multiple instances according 267 to a 'sched_mask', each instance manages its own set of queues 268 and transmits on a private instance of a configurable LINK. 269 270 A PIPE is a simplified version of the above, where there 271 is no flow_mask, and each scheduler instance handles a single queue. 272 273 The following data structures (visible from userland) describe 274 the objects used by dummynet: 275 276 + dn_link, contains the main configuration parameters related 277 to delay and bandwidth; 278 + dn_profile describes a delay profile; 279 + dn_flow describes the flow status (flow id, statistics) 280 281 + dn_sch describes a scheduler 282 + dn_fs describes a flowset (msk, weight, queue parameters) 283 284 * 285 */ 286 287 #endif /* _IP_DUMMYNET_H */ 288