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: releng/10.3/sys/netinet/ip_dummynet.h 239124 2012-08-07 07:52:25Z luigi $ 2839119Sluigi */ 2939119Sluigi 3039119Sluigi#ifndef _IP_DUMMYNET_H 3139119Sluigi#define _IP_DUMMYNET_H 3239119Sluigi 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, 88204591Sluigi 89204591Sluigi DN_LAST, 90206845Sluigi}; 9155597Sluigi 92204591Sluigienum { /* subtype for schedulers, flowset and the like */ 93204591Sluigi DN_SCHED_UNKNOWN = 0, 94204591Sluigi DN_SCHED_FIFO = 1, 95204591Sluigi DN_SCHED_WF2QP = 2, 96204591Sluigi /* others are in individual modules */ 97206845Sluigi}; 9855597Sluigi 99204591Sluigienum { /* user flags */ 100204591Sluigi DN_HAVE_MASK = 0x0001, /* fs or sched has a mask */ 101204591Sluigi DN_NOERROR = 0x0002, /* do not report errors */ 102204591Sluigi DN_QHT_HASH = 0x0004, /* qht is a hash table */ 103204591Sluigi DN_QSIZE_BYTES = 0x0008, /* queue size is in bytes */ 104204591Sluigi DN_HAS_PROFILE = 0x0010, /* a link has a profile */ 105204591Sluigi DN_IS_RED = 0x0020, 106204591Sluigi DN_IS_GENTLE_RED= 0x0040, 107204591Sluigi DN_PIPE_CMD = 0x1000, /* pipe config... */ 10839119Sluigi}; 10939119Sluigi 11061413Sluigi/* 111204591Sluigi * link template. 11261413Sluigi */ 113204591Sluigistruct dn_link { 114204591Sluigi struct dn_id oid; 11561413Sluigi 116206845Sluigi /* 117204591Sluigi * Userland sets bw and delay in bits/s and milliseconds. 118204591Sluigi * The kernel converts this back and forth to bits/tick and ticks. 119204591Sluigi * XXX what about burst ? 120206845Sluigi */ 121204591Sluigi int32_t link_nr; 122204591Sluigi int bandwidth; /* bit/s or bits/tick. */ 123204591Sluigi int delay; /* ms and ticks */ 124204591Sluigi uint64_t burst; /* scaled. bits*Hz XXX */ 125206845Sluigi}; 12655597Sluigi 12771137Sluigi/* 128204591Sluigi * A flowset, which is a template for flows. Contains parameters 129204591Sluigi * from the command line: id, target scheduler, queue sizes, plr, 130204591Sluigi * flow masks, buckets for the flow hash, and possibly scheduler- 131204591Sluigi * specific parameters (weight, quantum and so on). 13271137Sluigi */ 133204591Sluigistruct dn_fs { 134204591Sluigi struct dn_id oid; 135206845Sluigi uint32_t fs_nr; /* the flowset number */ 136206845Sluigi uint32_t flags; /* userland flags */ 137206845Sluigi int qsize; /* queue size in slots or bytes */ 138206845Sluigi int32_t plr; /* PLR, pkt loss rate (2^31-1 means 100%) */ 139204591Sluigi uint32_t buckets; /* buckets used for the queue hash table */ 14061413Sluigi 141206845Sluigi struct ipfw_flow_id flow_mask; 142204591Sluigi uint32_t sched_nr; /* the scheduler we attach to */ 143204591Sluigi /* generic scheduler parameters. Leave them at -1 if unset. 144204591Sluigi * Now we use 0: weight, 1: lmax, 2: priority 145204591Sluigi */ 146204591Sluigi int par[4]; 14796077Sluigi 148204591Sluigi /* RED/GRED parameters. 149204591Sluigi * weight and probabilities are in the range 0..1 represented 150204591Sluigi * in fixed point arithmetic with SCALE_RED decimal bits. 151204591Sluigi */ 152206845Sluigi#define SCALE_RED 16 153206845Sluigi#define SCALE(x) ( (x) << SCALE_RED ) 154206845Sluigi#define SCALE_VAL(x) ( (x) >> SCALE_RED ) 155206845Sluigi#define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) 156206845Sluigi int w_q ; /* queue weight (scaled) */ 157206845Sluigi int max_th ; /* maximum threshold for queue (scaled) */ 158206845Sluigi int min_th ; /* minimum threshold for queue (scaled) */ 159206845Sluigi int max_p ; /* maximum value for p_b (scaled) */ 160204591Sluigi 161152910Sglebius}; 16261413Sluigi 16355597Sluigi/* 164204591Sluigi * dn_flow collects flow_id and stats for queues and scheduler 165204591Sluigi * instances, and is used to pass these info to userland. 166204591Sluigi * oid.type/oid.subtype describe the object, oid.id is number 167204591Sluigi * of the parent object. 16855597Sluigi */ 169204591Sluigistruct dn_flow { 170204591Sluigi struct dn_id oid; 171204591Sluigi struct ipfw_flow_id fid; 172204591Sluigi uint64_t tot_pkts; /* statistics counters */ 173204591Sluigi uint64_t tot_bytes; 174239124Sluigi uint32_t length; /* Queue length, in packets */ 175239124Sluigi uint32_t len_bytes; /* Queue length, in bytes */ 176204591Sluigi uint32_t drops; 177204591Sluigi}; 17839119Sluigi 17939119Sluigi 180206845Sluigi/* 181204591Sluigi * Scheduler template, mostly indicating the name, number, 182204591Sluigi * sched_mask and buckets. 183206845Sluigi */ 184204591Sluigistruct dn_sch { 185204591Sluigi struct dn_id oid; 186204591Sluigi uint32_t sched_nr; /* N, scheduler number */ 187204591Sluigi uint32_t buckets; /* number of buckets for the instances */ 188204591Sluigi uint32_t flags; /* have_mask, ... */ 18961413Sluigi 190204591Sluigi char name[16]; /* null terminated */ 191204591Sluigi /* mask to select the appropriate scheduler instance */ 192204591Sluigi struct ipfw_flow_id sched_mask; /* M */ 193204591Sluigi}; 194190865Sluigi 195204591Sluigi 196204591Sluigi/* A delay profile is attached to a link. 197204591Sluigi * Note that a profile, as any other object, cannot be longer than 2^16 198204591Sluigi */ 199204591Sluigi#define ED_MAX_SAMPLES_NO 1024 200204591Sluigistruct dn_profile { 201204591Sluigi struct dn_id oid; 202206845Sluigi /* fields to simulate a delay profile */ 203190865Sluigi#define ED_MAX_NAME_LEN 32 204206845Sluigi char name[ED_MAX_NAME_LEN]; 205206845Sluigi int link_nr; 206206845Sluigi int loss_level; 207206845Sluigi int bandwidth; // XXX use link bandwidth? 208206845Sluigi int samples_no; /* actual len of samples[] */ 209206845Sluigi int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */ 21039119Sluigi}; 211190865Sluigi 212204591Sluigi 213204591Sluigi 214204591Sluigi/* 215204591Sluigi * Overall structure of dummynet 216204591Sluigi 217204591SluigiIn dummynet, packets are selected with the firewall rules, and passed 218204591Sluigito two different objects: PIPE or QUEUE (bad name). 219204591Sluigi 220204591SluigiA QUEUE defines a classifier, which groups packets into flows 221204591Sluigiaccording to a 'mask', puts them into independent queues (one 222204591Sluigiper flow) with configurable size and queue management policy, 223204591Sluigiand passes flows to a scheduler: 224204591Sluigi 225204591Sluigi (flow_mask|sched_mask) sched_mask 226204591Sluigi +---------+ weight Wx +-------------+ 227204591Sluigi | |->-[flow]-->--| |-+ 228204591Sluigi -->--| QUEUE x | ... | | | 229204591Sluigi | |->-[flow]-->--| SCHEDuler N | | 230204591Sluigi +---------+ | | | 231204591Sluigi ... | +--[LINK N]-->-- 232204591Sluigi +---------+ weight Wy | | +--[LINK N]-->-- 233204591Sluigi | |->-[flow]-->--| | | 234204591Sluigi -->--| QUEUE y | ... | | | 235204591Sluigi | |->-[flow]-->--| | | 236204591Sluigi +---------+ +-------------+ | 237204591Sluigi +-------------+ 238204591Sluigi 239204591SluigiMany QUEUE objects can connect to the same scheduler, each 240204591SluigiQUEUE object can have its own set of parameters. 241204591Sluigi 242204591SluigiIn turn, the SCHEDuler 'forks' multiple instances according 243204591Sluigito a 'sched_mask', each instance manages its own set of queues 244204591Sluigiand transmits on a private instance of a configurable LINK. 245204591Sluigi 246204591SluigiA PIPE is a simplified version of the above, where there 247204591Sluigiis no flow_mask, and each scheduler instance handles a single queue. 248204591Sluigi 249204591SluigiThe following data structures (visible from userland) describe 250204591Sluigithe objects used by dummynet: 251204591Sluigi 252204591Sluigi + dn_link, contains the main configuration parameters related 253204591Sluigi to delay and bandwidth; 254204591Sluigi + dn_profile describes a delay profile; 255204591Sluigi + dn_flow describes the flow status (flow id, statistics) 256204591Sluigi 257204591Sluigi + dn_sch describes a scheduler 258204591Sluigi + dn_fs describes a flowset (msk, weight, queue parameters) 259204591Sluigi 260204591Sluigi * 261190865Sluigi */ 262190865Sluigi 26339119Sluigi#endif /* _IP_DUMMYNET_H */ 264