xref: /freebsd/sys/netinet/ip_dummynet.h (revision 23f282aa31e9b6fceacd449020e936e98d6f2298)
1 /*
2  * Copyright (c) 1998-2000 Luigi Rizzo, Universita` di Pisa
3  * Portions Copyright (c) 2000 Akamba Corp.
4  * All rights reserved
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  *
27  * $FreeBSD$
28  */
29 
30 #ifndef _IP_DUMMYNET_H
31 #define _IP_DUMMYNET_H
32 
33 /*
34  * Definition of dummynet data structures.
35  * We first start with the heap which is used by the scheduler.
36  *
37  * Each list contains a set of parameters identifying the pipe, and
38  * a set of packets queued on the pipe itself.
39  *
40  * I could have used queue macros, but the management i have
41  * is pretty simple and this makes the code more portable.
42  */
43 
44 typedef u_int32_t dn_key ;      /* sorting key */
45 #define DN_KEY_LT(a,b)     ((int)((a)-(b)) < 0)
46 #define DN_KEY_LEQ(a,b)    ((int)((a)-(b)) <= 0)
47 #define DN_KEY_GT(a,b)     ((int)((a)-(b)) > 0)
48 #define DN_KEY_GEQ(a,b)    ((int)((a)-(b)) >= 0)
49 
50 struct dn_heap_entry {
51     dn_key key ;	/* sorting key. Topmost element is smallest one */
52     void *object ;	/* object pointer */
53 } ;
54 
55 struct dn_heap {
56     int size ;
57     int elements ;
58     struct dn_heap_entry *p ;	/* really an array of "size" entries */
59 } ;
60 
61 /*
62  * MT_DUMMYNET is a new (fake) mbuf type that is prepended to the
63  * packet when it comes out of a pipe. The definition
64  * ought to go in /sys/sys/mbuf.h but here it is less intrusive.
65  */
66 
67 #define MT_DUMMYNET MT_CONTROL
68 
69 /*
70  * struct dn_pkt identifies a packet in the dummynet queue. The
71  * first part is really an m_hdr for implementation purposes, and some
72  * fields are saved there. When passing the packet back to the ip_input/
73  * ip_output(), the struct is prepended to the mbuf chain with type
74  * MT_DUMMYNET, and contains the pointer to the matching rule.
75  */
76 struct dn_pkt {
77 	struct m_hdr hdr ;
78 #define dn_next	hdr.mh_nextpkt	/* next element in queue */
79 #define DN_NEXT(x)	(struct dn_pkt *)(x)->dn_next
80 #define dn_m	hdr.mh_next	/* packet to be forwarded */
81 /* #define dn_dst	hdr.mh_len -* dst, for ip_output		*/
82 #define dn_dir	hdr.mh_flags	/* action when pkt extracted from a queue */
83 #define DN_TO_IP_OUT	1
84 #define DN_TO_IP_IN	2
85 #define DN_TO_BDG_FWD	3
86 
87 	dn_key  output_time;    /* when the pkt is due for delivery */
88         struct ifnet *ifp;	/* interface, for ip_output		*/
89 	struct sockaddr_in *dn_dst ;
90         struct route ro;	/* route, for ip_output. MUST COPY	*/
91 	int flags ;		/* flags, for ip_output (IPv6 ?) */
92 };
93 
94 struct dn_queue {
95 	struct dn_pkt *head, *tail;
96 } ;
97 
98 /*
99  * We use per flow queues. Hashing is used to select the right slot,
100  * then we scan the list to match the flow-id.
101  * The pipe is shared as it is only a delay line and thus one is enough.
102  */
103 struct dn_flow_queue {
104     struct dn_flow_queue *next ;
105     struct ipfw_flow_id id ;
106     struct dn_pipe *p ;	/* parent pipe */
107     struct dn_queue r;
108     long numbytes ;
109     u_int len ;
110     u_int len_bytes ;
111 
112     u_int64_t tot_pkts ;	/* statistics counters	*/
113     u_int64_t tot_bytes ;
114     u_int32_t drops ;
115     int hash_slot ;	/* debugging/diagnostic */
116 } ;
117 
118 /*
119  * Pipe descriptor. Contains global parameters, delay-line queue,
120  * and the hash array of the per-flow queues.
121  */
122 struct dn_pipe {			/* a pipe */
123 	struct dn_pipe *next ;
124 
125 	u_short	pipe_nr ;		/* number	*/
126 	u_short	flags ;			/* to speed up things	*/
127 #define DN_HAVE_FLOW_MASK	8
128 	int	bandwidth;		/* really, bytes/tick.	*/
129 	int	queue_size ;
130 	int	queue_size_bytes ;
131 	int	delay ;			/* really, ticks	*/
132 	int	plr ;		/* pkt loss rate (2^31-1 means 100%) */
133 
134         struct	dn_queue p ;
135 	struct ipfw_flow_id flow_mask ;
136 	int rq_size ;
137 	int rq_elements ;
138 	struct dn_flow_queue **rq ;	/* array of rq_size entries */
139 };
140 
141 #ifdef _KERNEL
142 
143 MALLOC_DECLARE(M_IPFW);
144 
145 typedef int ip_dn_ctl_t __P((struct sockopt *)) ;
146 extern ip_dn_ctl_t *ip_dn_ctl_ptr;
147 
148 void dn_rule_delete(void *r);		/* used in ip_fw.c */
149 int dummynet_io(int pipe, int dir,
150 	struct mbuf *m, struct ifnet *ifp, struct route *ro,
151 	struct sockaddr_in * dst,
152 	struct ip_fw_chain *rule, int flags);
153 #endif
154 
155 #endif /* _IP_DUMMYNET_H */
156