1package nl
2
3import (
4	"unsafe"
5)
6
7// Message types
8const (
9	TCA_UNSPEC = iota
10	TCA_KIND
11	TCA_OPTIONS
12	TCA_STATS
13	TCA_XSTATS
14	TCA_RATE
15	TCA_FCNT
16	TCA_STATS2
17	TCA_STAB
18	TCA_MAX = TCA_STAB
19)
20
21const (
22	TCA_ACT_TAB = 1
23	TCAA_MAX    = 1
24)
25
26const (
27	TCA_PRIO_UNSPEC = iota
28	TCA_PRIO_MQ
29	TCA_PRIO_MAX = TCA_PRIO_MQ
30)
31
32const (
33	SizeofTcMsg       = 0x14
34	SizeofTcActionMsg = 0x04
35	SizeofTcPrioMap   = 0x14
36	SizeofTcRateSpec  = 0x0c
37	SizeofTcTbfQopt   = 2*SizeofTcRateSpec + 0x0c
38	SizeofTcU32Key    = 0x10
39	SizeofTcU32Sel    = 0x10 // without keys
40	SizeofTcMirred    = 0x1c
41)
42
43// struct tcmsg {
44//   unsigned char tcm_family;
45//   unsigned char tcm__pad1;
46//   unsigned short  tcm__pad2;
47//   int   tcm_ifindex;
48//   __u32   tcm_handle;
49//   __u32   tcm_parent;
50//   __u32   tcm_info;
51// };
52
53type TcMsg struct {
54	Family  uint8
55	Pad     [3]byte
56	Ifindex int32
57	Handle  uint32
58	Parent  uint32
59	Info    uint32
60}
61
62func (msg *TcMsg) Len() int {
63	return SizeofTcMsg
64}
65
66func DeserializeTcMsg(b []byte) *TcMsg {
67	return (*TcMsg)(unsafe.Pointer(&b[0:SizeofTcMsg][0]))
68}
69
70func (x *TcMsg) Serialize() []byte {
71	return (*(*[SizeofTcMsg]byte)(unsafe.Pointer(x)))[:]
72}
73
74// struct tcamsg {
75//   unsigned char tca_family;
76//   unsigned char tca__pad1;
77//   unsigned short  tca__pad2;
78// };
79
80type TcActionMsg struct {
81	Family uint8
82	Pad    [3]byte
83}
84
85func (msg *TcActionMsg) Len() int {
86	return SizeofTcActionMsg
87}
88
89func DeserializeTcActionMsg(b []byte) *TcActionMsg {
90	return (*TcActionMsg)(unsafe.Pointer(&b[0:SizeofTcActionMsg][0]))
91}
92
93func (x *TcActionMsg) Serialize() []byte {
94	return (*(*[SizeofTcActionMsg]byte)(unsafe.Pointer(x)))[:]
95}
96
97const (
98	TC_PRIO_MAX = 15
99)
100
101// struct tc_prio_qopt {
102// 	int bands;      /* Number of bands */
103// 	__u8  priomap[TC_PRIO_MAX+1]; /* Map: logical priority -> PRIO band */
104// };
105
106type TcPrioMap struct {
107	Bands   int32
108	Priomap [TC_PRIO_MAX + 1]uint8
109}
110
111func (msg *TcPrioMap) Len() int {
112	return SizeofTcPrioMap
113}
114
115func DeserializeTcPrioMap(b []byte) *TcPrioMap {
116	return (*TcPrioMap)(unsafe.Pointer(&b[0:SizeofTcPrioMap][0]))
117}
118
119func (x *TcPrioMap) Serialize() []byte {
120	return (*(*[SizeofTcPrioMap]byte)(unsafe.Pointer(x)))[:]
121}
122
123const (
124	TCA_TBF_UNSPEC = iota
125	TCA_TBF_PARMS
126	TCA_TBF_RTAB
127	TCA_TBF_PTAB
128	TCA_TBF_RATE64
129	TCA_TBF_PRATE64
130	TCA_TBF_BURST
131	TCA_TBF_PBURST
132	TCA_TBF_MAX = TCA_TBF_PBURST
133)
134
135// struct tc_ratespec {
136//   unsigned char cell_log;
137//   __u8    linklayer; /* lower 4 bits */
138//   unsigned short  overhead;
139//   short   cell_align;
140//   unsigned short  mpu;
141//   __u32   rate;
142// };
143
144type TcRateSpec struct {
145	CellLog   uint8
146	Linklayer uint8
147	Overhead  uint16
148	CellAlign int16
149	Mpu       uint16
150	Rate      uint32
151}
152
153func (msg *TcRateSpec) Len() int {
154	return SizeofTcRateSpec
155}
156
157func DeserializeTcRateSpec(b []byte) *TcRateSpec {
158	return (*TcRateSpec)(unsafe.Pointer(&b[0:SizeofTcRateSpec][0]))
159}
160
161func (x *TcRateSpec) Serialize() []byte {
162	return (*(*[SizeofTcRateSpec]byte)(unsafe.Pointer(x)))[:]
163}
164
165// struct tc_tbf_qopt {
166//   struct tc_ratespec rate;
167//   struct tc_ratespec peakrate;
168//   __u32   limit;
169//   __u32   buffer;
170//   __u32   mtu;
171// };
172
173type TcTbfQopt struct {
174	Rate     TcRateSpec
175	Peakrate TcRateSpec
176	Limit    uint32
177	Buffer   uint32
178	Mtu      uint32
179}
180
181func (msg *TcTbfQopt) Len() int {
182	return SizeofTcTbfQopt
183}
184
185func DeserializeTcTbfQopt(b []byte) *TcTbfQopt {
186	return (*TcTbfQopt)(unsafe.Pointer(&b[0:SizeofTcTbfQopt][0]))
187}
188
189func (x *TcTbfQopt) Serialize() []byte {
190	return (*(*[SizeofTcTbfQopt]byte)(unsafe.Pointer(x)))[:]
191}
192
193const (
194	TCA_U32_UNSPEC = iota
195	TCA_U32_CLASSID
196	TCA_U32_HASH
197	TCA_U32_LINK
198	TCA_U32_DIVISOR
199	TCA_U32_SEL
200	TCA_U32_POLICE
201	TCA_U32_ACT
202	TCA_U32_INDEV
203	TCA_U32_PCNT
204	TCA_U32_MARK
205	TCA_U32_MAX = TCA_U32_MARK
206)
207
208// struct tc_u32_key {
209//   __be32    mask;
210//   __be32    val;
211//   int   off;
212//   int   offmask;
213// };
214
215type TcU32Key struct {
216	Mask    uint32 // big endian
217	Val     uint32 // big endian
218	Off     int32
219	OffMask int32
220}
221
222func (msg *TcU32Key) Len() int {
223	return SizeofTcU32Key
224}
225
226func DeserializeTcU32Key(b []byte) *TcU32Key {
227	return (*TcU32Key)(unsafe.Pointer(&b[0:SizeofTcU32Key][0]))
228}
229
230func (x *TcU32Key) Serialize() []byte {
231	return (*(*[SizeofTcU32Key]byte)(unsafe.Pointer(x)))[:]
232}
233
234// struct tc_u32_sel {
235//   unsigned char   flags;
236//   unsigned char   offshift;
237//   unsigned char   nkeys;
238//
239//   __be16      offmask;
240//   __u16     off;
241//   short     offoff;
242//
243//   short     hoff;
244//   __be32      hmask;
245//   struct tc_u32_key keys[0];
246// };
247
248const (
249	TC_U32_TERMINAL  = 1 << iota
250	TC_U32_OFFSET    = 1 << iota
251	TC_U32_VAROFFSET = 1 << iota
252	TC_U32_EAT       = 1 << iota
253)
254
255type TcU32Sel struct {
256	Flags    uint8
257	Offshift uint8
258	Nkeys    uint8
259	Pad      uint8
260	Offmask  uint16 // big endian
261	Off      uint16
262	Offoff   int16
263	Hoff     int16
264	Hmask    uint32 // big endian
265	Keys     []TcU32Key
266}
267
268func (msg *TcU32Sel) Len() int {
269	return SizeofTcU32Sel + int(msg.Nkeys)*SizeofTcU32Key
270}
271
272func DeserializeTcU32Sel(b []byte) *TcU32Sel {
273	x := &TcU32Sel{}
274	copy((*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:], b)
275	next := SizeofTcU32Sel
276	var i uint8
277	for i = 0; i < x.Nkeys; i++ {
278		x.Keys = append(x.Keys, *DeserializeTcU32Key(b[next:]))
279		next += SizeofTcU32Key
280	}
281	return x
282}
283
284func (x *TcU32Sel) Serialize() []byte {
285	// This can't just unsafe.cast because it must iterate through keys.
286	buf := make([]byte, x.Len())
287	copy(buf, (*(*[SizeofTcU32Sel]byte)(unsafe.Pointer(x)))[:])
288	next := SizeofTcU32Sel
289	for _, key := range x.Keys {
290		keyBuf := key.Serialize()
291		copy(buf[next:], keyBuf)
292		next += SizeofTcU32Key
293	}
294	return buf
295}
296
297const (
298	TCA_ACT_MIRRED = 8
299)
300
301const (
302	TCA_MIRRED_UNSPEC = iota
303	TCA_MIRRED_TM
304	TCA_MIRRED_PARMS
305	TCA_MIRRED_MAX = TCA_MIRRED_PARMS
306)
307
308const (
309	TCA_EGRESS_REDIR   = 1 /* packet redirect to EGRESS*/
310	TCA_EGRESS_MIRROR  = 2 /* mirror packet to EGRESS */
311	TCA_INGRESS_REDIR  = 3 /* packet redirect to INGRESS*/
312	TCA_INGRESS_MIRROR = 4 /* mirror packet to INGRESS */
313)
314
315const (
316	TC_ACT_UNSPEC     = int32(-1)
317	TC_ACT_OK         = 0
318	TC_ACT_RECLASSIFY = 1
319	TC_ACT_SHOT       = 2
320	TC_ACT_PIPE       = 3
321	TC_ACT_STOLEN     = 4
322	TC_ACT_QUEUED     = 5
323	TC_ACT_REPEAT     = 6
324	TC_ACT_JUMP       = 0x10000000
325)
326
327// #define tc_gen \
328//   __u32                 index; \
329//   __u32                 capab; \
330//   int                   action; \
331//   int                   refcnt; \
332//   int                   bindcnt
333// struct tc_mirred {
334// 	tc_gen;
335// 	int                     eaction;   /* one of IN/EGRESS_MIRROR/REDIR */
336// 	__u32                   ifindex;  /* ifindex of egress port */
337// };
338
339type TcMirred struct {
340	Index   uint32
341	Capab   uint32
342	Action  int32
343	Refcnt  int32
344	Bindcnt int32
345	Eaction int32
346	Ifindex uint32
347}
348
349func (msg *TcMirred) Len() int {
350	return SizeofTcMirred
351}
352
353func DeserializeTcMirred(b []byte) *TcMirred {
354	return (*TcMirred)(unsafe.Pointer(&b[0:SizeofTcMirred][0]))
355}
356
357func (x *TcMirred) Serialize() []byte {
358	return (*(*[SizeofTcMirred]byte)(unsafe.Pointer(x)))[:]
359}
360