1package netlink
2
3import (
4	"fmt"
5	"net"
6)
7
8type Filter interface {
9	Attrs() *FilterAttrs
10	Type() string
11}
12
13// FilterAttrs represents a netlink filter. A filter is associated with a link,
14// has a handle and a parent. The root filter of a device should have a
15// parent == HANDLE_ROOT.
16type FilterAttrs struct {
17	LinkIndex int
18	Handle    uint32
19	Parent    uint32
20	Priority  uint16 // lower is higher priority
21	Protocol  uint16 // unix.ETH_P_*
22}
23
24func (q FilterAttrs) String() string {
25	return fmt.Sprintf("{LinkIndex: %d, Handle: %s, Parent: %s, Priority: %d, Protocol: %d}", q.LinkIndex, HandleStr(q.Handle), HandleStr(q.Parent), q.Priority, q.Protocol)
26}
27
28type TcAct int32
29
30const (
31	TC_ACT_UNSPEC     TcAct = -1
32	TC_ACT_OK         TcAct = 0
33	TC_ACT_RECLASSIFY TcAct = 1
34	TC_ACT_SHOT       TcAct = 2
35	TC_ACT_PIPE       TcAct = 3
36	TC_ACT_STOLEN     TcAct = 4
37	TC_ACT_QUEUED     TcAct = 5
38	TC_ACT_REPEAT     TcAct = 6
39	TC_ACT_REDIRECT   TcAct = 7
40	TC_ACT_JUMP       TcAct = 0x10000000
41)
42
43func (a TcAct) String() string {
44	switch a {
45	case TC_ACT_UNSPEC:
46		return "unspec"
47	case TC_ACT_OK:
48		return "ok"
49	case TC_ACT_RECLASSIFY:
50		return "reclassify"
51	case TC_ACT_SHOT:
52		return "shot"
53	case TC_ACT_PIPE:
54		return "pipe"
55	case TC_ACT_STOLEN:
56		return "stolen"
57	case TC_ACT_QUEUED:
58		return "queued"
59	case TC_ACT_REPEAT:
60		return "repeat"
61	case TC_ACT_REDIRECT:
62		return "redirect"
63	case TC_ACT_JUMP:
64		return "jump"
65	}
66	return fmt.Sprintf("0x%x", int32(a))
67}
68
69type TcPolAct int32
70
71const (
72	TC_POLICE_UNSPEC     TcPolAct = TcPolAct(TC_ACT_UNSPEC)
73	TC_POLICE_OK         TcPolAct = TcPolAct(TC_ACT_OK)
74	TC_POLICE_RECLASSIFY TcPolAct = TcPolAct(TC_ACT_RECLASSIFY)
75	TC_POLICE_SHOT       TcPolAct = TcPolAct(TC_ACT_SHOT)
76	TC_POLICE_PIPE       TcPolAct = TcPolAct(TC_ACT_PIPE)
77)
78
79func (a TcPolAct) String() string {
80	switch a {
81	case TC_POLICE_UNSPEC:
82		return "unspec"
83	case TC_POLICE_OK:
84		return "ok"
85	case TC_POLICE_RECLASSIFY:
86		return "reclassify"
87	case TC_POLICE_SHOT:
88		return "shot"
89	case TC_POLICE_PIPE:
90		return "pipe"
91	}
92	return fmt.Sprintf("0x%x", int32(a))
93}
94
95type ActionAttrs struct {
96	Index   int
97	Capab   int
98	Action  TcAct
99	Refcnt  int
100	Bindcnt int
101}
102
103func (q ActionAttrs) String() string {
104	return fmt.Sprintf("{Index: %d, Capab: %x, Action: %s, Refcnt: %d, Bindcnt: %d}", q.Index, q.Capab, q.Action.String(), q.Refcnt, q.Bindcnt)
105}
106
107// Action represents an action in any supported filter.
108type Action interface {
109	Attrs() *ActionAttrs
110	Type() string
111}
112
113type GenericAction struct {
114	ActionAttrs
115}
116
117func (action *GenericAction) Type() string {
118	return "generic"
119}
120
121func (action *GenericAction) Attrs() *ActionAttrs {
122	return &action.ActionAttrs
123}
124
125type BpfAction struct {
126	ActionAttrs
127	Fd   int
128	Name string
129}
130
131func (action *BpfAction) Type() string {
132	return "bpf"
133}
134
135func (action *BpfAction) Attrs() *ActionAttrs {
136	return &action.ActionAttrs
137}
138
139type ConnmarkAction struct {
140	ActionAttrs
141	Zone uint16
142}
143
144func (action *ConnmarkAction) Type() string {
145	return "connmark"
146}
147
148func (action *ConnmarkAction) Attrs() *ActionAttrs {
149	return &action.ActionAttrs
150}
151
152func NewConnmarkAction() *ConnmarkAction {
153	return &ConnmarkAction{
154		ActionAttrs: ActionAttrs{
155			Action: TC_ACT_PIPE,
156		},
157	}
158}
159
160type MirredAct uint8
161
162func (a MirredAct) String() string {
163	switch a {
164	case TCA_EGRESS_REDIR:
165		return "egress redir"
166	case TCA_EGRESS_MIRROR:
167		return "egress mirror"
168	case TCA_INGRESS_REDIR:
169		return "ingress redir"
170	case TCA_INGRESS_MIRROR:
171		return "ingress mirror"
172	}
173	return "unknown"
174}
175
176const (
177	TCA_EGRESS_REDIR   MirredAct = 1 /* packet redirect to EGRESS*/
178	TCA_EGRESS_MIRROR  MirredAct = 2 /* mirror packet to EGRESS */
179	TCA_INGRESS_REDIR  MirredAct = 3 /* packet redirect to INGRESS*/
180	TCA_INGRESS_MIRROR MirredAct = 4 /* mirror packet to INGRESS */
181)
182
183type MirredAction struct {
184	ActionAttrs
185	MirredAction MirredAct
186	Ifindex      int
187}
188
189func (action *MirredAction) Type() string {
190	return "mirred"
191}
192
193func (action *MirredAction) Attrs() *ActionAttrs {
194	return &action.ActionAttrs
195}
196
197func NewMirredAction(redirIndex int) *MirredAction {
198	return &MirredAction{
199		ActionAttrs: ActionAttrs{
200			Action: TC_ACT_STOLEN,
201		},
202		MirredAction: TCA_EGRESS_REDIR,
203		Ifindex:      redirIndex,
204	}
205}
206
207type TunnelKeyAct int8
208
209const (
210	TCA_TUNNEL_KEY_SET   TunnelKeyAct = 1 // set tunnel key
211	TCA_TUNNEL_KEY_UNSET TunnelKeyAct = 2 // unset tunnel key
212)
213
214type TunnelKeyAction struct {
215	ActionAttrs
216	Action  TunnelKeyAct
217	SrcAddr net.IP
218	DstAddr net.IP
219	KeyID   uint32
220}
221
222func (action *TunnelKeyAction) Type() string {
223	return "tunnel_key"
224}
225
226func (action *TunnelKeyAction) Attrs() *ActionAttrs {
227	return &action.ActionAttrs
228}
229
230func NewTunnelKeyAction() *TunnelKeyAction {
231	return &TunnelKeyAction{
232		ActionAttrs: ActionAttrs{
233			Action: TC_ACT_PIPE,
234		},
235	}
236}
237
238type SkbEditAction struct {
239	ActionAttrs
240	QueueMapping *uint16
241	PType        *uint16
242	Priority     *uint32
243	Mark         *uint32
244}
245
246func (action *SkbEditAction) Type() string {
247	return "skbedit"
248}
249
250func (action *SkbEditAction) Attrs() *ActionAttrs {
251	return &action.ActionAttrs
252}
253
254func NewSkbEditAction() *SkbEditAction {
255	return &SkbEditAction{
256		ActionAttrs: ActionAttrs{
257			Action: TC_ACT_PIPE,
258		},
259	}
260}
261
262// MatchAll filters match all packets
263type MatchAll struct {
264	FilterAttrs
265	ClassId uint32
266	Actions []Action
267}
268
269func (filter *MatchAll) Attrs() *FilterAttrs {
270	return &filter.FilterAttrs
271}
272
273func (filter *MatchAll) Type() string {
274	return "matchall"
275}
276
277type FilterFwAttrs struct {
278	ClassId   uint32
279	InDev     string
280	Mask      uint32
281	Index     uint32
282	Buffer    uint32
283	Mtu       uint32
284	Mpu       uint16
285	Rate      uint32
286	AvRate    uint32
287	PeakRate  uint32
288	Action    TcPolAct
289	Overhead  uint16
290	LinkLayer int
291}
292
293type BpfFilter struct {
294	FilterAttrs
295	ClassId      uint32
296	Fd           int
297	Name         string
298	DirectAction bool
299	Id           int
300	Tag          string
301}
302
303func (filter *BpfFilter) Type() string {
304	return "bpf"
305}
306
307func (filter *BpfFilter) Attrs() *FilterAttrs {
308	return &filter.FilterAttrs
309}
310
311// GenericFilter filters represent types that are not currently understood
312// by this netlink library.
313type GenericFilter struct {
314	FilterAttrs
315	FilterType string
316}
317
318func (filter *GenericFilter) Attrs() *FilterAttrs {
319	return &filter.FilterAttrs
320}
321
322func (filter *GenericFilter) Type() string {
323	return filter.FilterType
324}
325