1139823Simp/*- 2204591Sluigi * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa 355597Sluigi * Portions Copyright (c) 2000 Akamba Corp. 455597Sluigi * All rights reserved 539119Sluigi * 655597Sluigi * Redistribution and use in source and binary forms, with or without 755597Sluigi * modification, are permitted provided that the following conditions 855597Sluigi * are met: 955597Sluigi * 1. Redistributions of source code must retain the above copyright 1055597Sluigi * notice, this list of conditions and the following disclaimer. 1155597Sluigi * 2. Redistributions in binary form must reproduce the above copyright 1255597Sluigi * notice, this list of conditions and the following disclaimer in the 1355597Sluigi * documentation and/or other materials provided with the distribution. 1439119Sluigi * 1555597Sluigi * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1655597Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1755597Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1855597Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 1955597Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2055597Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2155597Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2255597Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2355597Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2455597Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2555597Sluigi * SUCH DAMAGE. 2639119Sluigi * 2750477Speter * $FreeBSD$ 2839119Sluigi */ 2939119Sluigi 3039119Sluigi#ifndef _IP_DUMMYNET_H 3139119Sluigi#define _IP_DUMMYNET_H 32300779Struckman#define NEW_AQM 3339119Sluigi/* 34204591Sluigi * Definition of the kernel-userland API for dummynet. 3571137Sluigi * 36204591Sluigi * Setsockopt() and getsockopt() pass a batch of objects, each 37204591Sluigi * of them starting with a "struct dn_id" which should fully identify 38204591Sluigi * the object and its relation with others in the sequence. 39204591Sluigi * The first object in each request should have 40204591Sluigi * type= DN_CMD_*, id = DN_API_VERSION. 41204591Sluigi * For other objects, type and subtype specify the object, len indicates 42204591Sluigi * the total length including the header, and 'id' identifies the specific 43204591Sluigi * object. 4471137Sluigi * 45204591Sluigi * Most objects are numbered with an identifier in the range 1..65535. 46204591Sluigi * DN_MAX_ID indicates the first value outside the range. 4761413Sluigi */ 4871137Sluigi 49204591Sluigi#define DN_API_VERSION 12500000 50204591Sluigi#define DN_MAX_ID 0x10000 5161413Sluigi 52204591Sluigistruct dn_id { 53204591Sluigi uint16_t len; /* total obj len including this header */ 54204591Sluigi uint8_t type; 55204591Sluigi uint8_t subtype; 56204591Sluigi uint32_t id; /* generic id */ 57204591Sluigi}; 5861413Sluigi 5971137Sluigi/* 60204591Sluigi * These values are in the type field of struct dn_id. 61204591Sluigi * To preserve the ABI, never rearrange the list or delete 62204591Sluigi * entries with the exception of DN_LAST 63104975Sseanc */ 64204591Sluigienum { 65204591Sluigi DN_NONE = 0, 66204591Sluigi DN_LINK = 1, 67204591Sluigi DN_FS, 68204591Sluigi DN_SCH, 69204591Sluigi DN_SCH_I, 70204591Sluigi DN_QUEUE, 71204591Sluigi DN_DELAY_LINE, 72204591Sluigi DN_PROFILE, 73204591Sluigi DN_FLOW, /* struct dn_flow */ 74204591Sluigi DN_TEXT, /* opaque text is the object */ 75104975Sseanc 76204591Sluigi DN_CMD_CONFIG = 0x80, /* objects follow */ 77204591Sluigi DN_CMD_DELETE, /* subtype + list of entries */ 78204591Sluigi DN_CMD_GET, /* subtype + list of entries */ 79204591Sluigi DN_CMD_FLUSH, 80204591Sluigi /* for compatibility with FreeBSD 7.2/8 */ 81204591Sluigi DN_COMPAT_PIPE, 82204591Sluigi DN_COMPAT_QUEUE, 83204591Sluigi DN_GET_COMPAT, 84204591Sluigi 85204591Sluigi /* special commands for emulation of sysctl variables */ 86204591Sluigi DN_SYSCTL_GET, 87204591Sluigi DN_SYSCTL_SET, 88300779Struckman#ifdef NEW_AQM 89300779Struckman /* subtypes used for setting/getting extra parameters. 90300779Struckman * these subtypes used with IP_DUMMYNET3 command (get) 91300779Struckman * and DN_TEXT (set). */ 92300779Struckman DN_AQM_PARAMS, /* AQM extra params */ 93300779Struckman DN_SCH_PARAMS, /* scheduler extra params */ 94300779Struckman#endif 95204591Sluigi DN_LAST, 96206845Sluigi}; 9755597Sluigi 98204591Sluigienum { /* subtype for schedulers, flowset and the like */ 99204591Sluigi DN_SCHED_UNKNOWN = 0, 100204591Sluigi DN_SCHED_FIFO = 1, 101204591Sluigi DN_SCHED_WF2QP = 2, 102204591Sluigi /* others are in individual modules */ 103206845Sluigi}; 10455597Sluigi 105204591Sluigienum { /* user flags */ 106204591Sluigi DN_HAVE_MASK = 0x0001, /* fs or sched has a mask */ 107204591Sluigi DN_NOERROR = 0x0002, /* do not report errors */ 108204591Sluigi DN_QHT_HASH = 0x0004, /* qht is a hash table */ 109204591Sluigi DN_QSIZE_BYTES = 0x0008, /* queue size is in bytes */ 110204591Sluigi DN_HAS_PROFILE = 0x0010, /* a link has a profile */ 111204591Sluigi DN_IS_RED = 0x0020, 112204591Sluigi DN_IS_GENTLE_RED= 0x0040, 113266941Shiren DN_IS_ECN = 0x0080, 114300779Struckman #ifdef NEW_AQM 115300779Struckman DN_IS_AQM = 0x0100, /* AQMs: e.g Codel & PIE */ 116300779Struckman #endif 117204591Sluigi DN_PIPE_CMD = 0x1000, /* pipe config... */ 11839119Sluigi}; 11939119Sluigi 12061413Sluigi/* 121204591Sluigi * link template. 12261413Sluigi */ 123204591Sluigistruct dn_link { 124204591Sluigi struct dn_id oid; 12561413Sluigi 126206845Sluigi /* 127204591Sluigi * Userland sets bw and delay in bits/s and milliseconds. 128204591Sluigi * The kernel converts this back and forth to bits/tick and ticks. 129204591Sluigi * XXX what about burst ? 130206845Sluigi */ 131204591Sluigi int32_t link_nr; 132204591Sluigi int bandwidth; /* bit/s or bits/tick. */ 133204591Sluigi int delay; /* ms and ticks */ 134204591Sluigi uint64_t burst; /* scaled. bits*Hz XXX */ 135206845Sluigi}; 13655597Sluigi 13771137Sluigi/* 138204591Sluigi * A flowset, which is a template for flows. Contains parameters 139204591Sluigi * from the command line: id, target scheduler, queue sizes, plr, 140204591Sluigi * flow masks, buckets for the flow hash, and possibly scheduler- 141204591Sluigi * specific parameters (weight, quantum and so on). 14271137Sluigi */ 143204591Sluigistruct dn_fs { 144204591Sluigi struct dn_id oid; 145206845Sluigi uint32_t fs_nr; /* the flowset number */ 146206845Sluigi uint32_t flags; /* userland flags */ 147206845Sluigi int qsize; /* queue size in slots or bytes */ 148206845Sluigi int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ 149204591Sluigi uint32_t buckets; /* buckets used for the queue hash table */ 15061413Sluigi 151206845Sluigi struct ipfw_flow_id flow_mask; 152204591Sluigi uint32_t sched_nr; /* the scheduler we attach to */ 153204591Sluigi /* generic scheduler parameters. Leave them at -1 if unset. 154204591Sluigi * Now we use 0: weight, 1: lmax, 2: priority 155204591Sluigi */ 156204591Sluigi int par[4]; 15796077Sluigi 158204591Sluigi /* RED/GRED parameters. 159204591Sluigi * weight and probabilities are in the range 0..1 represented 160204591Sluigi * in fixed point arithmetic with SCALE_RED decimal bits. 161204591Sluigi */ 162206845Sluigi#define SCALE_RED 16 163206845Sluigi#define SCALE(x) ( (x) << SCALE_RED ) 164206845Sluigi#define SCALE_VAL(x) ( (x) >> SCALE_RED ) 165206845Sluigi#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) 166206845Sluigi int w_q ; /* queue weight (scaled) */ 167206845Sluigi int max_th ; /* maximum threshold for queue (scaled) */ 168206845Sluigi int min_th ; /* minimum threshold for queue (scaled) */ 169206845Sluigi int max_p ; /* maximum value for p_b (scaled) */ 170204591Sluigi 171152910Sglebius}; 17261413Sluigi 17355597Sluigi/* 174204591Sluigi * dn_flow collects flow_id and stats for queues and scheduler 175204591Sluigi * instances, and is used to pass these info to userland. 176204591Sluigi * oid.type/oid.subtype describe the object, oid.id is number 177204591Sluigi * of the parent object. 17855597Sluigi */ 179204591Sluigistruct dn_flow { 180204591Sluigi struct dn_id oid; 181204591Sluigi struct ipfw_flow_id fid; 182204591Sluigi uint64_t tot_pkts; /* statistics counters */ 183204591Sluigi uint64_t tot_bytes; 184239124Sluigi uint32_t length; /* Queue length, in packets */ 185239124Sluigi uint32_t len_bytes; /* Queue length, in bytes */ 186204591Sluigi uint32_t drops; 187204591Sluigi}; 18839119Sluigi 18939119Sluigi 190206845Sluigi/* 191204591Sluigi * Scheduler template, mostly indicating the name, number, 192204591Sluigi * sched_mask and buckets. 193206845Sluigi */ 194204591Sluigistruct dn_sch { 195204591Sluigi struct dn_id oid; 196204591Sluigi uint32_t sched_nr; /* N, scheduler number */ 197204591Sluigi uint32_t buckets; /* number of buckets for the instances */ 198204591Sluigi uint32_t flags; /* have_mask, ... */ 19961413Sluigi 200204591Sluigi char name[16]; /* null terminated */ 201204591Sluigi /* mask to select the appropriate scheduler instance */ 202204591Sluigi struct ipfw_flow_id sched_mask; /* M */ 203204591Sluigi}; 204190865Sluigi 205204591Sluigi 206204591Sluigi/* A delay profile is attached to a link. 207204591Sluigi * Note that a profile, as any other object, cannot be longer than 2^16 208204591Sluigi */ 209204591Sluigi#define ED_MAX_SAMPLES_NO 1024 210204591Sluigistruct dn_profile { 211204591Sluigi struct dn_id oid; 212206845Sluigi /* fields to simulate a delay profile */ 213190865Sluigi#define ED_MAX_NAME_LEN 32 214206845Sluigi char name[ED_MAX_NAME_LEN]; 215206845Sluigi int link_nr; 216206845Sluigi int loss_level; 217206845Sluigi int bandwidth; // XXX use link bandwidth? 218206845Sluigi int samples_no; /* actual len of samples[] */ 219206845Sluigi int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */ 22039119Sluigi}; 221190865Sluigi 222300779Struckman#ifdef NEW_AQM 223300779Struckman/* Extra parameters for AQM and scheduler. 224300779Struckman * This struct is used to pass and retrieve parameters (configurations) 225300779Struckman * to/from AQM and Scheduler. 226300779Struckman */ 227300779Struckmanstruct dn_extra_parms { 228300779Struckman struct dn_id oid; 229300779Struckman char name[16]; 230300779Struckman uint32_t nr; 231300779Struckman#define DN_MAX_EXTRA_PARM 10 232300779Struckman int64_t par[DN_MAX_EXTRA_PARM]; 233300779Struckman}; 234300779Struckman#endif 235204591Sluigi 236204591Sluigi/* 237204591Sluigi * Overall structure of dummynet 238204591Sluigi 239204591SluigiIn dummynet, packets are selected with the firewall rules, and passed 240204591Sluigito two different objects: PIPE or QUEUE (bad name). 241204591Sluigi 242204591SluigiA QUEUE defines a classifier, which groups packets into flows 243204591Sluigiaccording to a 'mask', puts them into independent queues (one 244204591Sluigiper flow) with configurable size and queue management policy, 245204591Sluigiand passes flows to a scheduler: 246204591Sluigi 247204591Sluigi (flow_mask|sched_mask) sched_mask 248204591Sluigi +---------+ weight Wx +-------------+ 249204591Sluigi | |->-[flow]-->--| |-+ 250204591Sluigi -->--| QUEUE x | ... | | | 251204591Sluigi | |->-[flow]-->--| SCHEDuler N | | 252204591Sluigi +---------+ | | | 253204591Sluigi ... | +--[LINK N]-->-- 254204591Sluigi +---------+ weight Wy | | +--[LINK N]-->-- 255204591Sluigi | |->-[flow]-->--| | | 256204591Sluigi -->--| QUEUE y | ... | | | 257204591Sluigi | |->-[flow]-->--| | | 258204591Sluigi +---------+ +-------------+ | 259204591Sluigi +-------------+ 260204591Sluigi 261204591SluigiMany QUEUE objects can connect to the same scheduler, each 262204591SluigiQUEUE object can have its own set of parameters. 263204591Sluigi 264204591SluigiIn turn, the SCHEDuler 'forks' multiple instances according 265204591Sluigito a 'sched_mask', each instance manages its own set of queues 266204591Sluigiand transmits on a private instance of a configurable LINK. 267204591Sluigi 268204591SluigiA PIPE is a simplified version of the above, where there 269204591Sluigiis no flow_mask, and each scheduler instance handles a single queue. 270204591Sluigi 271204591SluigiThe following data structures (visible from userland) describe 272204591Sluigithe objects used by dummynet: 273204591Sluigi 274204591Sluigi + dn_link, contains the main configuration parameters related 275204591Sluigi to delay and bandwidth; 276204591Sluigi + dn_profile describes a delay profile; 277204591Sluigi + dn_flow describes the flow status (flow id, statistics) 278204591Sluigi 279204591Sluigi + dn_sch describes a scheduler 280204591Sluigi + dn_fs describes a flowset (msk, weight, queue parameters) 281204591Sluigi 282204591Sluigi * 283190865Sluigi */ 284190865Sluigi 28539119Sluigi#endif /* _IP_DUMMYNET_H */ 286