Changeset View
Changeset View
Standalone View
Standalone View
sbin/ipfw15/include15/netinet/ip_dummynet15.h
- This file was added.
| /*- | |||||
| * SPDX-License-Identifier: BSD-2-Clause | |||||
| * | |||||
| * Copyright (c) 1998-2010 Luigi Rizzo, Universita` di Pisa | |||||
| * Portions Copyright (c) 2000 Akamba Corp. | |||||
| * All rights reserved | |||||
| * | |||||
| * Redistribution and use in source and binary forms, with or without | |||||
| * modification, are permitted provided that the following conditions | |||||
| * are met: | |||||
| * 1. Redistributions of source code must retain the above copyright | |||||
| * notice, this list of conditions and the following disclaimer. | |||||
| * 2. Redistributions in binary form must reproduce the above copyright | |||||
| * notice, this list of conditions and the following disclaimer in the | |||||
| * documentation and/or other materials provided with the distribution. | |||||
| * | |||||
| * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
| * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
| * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
| * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
| * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
| * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
| * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
| * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
| * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
| * SUCH DAMAGE. | |||||
| */ | |||||
| #ifndef _IP_DUMMYNET_H | |||||
| #define _IP_DUMMYNET_H | |||||
| #define NEW_AQM | |||||
| /* | |||||
| * Definition of the kernel-userland API for dummynet. | |||||
| * | |||||
| * Setsockopt() and getsockopt() pass a batch of objects, each | |||||
| * of them starting with a "struct dn_id" which should fully identify | |||||
| * the object and its relation with others in the sequence. | |||||
| * The first object in each request should have | |||||
| * type= DN_CMD_*, id = DN_API_VERSION. | |||||
| * For other objects, type and subtype specify the object, len indicates | |||||
| * the total length including the header, and 'id' identifies the specific | |||||
| * object. | |||||
| * | |||||
| * Most objects are numbered with an identifier in the range 1..65535. | |||||
| * DN_MAX_ID indicates the first value outside the range. | |||||
| */ | |||||
| #define DN_API_VERSION 12500000 | |||||
| #define DN_MAX_ID 0x10000 | |||||
| struct dn_id { | |||||
| uint16_t len; /* total obj len including this header */ | |||||
| uint8_t type; | |||||
| uint8_t subtype; | |||||
| uint32_t id; /* generic id */ | |||||
| }; | |||||
| /* | |||||
| * These values are in the type field of struct dn_id. | |||||
| * To preserve the ABI, never rearrange the list or delete | |||||
| * entries with the exception of DN_LAST | |||||
| */ | |||||
| enum { | |||||
| DN_NONE = 0, | |||||
| DN_LINK = 1, | |||||
| DN_FS, | |||||
| DN_SCH, | |||||
| DN_SCH_I, | |||||
| DN_QUEUE, | |||||
| DN_DELAY_LINE, | |||||
| DN_PROFILE, | |||||
| DN_FLOW, /* struct dn_flow */ | |||||
| DN_TEXT, /* opaque text is the object */ | |||||
| DN_CMD_CONFIG = 0x80, /* objects follow */ | |||||
| DN_CMD_DELETE, /* subtype + list of entries */ | |||||
| DN_CMD_GET, /* subtype + list of entries */ | |||||
| DN_CMD_FLUSH, | |||||
| /* for compatibility with FreeBSD 7.2/8 */ | |||||
| DN_COMPAT_PIPE, | |||||
| DN_COMPAT_QUEUE, | |||||
| DN_GET_COMPAT, | |||||
| /* special commands for emulation of sysctl variables */ | |||||
| DN_SYSCTL_GET, | |||||
| DN_SYSCTL_SET, | |||||
| #ifdef NEW_AQM | |||||
| /* subtypes used for setting/getting extra parameters. | |||||
| * these subtypes used with IP_DUMMYNET3 command (get) | |||||
| * and DN_TEXT (set). */ | |||||
| DN_AQM_PARAMS, /* AQM extra params */ | |||||
| DN_SCH_PARAMS, /* scheduler extra params */ | |||||
| #endif | |||||
| DN_LAST, | |||||
| }; | |||||
| enum { /* subtype for schedulers, flowset and the like */ | |||||
| DN_SCHED_UNKNOWN = 0, | |||||
| DN_SCHED_FIFO = 1, | |||||
| DN_SCHED_WF2QP = 2, | |||||
| /* others are in individual modules */ | |||||
| }; | |||||
| enum { /* user flags */ | |||||
| DN_HAVE_MASK = 0x0001, /* fs or sched has a mask */ | |||||
| DN_NOERROR = 0x0002, /* do not report errors */ | |||||
| DN_QHT_HASH = 0x0004, /* qht is a hash table */ | |||||
| DN_QSIZE_BYTES = 0x0008, /* queue size is in bytes */ | |||||
| DN_HAS_PROFILE = 0x0010, /* a link has a profile */ | |||||
| DN_IS_RED = 0x0020, | |||||
| DN_IS_GENTLE_RED= 0x0040, | |||||
| DN_IS_ECN = 0x0080, | |||||
| #ifdef NEW_AQM | |||||
| DN_IS_AQM = 0x0100, /* AQMs: e.g Codel & PIE */ | |||||
| #endif | |||||
| DN_PIPE_CMD = 0x1000, /* pipe config... */ | |||||
| }; | |||||
| /* | |||||
| * link template. | |||||
| */ | |||||
| struct dn_link { | |||||
| struct dn_id oid; | |||||
| /* | |||||
| * Userland sets bw and delay in bits/s and milliseconds. | |||||
| * The kernel converts this back and forth to bits/tick and ticks. | |||||
| * XXX what about burst ? | |||||
| */ | |||||
| int32_t link_nr; | |||||
| uint32_t bandwidth; /* bit/s or bits/tick. */ | |||||
| int delay; /* ms and ticks */ | |||||
| uint64_t burst; /* scaled. bits*Hz XXX */ | |||||
| }; | |||||
| /* | |||||
| * A flowset, which is a template for flows. Contains parameters | |||||
| * from the command line: id, target scheduler, queue sizes, plr, | |||||
| * flow masks, buckets for the flow hash, and possibly scheduler- | |||||
| * specific parameters (weight, quantum and so on). | |||||
| */ | |||||
| struct dn_fs { | |||||
| struct dn_id oid; | |||||
| uint32_t fs_nr; /* the flowset number */ | |||||
| uint32_t flags; /* userland flags */ | |||||
| int qsize; /* queue size in slots or bytes */ | |||||
| int32_t pl_state; /* packet loss state */ | |||||
| uint32_t buckets; /* buckets used for the queue hash table */ | |||||
| struct ipfw_flow_id flow_mask; | |||||
| uint32_t sched_nr; /* the scheduler we attach to */ | |||||
| /* generic scheduler parameters. Leave them at -1 if unset. | |||||
| * Now we use 0: weight, 1: lmax, 2: priority | |||||
| */ | |||||
| int par[4]; | |||||
| /* RED/GRED parameters. | |||||
| * weight and probabilities are in the range 0..1 represented | |||||
| * in fixed point arithmetic with SCALE_RED decimal bits. | |||||
| */ | |||||
| #define SCALE_RED 16 | |||||
| #define SCALE(x) ( (x) << SCALE_RED ) | |||||
| #define SCALE_VAL(x) ( (x) >> SCALE_RED ) | |||||
| #define SCALE_MUL(x,y) ( ( (x) * (y) ) >> SCALE_RED ) | |||||
| int w_q ; /* queue weight (scaled) */ | |||||
| int max_th ; /* maximum threshold for queue (scaled) */ | |||||
| int min_th ; /* minimum threshold for queue (scaled) */ | |||||
| int max_p ; /* maximum value for p_b (scaled) */ | |||||
| int32_t plr[4]; /* PLR, pkt loss rate (2^31-1 means 100%) */ | |||||
| }; | |||||
| /* | |||||
| * dn_flow collects flow_id and stats for queues and scheduler | |||||
| * instances, and is used to pass these info to userland. | |||||
| * oid.type/oid.subtype describe the object, oid.id is number | |||||
| * of the parent object. | |||||
| */ | |||||
| struct dn_flow { | |||||
| struct dn_id oid; | |||||
| struct ipfw_flow_id fid; | |||||
| uint64_t tot_pkts; /* statistics counters */ | |||||
| uint64_t tot_bytes; | |||||
| uint32_t length; /* Queue length, in packets */ | |||||
| uint32_t len_bytes; /* Queue length, in bytes */ | |||||
| uint32_t drops; | |||||
| }; | |||||
| /* | |||||
| * Scheduler template, mostly indicating the name, number, | |||||
| * sched_mask and buckets. | |||||
| */ | |||||
| struct dn_sch { | |||||
| struct dn_id oid; | |||||
| uint32_t sched_nr; /* N, scheduler number */ | |||||
| uint32_t buckets; /* number of buckets for the instances */ | |||||
| uint32_t flags; /* have_mask, ... */ | |||||
| char name[16]; /* null terminated */ | |||||
| /* mask to select the appropriate scheduler instance */ | |||||
| struct ipfw_flow_id sched_mask; /* M */ | |||||
| }; | |||||
| /* A delay profile is attached to a link. | |||||
| * Note that a profile, as any other object, cannot be longer than 2^16 | |||||
| */ | |||||
| #define ED_MAX_SAMPLES_NO 1024 | |||||
| struct dn_profile { | |||||
| struct dn_id oid; | |||||
| /* fields to simulate a delay profile */ | |||||
| #define ED_MAX_NAME_LEN 32 | |||||
| char name[ED_MAX_NAME_LEN]; | |||||
| int link_nr; | |||||
| int loss_level; | |||||
| uint32_t bandwidth; // XXX use link bandwidth? | |||||
| int samples_no; /* actual len of samples[] */ | |||||
| int samples[ED_MAX_SAMPLES_NO]; /* may be shorter */ | |||||
| }; | |||||
| #ifdef NEW_AQM | |||||
| /* Extra parameters for AQM and scheduler. | |||||
| * This struct is used to pass and retrieve parameters (configurations) | |||||
| * to/from AQM and Scheduler. | |||||
| */ | |||||
| struct dn_extra_parms { | |||||
| struct dn_id oid; | |||||
| char name[16]; | |||||
| uint32_t nr; | |||||
| #define DN_MAX_EXTRA_PARM 10 | |||||
| int64_t par[DN_MAX_EXTRA_PARM]; | |||||
| }; | |||||
| #endif | |||||
| /* | |||||
| * Overall structure of dummynet | |||||
| In dummynet, packets are selected with the firewall rules, and passed | |||||
| to two different objects: PIPE or QUEUE (bad name). | |||||
| A QUEUE defines a classifier, which groups packets into flows | |||||
| according to a 'mask', puts them into independent queues (one | |||||
| per flow) with configurable size and queue management policy, | |||||
| and passes flows to a scheduler: | |||||
| (flow_mask|sched_mask) sched_mask | |||||
| +---------+ weight Wx +-------------+ | |||||
| | |->-[flow]-->--| |-+ | |||||
| -->--| QUEUE x | ... | | | | |||||
| | |->-[flow]-->--| SCHEDuler N | | | |||||
| +---------+ | | | | |||||
| ... | +--[LINK N]-->-- | |||||
| +---------+ weight Wy | | +--[LINK N]-->-- | |||||
| | |->-[flow]-->--| | | | |||||
| -->--| QUEUE y | ... | | | | |||||
| | |->-[flow]-->--| | | | |||||
| +---------+ +-------------+ | | |||||
| +-------------+ | |||||
| Many QUEUE objects can connect to the same scheduler, each | |||||
| QUEUE object can have its own set of parameters. | |||||
| In turn, the SCHEDuler 'forks' multiple instances according | |||||
| to a 'sched_mask', each instance manages its own set of queues | |||||
| and transmits on a private instance of a configurable LINK. | |||||
| A PIPE is a simplified version of the above, where there | |||||
| is no flow_mask, and each scheduler instance handles a single queue. | |||||
| The following data structures (visible from userland) describe | |||||
| the objects used by dummynet: | |||||
| + dn_link, contains the main configuration parameters related | |||||
| to delay and bandwidth; | |||||
| + dn_profile describes a delay profile; | |||||
| + dn_flow describes the flow status (flow id, statistics) | |||||
| + dn_sch describes a scheduler | |||||
| + dn_fs describes a flowset (msk, weight, queue parameters) | |||||
| * | |||||
| */ | |||||
| #endif /* _IP_DUMMYNET_H */ | |||||