1*aca3beaaSApple OSS Distributions /* 2*aca3beaaSApple OSS Distributions * Copyright (c) 2000-2021 Apple Inc. All rights reserved. 3*aca3beaaSApple OSS Distributions * 4*aca3beaaSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ 5*aca3beaaSApple OSS Distributions * 6*aca3beaaSApple OSS Distributions * This file contains Original Code and/or Modifications of Original Code 7*aca3beaaSApple OSS Distributions * as defined in and that are subject to the Apple Public Source License 8*aca3beaaSApple OSS Distributions * Version 2.0 (the 'License'). You may not use this file except in 9*aca3beaaSApple OSS Distributions * compliance with the License. The rights granted to you under the License 10*aca3beaaSApple OSS Distributions * may not be used to create, or enable the creation or redistribution of, 11*aca3beaaSApple OSS Distributions * unlawful or unlicensed copies of an Apple operating system, or to 12*aca3beaaSApple OSS Distributions * circumvent, violate, or enable the circumvention or violation of, any 13*aca3beaaSApple OSS Distributions * terms of an Apple operating system software license agreement. 14*aca3beaaSApple OSS Distributions * 15*aca3beaaSApple OSS Distributions * Please obtain a copy of the License at 16*aca3beaaSApple OSS Distributions * http://www.opensource.apple.com/apsl/ and read it before using this file. 17*aca3beaaSApple OSS Distributions * 18*aca3beaaSApple OSS Distributions * The Original Code and all software distributed under the License are 19*aca3beaaSApple OSS Distributions * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 20*aca3beaaSApple OSS Distributions * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 21*aca3beaaSApple OSS Distributions * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 22*aca3beaaSApple OSS Distributions * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 23*aca3beaaSApple OSS Distributions * Please see the License for the specific language governing rights and 24*aca3beaaSApple OSS Distributions * limitations under the License. 25*aca3beaaSApple OSS Distributions * 26*aca3beaaSApple OSS Distributions * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ 27*aca3beaaSApple OSS Distributions */ 28*aca3beaaSApple OSS Distributions /* 29*aca3beaaSApple OSS Distributions * Copyright (c) 1998-2002 Luigi Rizzo, Universita` di Pisa 30*aca3beaaSApple OSS Distributions * Portions Copyright (c) 2000 Akamba Corp. 31*aca3beaaSApple OSS Distributions * All rights reserved 32*aca3beaaSApple OSS Distributions * 33*aca3beaaSApple OSS Distributions * Redistribution and use in source and binary forms, with or without 34*aca3beaaSApple OSS Distributions * modification, are permitted provided that the following conditions 35*aca3beaaSApple OSS Distributions * are met: 36*aca3beaaSApple OSS Distributions * 1. Redistributions of source code must retain the above copyright 37*aca3beaaSApple OSS Distributions * notice, this list of conditions and the following disclaimer. 38*aca3beaaSApple OSS Distributions * 2. Redistributions in binary form must reproduce the above copyright 39*aca3beaaSApple OSS Distributions * notice, this list of conditions and the following disclaimer in the 40*aca3beaaSApple OSS Distributions * documentation and/or other materials provided with the distribution. 41*aca3beaaSApple OSS Distributions * 42*aca3beaaSApple OSS Distributions * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 43*aca3beaaSApple OSS Distributions * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 44*aca3beaaSApple OSS Distributions * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 45*aca3beaaSApple OSS Distributions * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 46*aca3beaaSApple OSS Distributions * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 47*aca3beaaSApple OSS Distributions * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 48*aca3beaaSApple OSS Distributions * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 49*aca3beaaSApple OSS Distributions * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 50*aca3beaaSApple OSS Distributions * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 51*aca3beaaSApple OSS Distributions * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 52*aca3beaaSApple OSS Distributions * SUCH DAMAGE. 53*aca3beaaSApple OSS Distributions * 54*aca3beaaSApple OSS Distributions * $FreeBSD: src/sys/netinet/ip_dummynet.h,v 1.32 2004/08/17 22:05:54 andre Exp $ 55*aca3beaaSApple OSS Distributions */ 56*aca3beaaSApple OSS Distributions 57*aca3beaaSApple OSS Distributions #ifndef _IP_DUMMYNET_H 58*aca3beaaSApple OSS Distributions #define _IP_DUMMYNET_H 59*aca3beaaSApple OSS Distributions 60*aca3beaaSApple OSS Distributions #include <sys/appleapiopts.h> 61*aca3beaaSApple OSS Distributions 62*aca3beaaSApple OSS Distributions #ifdef PRIVATE 63*aca3beaaSApple OSS Distributions #include <netinet/ip_flowid.h> 64*aca3beaaSApple OSS Distributions 65*aca3beaaSApple OSS Distributions /* Apply ipv6 mask on ipv6 addr */ 66*aca3beaaSApple OSS Distributions #define APPLY_MASK(addr, mask) \ 67*aca3beaaSApple OSS Distributions (addr)->__u6_addr.__u6_addr32[0] &= (mask)->__u6_addr.__u6_addr32[0]; \ 68*aca3beaaSApple OSS Distributions (addr)->__u6_addr.__u6_addr32[1] &= (mask)->__u6_addr.__u6_addr32[1]; \ 69*aca3beaaSApple OSS Distributions (addr)->__u6_addr.__u6_addr32[2] &= (mask)->__u6_addr.__u6_addr32[2]; \ 70*aca3beaaSApple OSS Distributions (addr)->__u6_addr.__u6_addr32[3] &= (mask)->__u6_addr.__u6_addr32[3]; 71*aca3beaaSApple OSS Distributions 72*aca3beaaSApple OSS Distributions /* 73*aca3beaaSApple OSS Distributions * Definition of dummynet data structures. In the structures, I decided 74*aca3beaaSApple OSS Distributions * not to use the macros in <sys/queue.h> in the hope of making the code 75*aca3beaaSApple OSS Distributions * easier to port to other architectures. The type of lists and queue we 76*aca3beaaSApple OSS Distributions * use here is pretty simple anyways. 77*aca3beaaSApple OSS Distributions */ 78*aca3beaaSApple OSS Distributions 79*aca3beaaSApple OSS Distributions /* 80*aca3beaaSApple OSS Distributions * We start with a heap, which is used in the scheduler to decide when 81*aca3beaaSApple OSS Distributions * to transmit packets etc. 82*aca3beaaSApple OSS Distributions * 83*aca3beaaSApple OSS Distributions * The key for the heap is used for two different values: 84*aca3beaaSApple OSS Distributions * 85*aca3beaaSApple OSS Distributions * 1. timer ticks- max 10K/second, so 32 bits are enough; 86*aca3beaaSApple OSS Distributions * 87*aca3beaaSApple OSS Distributions * 2. virtual times. These increase in steps of len/x, where len is the 88*aca3beaaSApple OSS Distributions * packet length, and x is either the weight of the flow, or the 89*aca3beaaSApple OSS Distributions * sum of all weights. 90*aca3beaaSApple OSS Distributions * If we limit to max 1000 flows and a max weight of 100, then 91*aca3beaaSApple OSS Distributions * x needs 17 bits. The packet size is 16 bits, so we can easily 92*aca3beaaSApple OSS Distributions * overflow if we do not allow errors. 93*aca3beaaSApple OSS Distributions * So we use a key "dn_key" which is 64 bits. Some macros are used to 94*aca3beaaSApple OSS Distributions * compare key values and handle wraparounds. 95*aca3beaaSApple OSS Distributions * MAX64 returns the largest of two key values. 96*aca3beaaSApple OSS Distributions * MY_M is used as a shift count when doing fixed point arithmetic 97*aca3beaaSApple OSS Distributions * (a better name would be useful...). 98*aca3beaaSApple OSS Distributions */ 99*aca3beaaSApple OSS Distributions typedef u_int64_t dn_key; /* sorting key */ 100*aca3beaaSApple OSS Distributions #define DN_KEY_LT(a, b) ((int64_t)((a)-(b)) < 0) 101*aca3beaaSApple OSS Distributions #define DN_KEY_LEQ(a, b) ((int64_t)((a)-(b)) <= 0) 102*aca3beaaSApple OSS Distributions #define DN_KEY_GT(a, b) ((int64_t)((a)-(b)) > 0) 103*aca3beaaSApple OSS Distributions #define DN_KEY_GEQ(a, b) ((int64_t)((a)-(b)) >= 0) 104*aca3beaaSApple OSS Distributions #define MAX64(x, y) (( (int64_t) ( (y)-(x) )) > 0 ) ? (y) : (x) 105*aca3beaaSApple OSS Distributions #define MY_M 16 /* number of left shift to obtain a larger precision */ 106*aca3beaaSApple OSS Distributions 107*aca3beaaSApple OSS Distributions /* 108*aca3beaaSApple OSS Distributions * XXX With this scaling, max 1000 flows, max weight 100, 1Gbit/s, the 109*aca3beaaSApple OSS Distributions * virtual time wraps every 15 days. 110*aca3beaaSApple OSS Distributions */ 111*aca3beaaSApple OSS Distributions 112*aca3beaaSApple OSS Distributions /* 113*aca3beaaSApple OSS Distributions * The maximum hash table size for queues. This value must be a power 114*aca3beaaSApple OSS Distributions * of 2. 115*aca3beaaSApple OSS Distributions */ 116*aca3beaaSApple OSS Distributions #define DN_MAX_HASH_SIZE 65536 117*aca3beaaSApple OSS Distributions 118*aca3beaaSApple OSS Distributions /* 119*aca3beaaSApple OSS Distributions * A heap entry is made of a key and a pointer to the actual 120*aca3beaaSApple OSS Distributions * object stored in the heap. 121*aca3beaaSApple OSS Distributions * The heap is an array of dn_heap_entry entries, dynamically allocated. 122*aca3beaaSApple OSS Distributions * Current size is "size", with "elements" actually in use. 123*aca3beaaSApple OSS Distributions * The heap normally supports only ordered insert and extract from the top. 124*aca3beaaSApple OSS Distributions * If we want to extract an object from the middle of the heap, we 125*aca3beaaSApple OSS Distributions * have to know where the object itself is located in the heap (or we 126*aca3beaaSApple OSS Distributions * need to scan the whole array). To this purpose, an object has a 127*aca3beaaSApple OSS Distributions * field (int) which contains the index of the object itself into the 128*aca3beaaSApple OSS Distributions * heap. When the object is moved, the field must also be updated. 129*aca3beaaSApple OSS Distributions * The offset of the index in the object is stored in the 'offset' 130*aca3beaaSApple OSS Distributions * field in the heap descriptor. The assumption is that this offset 131*aca3beaaSApple OSS Distributions * is non-zero if we want to support extract from the middle. 132*aca3beaaSApple OSS Distributions */ 133*aca3beaaSApple OSS Distributions struct dn_heap_entry { 134*aca3beaaSApple OSS Distributions dn_key key; /* sorting key. Topmost element is smallest one */ 135*aca3beaaSApple OSS Distributions void *object; /* object pointer */ 136*aca3beaaSApple OSS Distributions }; 137*aca3beaaSApple OSS Distributions 138*aca3beaaSApple OSS Distributions struct dn_heap { 139*aca3beaaSApple OSS Distributions int size; 140*aca3beaaSApple OSS Distributions int elements; 141*aca3beaaSApple OSS Distributions int offset; /* XXX if > 0 this is the offset of direct ptr to obj */ 142*aca3beaaSApple OSS Distributions struct dn_heap_entry *p; /* really an array of "size" entries */ 143*aca3beaaSApple OSS Distributions }; 144*aca3beaaSApple OSS Distributions 145*aca3beaaSApple OSS Distributions /* 146*aca3beaaSApple OSS Distributions * Packets processed by dummynet have an mbuf tag associated with 147*aca3beaaSApple OSS Distributions * them that carries their dummynet state. This is used within 148*aca3beaaSApple OSS Distributions * the dummynet code as well as outside when checking for special 149*aca3beaaSApple OSS Distributions * processing requirements. 150*aca3beaaSApple OSS Distributions */ 151*aca3beaaSApple OSS Distributions #ifdef KERNEL 152*aca3beaaSApple OSS Distributions #include <net/if_var.h> 153*aca3beaaSApple OSS Distributions #include <net/route.h> 154*aca3beaaSApple OSS Distributions #include <netinet/ip_var.h> /* for ip_out_args */ 155*aca3beaaSApple OSS Distributions #include <netinet/ip6.h> /* for ip6_out_args */ 156*aca3beaaSApple OSS Distributions #include <netinet/in.h> 157*aca3beaaSApple OSS Distributions #include <netinet6/ip6_var.h> /* for ip6_out_args */ 158*aca3beaaSApple OSS Distributions 159*aca3beaaSApple OSS Distributions struct dn_pkt_tag { 160*aca3beaaSApple OSS Distributions void *dn_pf_rule; /* matching PF rule */ 161*aca3beaaSApple OSS Distributions int dn_dir; /* action when packet comes out. */ 162*aca3beaaSApple OSS Distributions #define DN_TO_IP_OUT 1 163*aca3beaaSApple OSS Distributions #define DN_TO_IP_IN 2 164*aca3beaaSApple OSS Distributions #define DN_TO_BDG_FWD 3 165*aca3beaaSApple OSS Distributions #define DN_TO_IP6_IN 4 166*aca3beaaSApple OSS Distributions #define DN_TO_IP6_OUT 5 167*aca3beaaSApple OSS Distributions dn_key dn_output_time; /* when the pkt is due for delivery */ 168*aca3beaaSApple OSS Distributions struct ifnet *dn_ifp; /* interface, for ip[6]_output */ 169*aca3beaaSApple OSS Distributions union { 170*aca3beaaSApple OSS Distributions struct sockaddr_in _dn_dst; 171*aca3beaaSApple OSS Distributions struct sockaddr_in6 _dn_dst6; 172*aca3beaaSApple OSS Distributions } dn_dst_; 173*aca3beaaSApple OSS Distributions #define dn_dst dn_dst_._dn_dst 174*aca3beaaSApple OSS Distributions #define dn_dst6 dn_dst_._dn_dst6 175*aca3beaaSApple OSS Distributions union { 176*aca3beaaSApple OSS Distributions struct route _dn_ro; /* route, for ip_output. MUST COPY */ 177*aca3beaaSApple OSS Distributions struct route_in6 _dn_ro6;/* route, for ip6_output. MUST COPY */ 178*aca3beaaSApple OSS Distributions } dn_ro_; 179*aca3beaaSApple OSS Distributions #define dn_ro dn_ro_._dn_ro 180*aca3beaaSApple OSS Distributions #define dn_ro6 dn_ro_._dn_ro6 181*aca3beaaSApple OSS Distributions struct route_in6 dn_ro6_pmtu; /* for ip6_output */ 182*aca3beaaSApple OSS Distributions struct ifnet *dn_origifp; /* for ip6_output */ 183*aca3beaaSApple OSS Distributions u_int32_t dn_mtu; /* for ip6_output */ 184*aca3beaaSApple OSS Distributions u_int32_t dn_unfragpartlen; /* for ip6_output */ 185*aca3beaaSApple OSS Distributions struct ip6_exthdrs dn_exthdrs; /* for ip6_output */ 186*aca3beaaSApple OSS Distributions int dn_flags; /* flags, for ip[6]_output */ 187*aca3beaaSApple OSS Distributions union { 188*aca3beaaSApple OSS Distributions struct ip_out_args _dn_ipoa;/* output args, for ip_output. MUST COPY */ 189*aca3beaaSApple OSS Distributions struct ip6_out_args _dn_ip6oa;/* output args, for ip_output. MUST COPY */ 190*aca3beaaSApple OSS Distributions } dn_ipoa_; 191*aca3beaaSApple OSS Distributions #define dn_ipoa dn_ipoa_._dn_ipoa 192*aca3beaaSApple OSS Distributions #define dn_ip6oa dn_ipoa_._dn_ip6oa 193*aca3beaaSApple OSS Distributions }; 194*aca3beaaSApple OSS Distributions #else 195*aca3beaaSApple OSS Distributions struct dn_pkt; 196*aca3beaaSApple OSS Distributions #endif /* KERNEL */ 197*aca3beaaSApple OSS Distributions 198*aca3beaaSApple OSS Distributions /* 199*aca3beaaSApple OSS Distributions * Overall structure of dummynet (with WF2Q+): 200*aca3beaaSApple OSS Distributions * 201*aca3beaaSApple OSS Distributions * In dummynet, packets are selected with the firewall rules, and passed 202*aca3beaaSApple OSS Distributions * to two different objects: PIPE or QUEUE. 203*aca3beaaSApple OSS Distributions * 204*aca3beaaSApple OSS Distributions * A QUEUE is just a queue with configurable size and queue management 205*aca3beaaSApple OSS Distributions * policy. It is also associated with a mask (to discriminate among 206*aca3beaaSApple OSS Distributions * different flows), a weight (used to give different shares of the 207*aca3beaaSApple OSS Distributions * bandwidth to different flows) and a "pipe", which essentially 208*aca3beaaSApple OSS Distributions * supplies the transmit clock for all queues associated with that 209*aca3beaaSApple OSS Distributions * pipe. 210*aca3beaaSApple OSS Distributions * 211*aca3beaaSApple OSS Distributions * A PIPE emulates a fixed-bandwidth link, whose bandwidth is 212*aca3beaaSApple OSS Distributions * configurable. The "clock" for a pipe can come from either an 213*aca3beaaSApple OSS Distributions * internal timer, or from the transmit interrupt of an interface. 214*aca3beaaSApple OSS Distributions * A pipe is also associated with one (or more, if masks are used) 215*aca3beaaSApple OSS Distributions * queue, where all packets for that pipe are stored. 216*aca3beaaSApple OSS Distributions * 217*aca3beaaSApple OSS Distributions * The bandwidth available on the pipe is shared by the queues 218*aca3beaaSApple OSS Distributions * associated with that pipe (only one in case the packet is sent 219*aca3beaaSApple OSS Distributions * to a PIPE) according to the WF2Q+ scheduling algorithm and the 220*aca3beaaSApple OSS Distributions * configured weights. 221*aca3beaaSApple OSS Distributions * 222*aca3beaaSApple OSS Distributions * In general, incoming packets are stored in the appropriate queue, 223*aca3beaaSApple OSS Distributions * which is then placed into one of a few heaps managed by a scheduler 224*aca3beaaSApple OSS Distributions * to decide when the packet should be extracted. 225*aca3beaaSApple OSS Distributions * The scheduler (a function called dummynet()) is run at every timer 226*aca3beaaSApple OSS Distributions * tick, and grabs queues from the head of the heaps when they are 227*aca3beaaSApple OSS Distributions * ready for processing. 228*aca3beaaSApple OSS Distributions * 229*aca3beaaSApple OSS Distributions * There are three data structures definining a pipe and associated queues: 230*aca3beaaSApple OSS Distributions * 231*aca3beaaSApple OSS Distributions + dn_pipe, which contains the main configuration parameters related 232*aca3beaaSApple OSS Distributions + to delay and bandwidth; 233*aca3beaaSApple OSS Distributions + dn_flow_set, which contains WF2Q+ configuration, flow 234*aca3beaaSApple OSS Distributions + masks, plr and RED configuration; 235*aca3beaaSApple OSS Distributions + dn_flow_queue, which is the per-flow queue (containing the packets) 236*aca3beaaSApple OSS Distributions + 237*aca3beaaSApple OSS Distributions + Multiple dn_flow_set can be linked to the same pipe, and multiple 238*aca3beaaSApple OSS Distributions + dn_flow_queue can be linked to the same dn_flow_set. 239*aca3beaaSApple OSS Distributions + All data structures are linked in a linear list which is used for 240*aca3beaaSApple OSS Distributions + housekeeping purposes. 241*aca3beaaSApple OSS Distributions + 242*aca3beaaSApple OSS Distributions + During configuration, we create and initialize the dn_flow_set 243*aca3beaaSApple OSS Distributions + and dn_pipe structures (a dn_pipe also contains a dn_flow_set). 244*aca3beaaSApple OSS Distributions + 245*aca3beaaSApple OSS Distributions + At runtime: packets are sent to the appropriate dn_flow_set (either 246*aca3beaaSApple OSS Distributions + WFQ ones, or the one embedded in the dn_pipe for fixed-rate flows), 247*aca3beaaSApple OSS Distributions + which in turn dispatches them to the appropriate dn_flow_queue 248*aca3beaaSApple OSS Distributions + (created dynamically according to the masks). 249*aca3beaaSApple OSS Distributions + 250*aca3beaaSApple OSS Distributions + The transmit clock for fixed rate flows (ready_event()) selects the 251*aca3beaaSApple OSS Distributions + dn_flow_queue to be used to transmit the next packet. For WF2Q, 252*aca3beaaSApple OSS Distributions + wfq_ready_event() extract a pipe which in turn selects the right 253*aca3beaaSApple OSS Distributions + flow using a number of heaps defined into the pipe itself. 254*aca3beaaSApple OSS Distributions + 255*aca3beaaSApple OSS Distributions * 256*aca3beaaSApple OSS Distributions */ 257*aca3beaaSApple OSS Distributions 258*aca3beaaSApple OSS Distributions /* 259*aca3beaaSApple OSS Distributions * per flow queue. This contains the flow identifier, the queue 260*aca3beaaSApple OSS Distributions * of packets, counters, and parameters used to support both RED and 261*aca3beaaSApple OSS Distributions * WF2Q+. 262*aca3beaaSApple OSS Distributions * 263*aca3beaaSApple OSS Distributions * A dn_flow_queue is created and initialized whenever a packet for 264*aca3beaaSApple OSS Distributions * a new flow arrives. 265*aca3beaaSApple OSS Distributions */ 266*aca3beaaSApple OSS Distributions struct dn_flow_queue { 267*aca3beaaSApple OSS Distributions struct dn_flow_queue *next; 268*aca3beaaSApple OSS Distributions struct ip_flow_id id; 269*aca3beaaSApple OSS Distributions 270*aca3beaaSApple OSS Distributions struct mbuf *head, *tail; /* queue of packets */ 271*aca3beaaSApple OSS Distributions u_int len; 272*aca3beaaSApple OSS Distributions u_int len_bytes; 273*aca3beaaSApple OSS Distributions u_int32_t numbytes; /* credit for transmission (dynamic queues) */ 274*aca3beaaSApple OSS Distributions 275*aca3beaaSApple OSS Distributions u_int64_t tot_pkts; /* statistics counters */ 276*aca3beaaSApple OSS Distributions u_int64_t tot_bytes; 277*aca3beaaSApple OSS Distributions u_int32_t drops; 278*aca3beaaSApple OSS Distributions 279*aca3beaaSApple OSS Distributions int hash_slot; /* debugging/diagnostic */ 280*aca3beaaSApple OSS Distributions 281*aca3beaaSApple OSS Distributions /* RED parameters */ 282*aca3beaaSApple OSS Distributions int avg; /* average queue length est. (scaled) */ 283*aca3beaaSApple OSS Distributions int count; /* arrivals since last RED drop */ 284*aca3beaaSApple OSS Distributions int random; /* random value (scaled) */ 285*aca3beaaSApple OSS Distributions u_int64_t q_time; /* start of queue idle time */ 286*aca3beaaSApple OSS Distributions 287*aca3beaaSApple OSS Distributions /* WF2Q+ support */ 288*aca3beaaSApple OSS Distributions struct dn_flow_set *fs; /* parent flow set */ 289*aca3beaaSApple OSS Distributions int heap_pos; /* position (index) of struct in heap */ 290*aca3beaaSApple OSS Distributions dn_key sched_time; /* current time when queue enters ready_heap */ 291*aca3beaaSApple OSS Distributions 292*aca3beaaSApple OSS Distributions dn_key S, F; /* start time, finish time */ 293*aca3beaaSApple OSS Distributions /* 294*aca3beaaSApple OSS Distributions * Setting F < S means the timestamp is invalid. We only need 295*aca3beaaSApple OSS Distributions * to test this when the queue is empty. 296*aca3beaaSApple OSS Distributions */ 297*aca3beaaSApple OSS Distributions }; 298*aca3beaaSApple OSS Distributions 299*aca3beaaSApple OSS Distributions /* 300*aca3beaaSApple OSS Distributions * flow_set descriptor. Contains the "template" parameters for the 301*aca3beaaSApple OSS Distributions * queue configuration, and pointers to the hash table of dn_flow_queue's. 302*aca3beaaSApple OSS Distributions * 303*aca3beaaSApple OSS Distributions * The hash table is an array of lists -- we identify the slot by 304*aca3beaaSApple OSS Distributions * hashing the flow-id, then scan the list looking for a match. 305*aca3beaaSApple OSS Distributions * The size of the hash table (buckets) is configurable on a per-queue 306*aca3beaaSApple OSS Distributions * basis. 307*aca3beaaSApple OSS Distributions * 308*aca3beaaSApple OSS Distributions * A dn_flow_set is created whenever a new queue or pipe is created (in the 309*aca3beaaSApple OSS Distributions * latter case, the structure is located inside the struct dn_pipe). 310*aca3beaaSApple OSS Distributions */ 311*aca3beaaSApple OSS Distributions struct dn_flow_set { 312*aca3beaaSApple OSS Distributions SLIST_ENTRY(dn_flow_set) next;/* linked list in a hash slot */ 313*aca3beaaSApple OSS Distributions 314*aca3beaaSApple OSS Distributions u_short fs_nr; /* flow_set number */ 315*aca3beaaSApple OSS Distributions u_short flags_fs; 316*aca3beaaSApple OSS Distributions #define DN_HAVE_FLOW_MASK 0x0001 317*aca3beaaSApple OSS Distributions #define DN_IS_RED 0x0002 318*aca3beaaSApple OSS Distributions #define DN_IS_GENTLE_RED 0x0004 319*aca3beaaSApple OSS Distributions #define DN_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */ 320*aca3beaaSApple OSS Distributions #define DN_NOERROR 0x0010 /* do not report ENOBUFS on drops */ 321*aca3beaaSApple OSS Distributions #define DN_IS_PIPE 0x4000 322*aca3beaaSApple OSS Distributions #define DN_IS_QUEUE 0x8000 323*aca3beaaSApple OSS Distributions 324*aca3beaaSApple OSS Distributions struct dn_pipe *pipe; /* pointer to parent pipe */ 325*aca3beaaSApple OSS Distributions u_short parent_nr; /* parent pipe#, 0 if local to a pipe */ 326*aca3beaaSApple OSS Distributions 327*aca3beaaSApple OSS Distributions int weight; /* WFQ queue weight */ 328*aca3beaaSApple OSS Distributions int qsize; /* queue size in slots or bytes */ 329*aca3beaaSApple OSS Distributions int plr; /* pkt loss rate (2^31-1 means 100%) */ 330*aca3beaaSApple OSS Distributions 331*aca3beaaSApple OSS Distributions struct ip_flow_id flow_mask; 332*aca3beaaSApple OSS Distributions 333*aca3beaaSApple OSS Distributions /* hash table of queues onto this flow_set */ 334*aca3beaaSApple OSS Distributions int rq_size; /* number of slots */ 335*aca3beaaSApple OSS Distributions int rq_elements; /* active elements */ 336*aca3beaaSApple OSS Distributions struct dn_flow_queue **rq; /* array of rq_size entries */ 337*aca3beaaSApple OSS Distributions 338*aca3beaaSApple OSS Distributions u_int32_t last_expired; /* do not expire too frequently */ 339*aca3beaaSApple OSS Distributions int backlogged; /* #active queues for this flowset */ 340*aca3beaaSApple OSS Distributions 341*aca3beaaSApple OSS Distributions /* RED parameters */ 342*aca3beaaSApple OSS Distributions #define SCALE_RED 16 343*aca3beaaSApple OSS Distributions #define SCALE(x) ( (x) << SCALE_RED ) 344*aca3beaaSApple OSS Distributions #define SCALE_VAL(x) ( (x) >> SCALE_RED ) 345*aca3beaaSApple OSS Distributions #define SCALE_MUL(x, y) ( ( (x) * (y) ) >> SCALE_RED ) 346*aca3beaaSApple OSS Distributions int w_q; /* queue weight (scaled) */ 347*aca3beaaSApple OSS Distributions int max_th; /* maximum threshold for queue (scaled) */ 348*aca3beaaSApple OSS Distributions int min_th; /* minimum threshold for queue (scaled) */ 349*aca3beaaSApple OSS Distributions int max_p; /* maximum value for p_b (scaled) */ 350*aca3beaaSApple OSS Distributions u_int c_1; /* max_p/(max_th-min_th) (scaled) */ 351*aca3beaaSApple OSS Distributions u_int c_2; /* max_p*min_th/(max_th-min_th) (scaled) */ 352*aca3beaaSApple OSS Distributions u_int c_3; /* for GRED, (1-max_p)/max_th (scaled) */ 353*aca3beaaSApple OSS Distributions u_int c_4; /* for GRED, 1 - 2*max_p (scaled) */ 354*aca3beaaSApple OSS Distributions u_int * w_q_lookup; /* lookup table for computing (1-w_q)^t */ 355*aca3beaaSApple OSS Distributions u_int lookup_depth; /* depth of lookup table */ 356*aca3beaaSApple OSS Distributions int lookup_step; /* granularity inside the lookup table */ 357*aca3beaaSApple OSS Distributions int lookup_weight; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */ 358*aca3beaaSApple OSS Distributions int avg_pkt_size; /* medium packet size */ 359*aca3beaaSApple OSS Distributions int max_pkt_size; /* max packet size */ 360*aca3beaaSApple OSS Distributions }; 361*aca3beaaSApple OSS Distributions 362*aca3beaaSApple OSS Distributions SLIST_HEAD(dn_flow_set_head, dn_flow_set); 363*aca3beaaSApple OSS Distributions 364*aca3beaaSApple OSS Distributions /* 365*aca3beaaSApple OSS Distributions * Pipe descriptor. Contains global parameters, delay-line queue, 366*aca3beaaSApple OSS Distributions * and the flow_set used for fixed-rate queues. 367*aca3beaaSApple OSS Distributions * 368*aca3beaaSApple OSS Distributions * For WF2Q+ support it also has 3 heaps holding dn_flow_queue: 369*aca3beaaSApple OSS Distributions * not_eligible_heap, for queues whose start time is higher 370*aca3beaaSApple OSS Distributions * than the virtual time. Sorted by start time. 371*aca3beaaSApple OSS Distributions * scheduler_heap, for queues eligible for scheduling. Sorted by 372*aca3beaaSApple OSS Distributions * finish time. 373*aca3beaaSApple OSS Distributions * idle_heap, all flows that are idle and can be removed. We 374*aca3beaaSApple OSS Distributions * do that on each tick so we do not slow down too much 375*aca3beaaSApple OSS Distributions * operations during forwarding. 376*aca3beaaSApple OSS Distributions * 377*aca3beaaSApple OSS Distributions */ 378*aca3beaaSApple OSS Distributions struct dn_pipe { /* a pipe */ 379*aca3beaaSApple OSS Distributions SLIST_ENTRY(dn_pipe) next;/* linked list in a hash slot */ 380*aca3beaaSApple OSS Distributions 381*aca3beaaSApple OSS Distributions int pipe_nr; /* number */ 382*aca3beaaSApple OSS Distributions int bandwidth; /* really, bytes/tick. */ 383*aca3beaaSApple OSS Distributions int delay; /* really, ticks */ 384*aca3beaaSApple OSS Distributions 385*aca3beaaSApple OSS Distributions struct mbuf *head, *tail; /* packets in delay line */ 386*aca3beaaSApple OSS Distributions 387*aca3beaaSApple OSS Distributions /* WF2Q+ */ 388*aca3beaaSApple OSS Distributions struct dn_heap scheduler_heap; /* top extract - key Finish time*/ 389*aca3beaaSApple OSS Distributions struct dn_heap not_eligible_heap; /* top extract- key Start time */ 390*aca3beaaSApple OSS Distributions struct dn_heap idle_heap; /* random extract - key Start=Finish time */ 391*aca3beaaSApple OSS Distributions 392*aca3beaaSApple OSS Distributions dn_key V; /* virtual time */ 393*aca3beaaSApple OSS Distributions int sum; /* sum of weights of all active sessions */ 394*aca3beaaSApple OSS Distributions int numbytes; /* bits I can transmit (more or less). */ 395*aca3beaaSApple OSS Distributions 396*aca3beaaSApple OSS Distributions dn_key sched_time; /* time pipe was scheduled in ready_heap */ 397*aca3beaaSApple OSS Distributions 398*aca3beaaSApple OSS Distributions /* 399*aca3beaaSApple OSS Distributions * When the tx clock come from an interface (if_name[0] != '\0'), its name 400*aca3beaaSApple OSS Distributions * is stored below, whereas the ifp is filled when the rule is configured. 401*aca3beaaSApple OSS Distributions */ 402*aca3beaaSApple OSS Distributions char if_name[IFNAMSIZ]; 403*aca3beaaSApple OSS Distributions struct ifnet *ifp; 404*aca3beaaSApple OSS Distributions int ready; /* set if ifp != NULL and we got a signal from it */ 405*aca3beaaSApple OSS Distributions 406*aca3beaaSApple OSS Distributions struct dn_flow_set fs; /* used with fixed-rate flows */ 407*aca3beaaSApple OSS Distributions }; 408*aca3beaaSApple OSS Distributions 409*aca3beaaSApple OSS Distributions SLIST_HEAD(dn_pipe_head, dn_pipe); 410*aca3beaaSApple OSS Distributions 411*aca3beaaSApple OSS Distributions #ifdef BSD_KERNEL_PRIVATE 412*aca3beaaSApple OSS Distributions extern uint32_t my_random(void); 413*aca3beaaSApple OSS Distributions void ip_dn_init(void); 414*aca3beaaSApple OSS Distributions 415*aca3beaaSApple OSS Distributions typedef int ip_dn_ctl_t(struct sockopt *); /* raw_ip.c */ 416*aca3beaaSApple OSS Distributions typedef int ip_dn_io_t(struct mbuf *m, int pipe_nr, int dir, 417*aca3beaaSApple OSS Distributions struct ip_fw_args *fwa); 418*aca3beaaSApple OSS Distributions extern ip_dn_ctl_t *ip_dn_ctl_ptr; 419*aca3beaaSApple OSS Distributions extern ip_dn_io_t *ip_dn_io_ptr; 420*aca3beaaSApple OSS Distributions #define DUMMYNET_LOADED (ip_dn_io_ptr != NULL) 421*aca3beaaSApple OSS Distributions 422*aca3beaaSApple OSS Distributions #pragma pack(4) 423*aca3beaaSApple OSS Distributions 424*aca3beaaSApple OSS Distributions struct dn_heap_32 { 425*aca3beaaSApple OSS Distributions int size; 426*aca3beaaSApple OSS Distributions int elements; 427*aca3beaaSApple OSS Distributions int offset; /* XXX if > 0 this is the offset of direct ptr to obj */ 428*aca3beaaSApple OSS Distributions user32_addr_t p; /* really an array of "size" entries */ 429*aca3beaaSApple OSS Distributions }; 430*aca3beaaSApple OSS Distributions 431*aca3beaaSApple OSS Distributions struct dn_flow_queue_32 { 432*aca3beaaSApple OSS Distributions user32_addr_t next; 433*aca3beaaSApple OSS Distributions struct ip_flow_id id; 434*aca3beaaSApple OSS Distributions 435*aca3beaaSApple OSS Distributions user32_addr_t head, tail; /* queue of packets */ 436*aca3beaaSApple OSS Distributions u_int len; 437*aca3beaaSApple OSS Distributions u_int len_bytes; 438*aca3beaaSApple OSS Distributions u_int32_t numbytes; /* credit for transmission (dynamic queues) */ 439*aca3beaaSApple OSS Distributions 440*aca3beaaSApple OSS Distributions u_int64_t tot_pkts; /* statistics counters */ 441*aca3beaaSApple OSS Distributions u_int64_t tot_bytes; 442*aca3beaaSApple OSS Distributions u_int32_t drops; 443*aca3beaaSApple OSS Distributions 444*aca3beaaSApple OSS Distributions int hash_slot; /* debugging/diagnostic */ 445*aca3beaaSApple OSS Distributions 446*aca3beaaSApple OSS Distributions /* RED parameters */ 447*aca3beaaSApple OSS Distributions int avg; /* average queue length est. (scaled) */ 448*aca3beaaSApple OSS Distributions int count; /* arrivals since last RED drop */ 449*aca3beaaSApple OSS Distributions int random; /* random value (scaled) */ 450*aca3beaaSApple OSS Distributions u_int32_t q_time; /* start of queue idle time */ 451*aca3beaaSApple OSS Distributions 452*aca3beaaSApple OSS Distributions /* WF2Q+ support */ 453*aca3beaaSApple OSS Distributions user32_addr_t fs; /* parent flow set */ 454*aca3beaaSApple OSS Distributions int heap_pos; /* position (index) of struct in heap */ 455*aca3beaaSApple OSS Distributions dn_key sched_time; /* current time when queue enters ready_heap */ 456*aca3beaaSApple OSS Distributions 457*aca3beaaSApple OSS Distributions dn_key S, F; /* start time, finish time */ 458*aca3beaaSApple OSS Distributions /* 459*aca3beaaSApple OSS Distributions * Setting F < S means the timestamp is invalid. We only need 460*aca3beaaSApple OSS Distributions * to test this when the queue is empty. 461*aca3beaaSApple OSS Distributions */ 462*aca3beaaSApple OSS Distributions }; 463*aca3beaaSApple OSS Distributions 464*aca3beaaSApple OSS Distributions struct dn_flow_set_32 { 465*aca3beaaSApple OSS Distributions user32_addr_t next;/* next flow set in all_flow_sets list */ 466*aca3beaaSApple OSS Distributions 467*aca3beaaSApple OSS Distributions u_short fs_nr; /* flow_set number */ 468*aca3beaaSApple OSS Distributions u_short flags_fs; 469*aca3beaaSApple OSS Distributions #define DN_HAVE_FLOW_MASK 0x0001 470*aca3beaaSApple OSS Distributions #define DN_IS_RED 0x0002 471*aca3beaaSApple OSS Distributions #define DN_IS_GENTLE_RED 0x0004 472*aca3beaaSApple OSS Distributions #define DN_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */ 473*aca3beaaSApple OSS Distributions #define DN_NOERROR 0x0010 /* do not report ENOBUFS on drops */ 474*aca3beaaSApple OSS Distributions #define DN_IS_PIPE 0x4000 475*aca3beaaSApple OSS Distributions #define DN_IS_QUEUE 0x8000 476*aca3beaaSApple OSS Distributions 477*aca3beaaSApple OSS Distributions user32_addr_t pipe; /* pointer to parent pipe */ 478*aca3beaaSApple OSS Distributions u_short parent_nr; /* parent pipe#, 0 if local to a pipe */ 479*aca3beaaSApple OSS Distributions 480*aca3beaaSApple OSS Distributions int weight; /* WFQ queue weight */ 481*aca3beaaSApple OSS Distributions int qsize; /* queue size in slots or bytes */ 482*aca3beaaSApple OSS Distributions int plr; /* pkt loss rate (2^31-1 means 100%) */ 483*aca3beaaSApple OSS Distributions 484*aca3beaaSApple OSS Distributions struct ip_flow_id flow_mask; 485*aca3beaaSApple OSS Distributions 486*aca3beaaSApple OSS Distributions /* hash table of queues onto this flow_set */ 487*aca3beaaSApple OSS Distributions int rq_size; /* number of slots */ 488*aca3beaaSApple OSS Distributions int rq_elements; /* active elements */ 489*aca3beaaSApple OSS Distributions user32_addr_t rq; /* array of rq_size entries */ 490*aca3beaaSApple OSS Distributions 491*aca3beaaSApple OSS Distributions u_int32_t last_expired; /* do not expire too frequently */ 492*aca3beaaSApple OSS Distributions int backlogged; /* #active queues for this flowset */ 493*aca3beaaSApple OSS Distributions 494*aca3beaaSApple OSS Distributions /* RED parameters */ 495*aca3beaaSApple OSS Distributions #define SCALE_RED 16 496*aca3beaaSApple OSS Distributions #define SCALE(x) ( (x) << SCALE_RED ) 497*aca3beaaSApple OSS Distributions #define SCALE_VAL(x) ( (x) >> SCALE_RED ) 498*aca3beaaSApple OSS Distributions #define SCALE_MUL(x, y) ( ( (x) * (y) ) >> SCALE_RED ) 499*aca3beaaSApple OSS Distributions int w_q; /* queue weight (scaled) */ 500*aca3beaaSApple OSS Distributions int max_th; /* maximum threshold for queue (scaled) */ 501*aca3beaaSApple OSS Distributions int min_th; /* minimum threshold for queue (scaled) */ 502*aca3beaaSApple OSS Distributions int max_p; /* maximum value for p_b (scaled) */ 503*aca3beaaSApple OSS Distributions u_int c_1; /* max_p/(max_th-min_th) (scaled) */ 504*aca3beaaSApple OSS Distributions u_int c_2; /* max_p*min_th/(max_th-min_th) (scaled) */ 505*aca3beaaSApple OSS Distributions u_int c_3; /* for GRED, (1-max_p)/max_th (scaled) */ 506*aca3beaaSApple OSS Distributions u_int c_4; /* for GRED, 1 - 2*max_p (scaled) */ 507*aca3beaaSApple OSS Distributions user32_addr_t w_q_lookup; /* lookup table for computing (1-w_q)^t */ 508*aca3beaaSApple OSS Distributions u_int lookup_depth; /* depth of lookup table */ 509*aca3beaaSApple OSS Distributions int lookup_step; /* granularity inside the lookup table */ 510*aca3beaaSApple OSS Distributions int lookup_weight; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */ 511*aca3beaaSApple OSS Distributions int avg_pkt_size; /* medium packet size */ 512*aca3beaaSApple OSS Distributions int max_pkt_size; /* max packet size */ 513*aca3beaaSApple OSS Distributions }; 514*aca3beaaSApple OSS Distributions 515*aca3beaaSApple OSS Distributions struct dn_pipe_32 { /* a pipe */ 516*aca3beaaSApple OSS Distributions user32_addr_t next; 517*aca3beaaSApple OSS Distributions 518*aca3beaaSApple OSS Distributions int pipe_nr; /* number */ 519*aca3beaaSApple OSS Distributions int bandwidth; /* really, bytes/tick. */ 520*aca3beaaSApple OSS Distributions int delay; /* really, ticks */ 521*aca3beaaSApple OSS Distributions 522*aca3beaaSApple OSS Distributions user32_addr_t head, tail; /* packets in delay line */ 523*aca3beaaSApple OSS Distributions 524*aca3beaaSApple OSS Distributions /* WF2Q+ */ 525*aca3beaaSApple OSS Distributions struct dn_heap_32 scheduler_heap; /* top extract - key Finish time*/ 526*aca3beaaSApple OSS Distributions struct dn_heap_32 not_eligible_heap; /* top extract- key Start time */ 527*aca3beaaSApple OSS Distributions struct dn_heap_32 idle_heap; /* random extract - key Start=Finish time */ 528*aca3beaaSApple OSS Distributions 529*aca3beaaSApple OSS Distributions dn_key V; /* virtual time */ 530*aca3beaaSApple OSS Distributions int sum; /* sum of weights of all active sessions */ 531*aca3beaaSApple OSS Distributions int numbytes; /* bits I can transmit (more or less). */ 532*aca3beaaSApple OSS Distributions 533*aca3beaaSApple OSS Distributions dn_key sched_time; /* time pipe was scheduled in ready_heap */ 534*aca3beaaSApple OSS Distributions 535*aca3beaaSApple OSS Distributions /* 536*aca3beaaSApple OSS Distributions * When the tx clock come from an interface (if_name[0] != '\0'), its name 537*aca3beaaSApple OSS Distributions * is stored below, whereas the ifp is filled when the rule is configured. 538*aca3beaaSApple OSS Distributions */ 539*aca3beaaSApple OSS Distributions char if_name[IFNAMSIZ]; 540*aca3beaaSApple OSS Distributions user32_addr_t ifp; 541*aca3beaaSApple OSS Distributions int ready; /* set if ifp != NULL and we got a signal from it */ 542*aca3beaaSApple OSS Distributions 543*aca3beaaSApple OSS Distributions struct dn_flow_set_32 fs; /* used with fixed-rate flows */ 544*aca3beaaSApple OSS Distributions }; 545*aca3beaaSApple OSS Distributions #pragma pack() 546*aca3beaaSApple OSS Distributions 547*aca3beaaSApple OSS Distributions 548*aca3beaaSApple OSS Distributions struct dn_heap_64 { 549*aca3beaaSApple OSS Distributions int size; 550*aca3beaaSApple OSS Distributions int elements; 551*aca3beaaSApple OSS Distributions int offset; /* XXX if > 0 this is the offset of direct ptr to obj */ 552*aca3beaaSApple OSS Distributions user64_addr_t p; /* really an array of "size" entries */ 553*aca3beaaSApple OSS Distributions }; 554*aca3beaaSApple OSS Distributions 555*aca3beaaSApple OSS Distributions 556*aca3beaaSApple OSS Distributions struct dn_flow_queue_64 { 557*aca3beaaSApple OSS Distributions user64_addr_t next; 558*aca3beaaSApple OSS Distributions struct ip_flow_id id; 559*aca3beaaSApple OSS Distributions 560*aca3beaaSApple OSS Distributions user64_addr_t head, tail; /* queue of packets */ 561*aca3beaaSApple OSS Distributions u_int len; 562*aca3beaaSApple OSS Distributions u_int len_bytes; 563*aca3beaaSApple OSS Distributions u_int32_t numbytes; /* credit for transmission (dynamic queues) */ 564*aca3beaaSApple OSS Distributions 565*aca3beaaSApple OSS Distributions u_int64_t tot_pkts; /* statistics counters */ 566*aca3beaaSApple OSS Distributions u_int64_t tot_bytes; 567*aca3beaaSApple OSS Distributions u_int32_t drops; 568*aca3beaaSApple OSS Distributions 569*aca3beaaSApple OSS Distributions int hash_slot; /* debugging/diagnostic */ 570*aca3beaaSApple OSS Distributions 571*aca3beaaSApple OSS Distributions /* RED parameters */ 572*aca3beaaSApple OSS Distributions int avg; /* average queue length est. (scaled) */ 573*aca3beaaSApple OSS Distributions int count; /* arrivals since last RED drop */ 574*aca3beaaSApple OSS Distributions int random; /* random value (scaled) */ 575*aca3beaaSApple OSS Distributions u_int32_t q_time; /* start of queue idle time */ 576*aca3beaaSApple OSS Distributions 577*aca3beaaSApple OSS Distributions /* WF2Q+ support */ 578*aca3beaaSApple OSS Distributions user64_addr_t fs; /* parent flow set */ 579*aca3beaaSApple OSS Distributions int heap_pos; /* position (index) of struct in heap */ 580*aca3beaaSApple OSS Distributions dn_key sched_time; /* current time when queue enters ready_heap */ 581*aca3beaaSApple OSS Distributions 582*aca3beaaSApple OSS Distributions dn_key S, F; /* start time, finish time */ 583*aca3beaaSApple OSS Distributions /* 584*aca3beaaSApple OSS Distributions * Setting F < S means the timestamp is invalid. We only need 585*aca3beaaSApple OSS Distributions * to test this when the queue is empty. 586*aca3beaaSApple OSS Distributions */ 587*aca3beaaSApple OSS Distributions }; 588*aca3beaaSApple OSS Distributions 589*aca3beaaSApple OSS Distributions struct dn_flow_set_64 { 590*aca3beaaSApple OSS Distributions user64_addr_t next; /* next flow set in all_flow_sets list */ 591*aca3beaaSApple OSS Distributions 592*aca3beaaSApple OSS Distributions u_short fs_nr; /* flow_set number */ 593*aca3beaaSApple OSS Distributions u_short flags_fs; 594*aca3beaaSApple OSS Distributions #define DN_HAVE_FLOW_MASK 0x0001 595*aca3beaaSApple OSS Distributions #define DN_IS_RED 0x0002 596*aca3beaaSApple OSS Distributions #define DN_IS_GENTLE_RED 0x0004 597*aca3beaaSApple OSS Distributions #define DN_QSIZE_IS_BYTES 0x0008 /* queue size is measured in bytes */ 598*aca3beaaSApple OSS Distributions #define DN_NOERROR 0x0010 /* do not report ENOBUFS on drops */ 599*aca3beaaSApple OSS Distributions #define DN_IS_PIPE 0x4000 600*aca3beaaSApple OSS Distributions #define DN_IS_QUEUE 0x8000 601*aca3beaaSApple OSS Distributions 602*aca3beaaSApple OSS Distributions user64_addr_t pipe; /* pointer to parent pipe */ 603*aca3beaaSApple OSS Distributions u_short parent_nr; /* parent pipe#, 0 if local to a pipe */ 604*aca3beaaSApple OSS Distributions 605*aca3beaaSApple OSS Distributions int weight; /* WFQ queue weight */ 606*aca3beaaSApple OSS Distributions int qsize; /* queue size in slots or bytes */ 607*aca3beaaSApple OSS Distributions int plr; /* pkt loss rate (2^31-1 means 100%) */ 608*aca3beaaSApple OSS Distributions 609*aca3beaaSApple OSS Distributions struct ip_flow_id flow_mask; 610*aca3beaaSApple OSS Distributions 611*aca3beaaSApple OSS Distributions /* hash table of queues onto this flow_set */ 612*aca3beaaSApple OSS Distributions int rq_size; /* number of slots */ 613*aca3beaaSApple OSS Distributions int rq_elements; /* active elements */ 614*aca3beaaSApple OSS Distributions user64_addr_t rq; /* array of rq_size entries */ 615*aca3beaaSApple OSS Distributions 616*aca3beaaSApple OSS Distributions u_int32_t last_expired; /* do not expire too frequently */ 617*aca3beaaSApple OSS Distributions int backlogged; /* #active queues for this flowset */ 618*aca3beaaSApple OSS Distributions 619*aca3beaaSApple OSS Distributions /* RED parameters */ 620*aca3beaaSApple OSS Distributions #define SCALE_RED 16 621*aca3beaaSApple OSS Distributions #define SCALE(x) ( (x) << SCALE_RED ) 622*aca3beaaSApple OSS Distributions #define SCALE_VAL(x) ( (x) >> SCALE_RED ) 623*aca3beaaSApple OSS Distributions #define SCALE_MUL(x, y) ( ( (x) * (y) ) >> SCALE_RED ) 624*aca3beaaSApple OSS Distributions int w_q; /* queue weight (scaled) */ 625*aca3beaaSApple OSS Distributions int max_th; /* maximum threshold for queue (scaled) */ 626*aca3beaaSApple OSS Distributions int min_th; /* minimum threshold for queue (scaled) */ 627*aca3beaaSApple OSS Distributions int max_p; /* maximum value for p_b (scaled) */ 628*aca3beaaSApple OSS Distributions u_int c_1; /* max_p/(max_th-min_th) (scaled) */ 629*aca3beaaSApple OSS Distributions u_int c_2; /* max_p*min_th/(max_th-min_th) (scaled) */ 630*aca3beaaSApple OSS Distributions u_int c_3; /* for GRED, (1-max_p)/max_th (scaled) */ 631*aca3beaaSApple OSS Distributions u_int c_4; /* for GRED, 1 - 2*max_p (scaled) */ 632*aca3beaaSApple OSS Distributions user64_addr_t w_q_lookup; /* lookup table for computing (1-w_q)^t */ 633*aca3beaaSApple OSS Distributions u_int lookup_depth; /* depth of lookup table */ 634*aca3beaaSApple OSS Distributions int lookup_step; /* granularity inside the lookup table */ 635*aca3beaaSApple OSS Distributions int lookup_weight; /* equal to (1-w_q)^t / (1-w_q)^(t+1) */ 636*aca3beaaSApple OSS Distributions int avg_pkt_size; /* medium packet size */ 637*aca3beaaSApple OSS Distributions int max_pkt_size; /* max packet size */ 638*aca3beaaSApple OSS Distributions }; 639*aca3beaaSApple OSS Distributions 640*aca3beaaSApple OSS Distributions struct dn_pipe_64 { /* a pipe */ 641*aca3beaaSApple OSS Distributions user64_addr_t next; 642*aca3beaaSApple OSS Distributions 643*aca3beaaSApple OSS Distributions int pipe_nr; /* number */ 644*aca3beaaSApple OSS Distributions int bandwidth; /* really, bytes/tick. */ 645*aca3beaaSApple OSS Distributions int delay; /* really, ticks */ 646*aca3beaaSApple OSS Distributions 647*aca3beaaSApple OSS Distributions user64_addr_t head, tail; /* packets in delay line */ 648*aca3beaaSApple OSS Distributions 649*aca3beaaSApple OSS Distributions /* WF2Q+ */ 650*aca3beaaSApple OSS Distributions struct dn_heap_64 scheduler_heap; /* top extract - key Finish time*/ 651*aca3beaaSApple OSS Distributions struct dn_heap_64 not_eligible_heap; /* top extract- key Start time */ 652*aca3beaaSApple OSS Distributions struct dn_heap_64 idle_heap; /* random extract - key Start=Finish time */ 653*aca3beaaSApple OSS Distributions 654*aca3beaaSApple OSS Distributions dn_key V; /* virtual time */ 655*aca3beaaSApple OSS Distributions int sum; /* sum of weights of all active sessions */ 656*aca3beaaSApple OSS Distributions int numbytes; /* bits I can transmit (more or less). */ 657*aca3beaaSApple OSS Distributions 658*aca3beaaSApple OSS Distributions dn_key sched_time; /* time pipe was scheduled in ready_heap */ 659*aca3beaaSApple OSS Distributions 660*aca3beaaSApple OSS Distributions /* 661*aca3beaaSApple OSS Distributions * When the tx clock come from an interface (if_name[0] != '\0'), its name 662*aca3beaaSApple OSS Distributions * is stored below, whereas the ifp is filled when the rule is configured. 663*aca3beaaSApple OSS Distributions */ 664*aca3beaaSApple OSS Distributions char if_name[IFNAMSIZ]; 665*aca3beaaSApple OSS Distributions user64_addr_t ifp; 666*aca3beaaSApple OSS Distributions int ready; /* set if ifp != NULL and we got a signal from it */ 667*aca3beaaSApple OSS Distributions 668*aca3beaaSApple OSS Distributions struct dn_flow_set_64 fs; /* used with fixed-rate flows */ 669*aca3beaaSApple OSS Distributions }; 670*aca3beaaSApple OSS Distributions 671*aca3beaaSApple OSS Distributions #include <sys/eventhandler.h> 672*aca3beaaSApple OSS Distributions /* Dummynet event handling declarations */ 673*aca3beaaSApple OSS Distributions extern struct eventhandler_lists_ctxt dummynet_evhdlr_ctxt; 674*aca3beaaSApple OSS Distributions extern void dummynet_init(void); 675*aca3beaaSApple OSS Distributions 676*aca3beaaSApple OSS Distributions struct dn_pipe_mini_config { 677*aca3beaaSApple OSS Distributions uint32_t bandwidth; 678*aca3beaaSApple OSS Distributions uint32_t delay; 679*aca3beaaSApple OSS Distributions uint32_t plr; 680*aca3beaaSApple OSS Distributions }; 681*aca3beaaSApple OSS Distributions 682*aca3beaaSApple OSS Distributions struct dn_rule_mini_config { 683*aca3beaaSApple OSS Distributions uint32_t dir; 684*aca3beaaSApple OSS Distributions uint32_t af; 685*aca3beaaSApple OSS Distributions uint32_t proto; 686*aca3beaaSApple OSS Distributions /* 687*aca3beaaSApple OSS Distributions * XXX PF rules actually define ranges of ports and 688*aca3beaaSApple OSS Distributions * along with range goes an opcode ((not) equal to, less than 689*aca3beaaSApple OSS Distributions * greater than, etc. 690*aca3beaaSApple OSS Distributions * For now the following works assuming there's no port range 691*aca3beaaSApple OSS Distributions * and the rule is for specific port. 692*aca3beaaSApple OSS Distributions * Also the operation is assumed as equal to. 693*aca3beaaSApple OSS Distributions */ 694*aca3beaaSApple OSS Distributions uint32_t src_port; 695*aca3beaaSApple OSS Distributions uint32_t dst_port; 696*aca3beaaSApple OSS Distributions char ifname[IFXNAMSIZ]; 697*aca3beaaSApple OSS Distributions }; 698*aca3beaaSApple OSS Distributions 699*aca3beaaSApple OSS Distributions struct dummynet_event { 700*aca3beaaSApple OSS Distributions uint32_t dn_event_code; 701*aca3beaaSApple OSS Distributions union { 702*aca3beaaSApple OSS Distributions struct dn_pipe_mini_config _dnev_pipe_config; 703*aca3beaaSApple OSS Distributions struct dn_rule_mini_config _dnev_rule_config; 704*aca3beaaSApple OSS Distributions } dn_event; 705*aca3beaaSApple OSS Distributions }; 706*aca3beaaSApple OSS Distributions 707*aca3beaaSApple OSS Distributions #define dn_event_pipe_config dn_event._dnev_pipe_config 708*aca3beaaSApple OSS Distributions #define dn_event_rule_config dn_event._dnev_rule_config 709*aca3beaaSApple OSS Distributions 710*aca3beaaSApple OSS Distributions extern void dummynet_event_enqueue_nwk_wq_entry(struct dummynet_event *); 711*aca3beaaSApple OSS Distributions 712*aca3beaaSApple OSS Distributions enum { 713*aca3beaaSApple OSS Distributions DUMMYNET_RULE_CONFIG, 714*aca3beaaSApple OSS Distributions DUMMYNET_RULE_DELETE, 715*aca3beaaSApple OSS Distributions DUMMYNET_PIPE_CONFIG, 716*aca3beaaSApple OSS Distributions DUMMYNET_PIPE_DELETE, 717*aca3beaaSApple OSS Distributions DUMMYNET_NLC_DISABLED, 718*aca3beaaSApple OSS Distributions }; 719*aca3beaaSApple OSS Distributions 720*aca3beaaSApple OSS Distributions enum { DN_INOUT, DN_IN, DN_OUT }; 721*aca3beaaSApple OSS Distributions /* 722*aca3beaaSApple OSS Distributions * The signature for the callback is: 723*aca3beaaSApple OSS Distributions * eventhandler_entry_arg __unused 724*aca3beaaSApple OSS Distributions * dummynet_event pointer to dummynet event object 725*aca3beaaSApple OSS Distributions */ 726*aca3beaaSApple OSS Distributions typedef void (*dummynet_event_fn) (struct eventhandler_entry_arg, struct dummynet_event *); 727*aca3beaaSApple OSS Distributions EVENTHANDLER_DECLARE(dummynet_event, dummynet_event_fn); 728*aca3beaaSApple OSS Distributions #endif /* BSD_KERNEL_PRIVATE */ 729*aca3beaaSApple OSS Distributions #endif /* PRIVATE */ 730*aca3beaaSApple OSS Distributions #endif /* _IP_DUMMYNET_H */ 731