1 package netlink
2
3 import (
4 "fmt"
5 "math"
6 )
7
8 const (
9 HANDLE_NONE = 0
10 HANDLE_INGRESS = 0xFFFFFFF1
11 HANDLE_CLSACT = HANDLE_INGRESS
12 HANDLE_ROOT = 0xFFFFFFFF
13 PRIORITY_MAP_LEN = 16
14 )
15 const (
16 HANDLE_MIN_INGRESS = 0xFFFFFFF2
17 HANDLE_MIN_EGRESS = 0xFFFFFFF3
18 )
19
20 const (
21 HORIZON_DROP_POLICY_CAP = 0
22 HORIZON_DROP_POLICY_DROP = 1
23 HORIZON_DROP_POLICY_DEFAULT = 255
24 )
25
26 type Qdisc interface {
27 Attrs() *QdiscAttrs
28 Type() string
29 }
30
31 type QdiscStatistics ClassStatistics
32
33
34
35
36 type QdiscAttrs struct {
37 LinkIndex int
38 Handle uint32
39 Parent uint32
40 Refcnt uint32
41 IngressBlock *uint32
42 Statistics *QdiscStatistics
43 }
44
45 func (q QdiscAttrs) String() string {
46 return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Refcnt: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Refcnt)
47 }
48
49 func MakeHandle(major, minor uint16) uint32 {
50 return (uint32(major) << 16) | uint32(minor)
51 }
52
53 func MajorMinor(handle uint32) (uint16, uint16) {
54 return uint16((handle & 0xFFFF0000) >> 16), uint16(handle & 0x0000FFFFF)
55 }
56
57 func HandleStr(handle uint32) string {
58 switch handle {
59 case HANDLE_NONE:
60 return "none"
61 case HANDLE_INGRESS:
62 return "ingress"
63 case HANDLE_ROOT:
64 return "root"
65 default:
66 major, minor := MajorMinor(handle)
67 return fmt.Sprintf("%x:%x", major, minor)
68 }
69 }
70
71 func Percentage2u32(percentage float32) uint32 {
72
73 if percentage == 100 {
74 return math.MaxUint32
75 }
76 return uint32(math.MaxUint32 * (percentage / 100))
77 }
78
79
80
81 type PfifoFast struct {
82 QdiscAttrs
83 Bands uint8
84 PriorityMap [PRIORITY_MAP_LEN]uint8
85 }
86
87 func (qdisc *PfifoFast) Attrs() *QdiscAttrs {
88 return &qdisc.QdiscAttrs
89 }
90
91 func (qdisc *PfifoFast) Type() string {
92 return "pfifo_fast"
93 }
94
95
96 type Prio struct {
97 QdiscAttrs
98 Bands uint8
99 PriorityMap [PRIORITY_MAP_LEN]uint8
100 }
101
102 func NewPrio(attrs QdiscAttrs) *Prio {
103 return &Prio{
104 QdiscAttrs: attrs,
105 Bands: 3,
106 PriorityMap: [PRIORITY_MAP_LEN]uint8{1, 2, 2, 2, 1, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1},
107 }
108 }
109
110 func (qdisc *Prio) Attrs() *QdiscAttrs {
111 return &qdisc.QdiscAttrs
112 }
113
114 func (qdisc *Prio) Type() string {
115 return "prio"
116 }
117
118
119 type Htb struct {
120 QdiscAttrs
121 Version uint32
122 Rate2Quantum uint32
123 Defcls uint32
124 Debug uint32
125 DirectPkts uint32
126 DirectQlen *uint32
127 }
128
129 func NewHtb(attrs QdiscAttrs) *Htb {
130 return &Htb{
131 QdiscAttrs: attrs,
132 Version: 3,
133 Defcls: 0,
134 Rate2Quantum: 10,
135 Debug: 0,
136 DirectPkts: 0,
137 DirectQlen: nil,
138 }
139 }
140
141 func (qdisc *Htb) Attrs() *QdiscAttrs {
142 return &qdisc.QdiscAttrs
143 }
144
145 func (qdisc *Htb) Type() string {
146 return "htb"
147 }
148
149
150
151 type NetemQdiscAttrs struct {
152 Latency uint32
153 DelayCorr float32
154 Limit uint32
155 Loss float32
156 LossCorr float32
157 Gap uint32
158 Duplicate float32
159 DuplicateCorr float32
160 Jitter uint32
161 ReorderProb float32
162 ReorderCorr float32
163 CorruptProb float32
164 CorruptCorr float32
165 Rate64 uint64
166 }
167
168 func (q NetemQdiscAttrs) String() string {
169 return fmt.Sprintf(
170 "{Latency: %d, Limit: %d, Loss: %f, Gap: %d, Duplicate: %f, Jitter: %d}",
171 q.Latency, q.Limit, q.Loss, q.Gap, q.Duplicate, q.Jitter,
172 )
173 }
174
175 type Netem struct {
176 QdiscAttrs
177 Latency uint32
178 DelayCorr uint32
179 Limit uint32
180 Loss uint32
181 LossCorr uint32
182 Gap uint32
183 Duplicate uint32
184 DuplicateCorr uint32
185 Jitter uint32
186 ReorderProb uint32
187 ReorderCorr uint32
188 CorruptProb uint32
189 CorruptCorr uint32
190 Rate64 uint64
191 }
192
193 func (netem *Netem) String() string {
194 return fmt.Sprintf(
195 "{Latency: %v, Limit: %v, Loss: %v, Gap: %v, Duplicate: %v, Jitter: %v}",
196 netem.Latency, netem.Limit, netem.Loss, netem.Gap, netem.Duplicate, netem.Jitter,
197 )
198 }
199
200 func (qdisc *Netem) Attrs() *QdiscAttrs {
201 return &qdisc.QdiscAttrs
202 }
203
204 func (qdisc *Netem) Type() string {
205 return "netem"
206 }
207
208
209 type Tbf struct {
210 QdiscAttrs
211 Rate uint64
212 Limit uint32
213 Buffer uint32
214 Peakrate uint64
215 Minburst uint32
216
217 }
218
219 func (qdisc *Tbf) Attrs() *QdiscAttrs {
220 return &qdisc.QdiscAttrs
221 }
222
223 func (qdisc *Tbf) Type() string {
224 return "tbf"
225 }
226
227
228 type Clsact struct {
229 QdiscAttrs
230 }
231
232 func (qdisc *Clsact) Attrs() *QdiscAttrs {
233 return &qdisc.QdiscAttrs
234 }
235
236 func (qdisc *Clsact) Type() string {
237 return "clsact"
238 }
239
240
241 type Ingress struct {
242 QdiscAttrs
243 }
244
245 func (qdisc *Ingress) Attrs() *QdiscAttrs {
246 return &qdisc.QdiscAttrs
247 }
248
249 func (qdisc *Ingress) Type() string {
250 return "ingress"
251 }
252
253
254
255 type GenericQdisc struct {
256 QdiscAttrs
257 QdiscType string
258 }
259
260 func (qdisc *GenericQdisc) Attrs() *QdiscAttrs {
261 return &qdisc.QdiscAttrs
262 }
263
264 func (qdisc *GenericQdisc) Type() string {
265 return qdisc.QdiscType
266 }
267
268 type Hfsc struct {
269 QdiscAttrs
270 Defcls uint16
271 }
272
273 func NewHfsc(attrs QdiscAttrs) *Hfsc {
274 return &Hfsc{
275 QdiscAttrs: attrs,
276 Defcls: 1,
277 }
278 }
279
280 func (hfsc *Hfsc) Attrs() *QdiscAttrs {
281 return &hfsc.QdiscAttrs
282 }
283
284 func (hfsc *Hfsc) Type() string {
285 return "hfsc"
286 }
287
288 func (hfsc *Hfsc) String() string {
289 return fmt.Sprintf(
290 "{%v -- default: %d}",
291 hfsc.Attrs(), hfsc.Defcls,
292 )
293 }
294
295
296 type Fq struct {
297 QdiscAttrs
298 PacketLimit uint32
299 FlowPacketLimit uint32
300
301 Quantum uint32
302 InitialQuantum uint32
303
304 Pacing uint32
305 FlowDefaultRate uint32
306 FlowMaxRate uint32
307
308 Buckets uint32
309 FlowRefillDelay uint32
310 LowRateThreshold uint32
311 Horizon uint32
312 HorizonDropPolicy uint8
313 }
314
315 func (fq *Fq) String() string {
316 return fmt.Sprintf(
317 "{PacketLimit: %v, FlowPacketLimit: %v, Quantum: %v, InitialQuantum: %v, Pacing: %v, FlowDefaultRate: %v, FlowMaxRate: %v, Buckets: %v, FlowRefillDelay: %v, LowRateThreshold: %v, Horizon: %v, HorizonDropPolicy: %v}",
318 fq.PacketLimit, fq.FlowPacketLimit, fq.Quantum, fq.InitialQuantum, fq.Pacing, fq.FlowDefaultRate, fq.FlowMaxRate, fq.Buckets, fq.FlowRefillDelay, fq.LowRateThreshold, fq.Horizon, fq.HorizonDropPolicy,
319 )
320 }
321
322 func NewFq(attrs QdiscAttrs) *Fq {
323 return &Fq{
324 QdiscAttrs: attrs,
325 Pacing: 1,
326 HorizonDropPolicy: HORIZON_DROP_POLICY_DEFAULT,
327 }
328 }
329
330 func (qdisc *Fq) Attrs() *QdiscAttrs {
331 return &qdisc.QdiscAttrs
332 }
333
334 func (qdisc *Fq) Type() string {
335 return "fq"
336 }
337
338
339 type FqCodel struct {
340 QdiscAttrs
341 Target uint32
342 Limit uint32
343 Interval uint32
344 ECN uint32
345 Flows uint32
346 Quantum uint32
347 CEThreshold uint32
348 DropBatchSize uint32
349 MemoryLimit uint32
350 }
351
352 func (fqcodel *FqCodel) String() string {
353 return fmt.Sprintf(
354 "{%v -- Target: %v, Limit: %v, Interval: %v, ECM: %v, Flows: %v, Quantum: %v}",
355 fqcodel.Attrs(), fqcodel.Target, fqcodel.Limit, fqcodel.Interval, fqcodel.ECN, fqcodel.Flows, fqcodel.Quantum,
356 )
357 }
358
359 func NewFqCodel(attrs QdiscAttrs) *FqCodel {
360 return &FqCodel{
361 QdiscAttrs: attrs,
362 ECN: 1,
363 }
364 }
365
366 func (qdisc *FqCodel) Attrs() *QdiscAttrs {
367 return &qdisc.QdiscAttrs
368 }
369
370 func (qdisc *FqCodel) Type() string {
371 return "fq_codel"
372 }
373
374 type Sfq struct {
375 QdiscAttrs
376
377 Quantum uint8
378 Perturb uint8
379 Limit uint32
380 Divisor uint8
381 }
382
383 func (sfq *Sfq) String() string {
384 return fmt.Sprintf(
385 "{%v -- Quantum: %v, Perturb: %v, Limit: %v, Divisor: %v}",
386 sfq.Attrs(), sfq.Quantum, sfq.Perturb, sfq.Limit, sfq.Divisor,
387 )
388 }
389
390 func (qdisc *Sfq) Attrs() *QdiscAttrs {
391 return &qdisc.QdiscAttrs
392 }
393
394 func (qdisc *Sfq) Type() string {
395 return "sfq"
396 }
397
View as plain text