Linux 4.14-rc6
[linux-2.6-block.git] / include / net / pkt_cls.h
CommitLineData
1da177e4
LT
1#ifndef __NET_PKT_CLS_H
2#define __NET_PKT_CLS_H
3
4#include <linux/pkt_cls.h>
5#include <net/sch_generic.h>
6#include <net/act_api.h>
7
8/* Basic packet classifier frontend definitions. */
9
fd2c3ef7 10struct tcf_walker {
1da177e4
LT
11 int stop;
12 int skip;
13 int count;
8113c095 14 int (*fn)(struct tcf_proto *, void *node, struct tcf_walker *);
1da177e4
LT
15};
16
5c15257f
JP
17int register_tcf_proto_ops(struct tcf_proto_ops *ops);
18int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
1da177e4 19
8ae70032 20#ifdef CONFIG_NET_CLS
367a8ce8
WC
21struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
22 bool create);
5bc17018 23void tcf_chain_put(struct tcf_chain *chain);
6529eaba
JP
24int tcf_block_get(struct tcf_block **p_block,
25 struct tcf_proto __rcu **p_filter_chain);
26void tcf_block_put(struct tcf_block *block);
87d83093
JP
27int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
28 struct tcf_result *res, bool compat_mode);
29
8ae70032 30#else
6529eaba
JP
31static inline
32int tcf_block_get(struct tcf_block **p_block,
33 struct tcf_proto __rcu **p_filter_chain)
34{
35 return 0;
36}
37
38static inline void tcf_block_put(struct tcf_block *block)
8ae70032
JP
39{
40}
87d83093
JP
41
42static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
43 struct tcf_result *res, bool compat_mode)
44{
45 return TC_ACT_UNSPEC;
46}
8ae70032 47#endif
cf1facda 48
1da177e4
LT
49static inline unsigned long
50__cls_set_class(unsigned long *clp, unsigned long cl)
51{
a0efb80c 52 return xchg(clp, cl);
1da177e4
LT
53}
54
55static inline unsigned long
56cls_set_class(struct tcf_proto *tp, unsigned long *clp,
57 unsigned long cl)
58{
59 unsigned long old_cl;
60
61 tcf_tree_lock(tp);
62 old_cl = __cls_set_class(clp, cl);
63 tcf_tree_unlock(tp);
64
65 return old_cl;
66}
67
68static inline void
69tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
70{
71 unsigned long cl;
72
73 cl = tp->q->ops->cl_ops->bind_tcf(tp->q, base, r->classid);
74 cl = cls_set_class(tp, &r->class, cl);
75 if (cl)
76 tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
77}
78
79static inline void
80tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
81{
82 unsigned long cl;
83
84 if ((cl = __cls_set_class(&r->class, 0)) != 0)
85 tp->q->ops->cl_ops->unbind_tcf(tp->q, cl);
86}
87
fd2c3ef7 88struct tcf_exts {
1da177e4 89#ifdef CONFIG_NET_CLS_ACT
33be6271 90 __u32 type; /* for backward compat(TCA_OLD_COMPAT) */
22dc13c8
WC
91 int nr_actions;
92 struct tc_action **actions;
1da177e4 93#endif
5da57f42
WC
94 /* Map to export classifier specific extension TLV types to the
95 * generic extensions API. Unsupported extensions must be set to 0.
96 */
1da177e4
LT
97 int action;
98 int police;
99};
100
b9a24bb7 101static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
33be6271
WC
102{
103#ifdef CONFIG_NET_CLS_ACT
5da57f42 104 exts->type = 0;
22dc13c8
WC
105 exts->nr_actions = 0;
106 exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
107 GFP_KERNEL);
b9a24bb7
WC
108 if (!exts->actions)
109 return -ENOMEM;
33be6271 110#endif
5da57f42
WC
111 exts->action = action;
112 exts->police = police;
b9a24bb7 113 return 0;
33be6271
WC
114}
115
22dc13c8
WC
116static inline void tcf_exts_to_list(const struct tcf_exts *exts,
117 struct list_head *actions)
118{
119#ifdef CONFIG_NET_CLS_ACT
120 int i;
121
122 for (i = 0; i < exts->nr_actions; i++) {
123 struct tc_action *a = exts->actions[i];
124
fa5effe7 125 list_add_tail(&a->list, actions);
22dc13c8
WC
126 }
127#endif
128}
129
d897a638
JK
130static inline void
131tcf_exts_stats_update(const struct tcf_exts *exts,
132 u64 bytes, u64 packets, u64 lastuse)
133{
134#ifdef CONFIG_NET_CLS_ACT
135 int i;
136
137 preempt_disable();
138
139 for (i = 0; i < exts->nr_actions; i++) {
140 struct tc_action *a = exts->actions[i];
141
142 tcf_action_stats_update(a, bytes, packets, lastuse);
143 }
144
145 preempt_enable();
146#endif
147}
148
3bcc0cec
JP
149/**
150 * tcf_exts_has_actions - check if at least one action is present
151 * @exts: tc filter extensions handle
152 *
153 * Returns true if at least one action is present.
154 */
155static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
156{
2734437e 157#ifdef CONFIG_NET_CLS_ACT
3bcc0cec
JP
158 return exts->nr_actions;
159#else
160 return false;
161#endif
162}
2734437e 163
3bcc0cec
JP
164/**
165 * tcf_exts_has_one_action - check if exactly one action is present
166 * @exts: tc filter extensions handle
167 *
168 * Returns true if exactly one action is present.
169 */
170static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
171{
172#ifdef CONFIG_NET_CLS_ACT
173 return exts->nr_actions == 1;
174#else
175 return false;
176#endif
177}
2734437e 178
af69afc5
JP
179/**
180 * tcf_exts_exec - execute tc filter extensions
181 * @skb: socket buffer
182 * @exts: tc filter extensions handle
183 * @res: desired result
184 *
af089e70 185 * Executes all configured extensions. Returns TC_ACT_OK on a normal execution,
af69afc5
JP
186 * a negative number if the filter must be considered unmatched or
187 * a positive action code (TC_ACT_*) which must be returned to the
188 * underlying layer.
189 */
190static inline int
191tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
192 struct tcf_result *res)
193{
194#ifdef CONFIG_NET_CLS_ACT
ec1a9cca 195 return tcf_action_exec(skb, exts->actions, exts->nr_actions, res);
af69afc5 196#endif
af089e70 197 return TC_ACT_OK;
af69afc5
JP
198}
199
5c15257f
JP
200int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
201 struct nlattr **tb, struct nlattr *rate_tlv,
2f7ef2f8 202 struct tcf_exts *exts, bool ovr);
18d0264f 203void tcf_exts_destroy(struct tcf_exts *exts);
9b0d4446 204void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
5da57f42
WC
205int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
206int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
7091d8c7
HHZ
207int tcf_exts_get_dev(struct net_device *dev, struct tcf_exts *exts,
208 struct net_device **hw_dev);
1da177e4
LT
209
210/**
211 * struct tcf_pkt_info - packet information
212 */
fd2c3ef7 213struct tcf_pkt_info {
1da177e4
LT
214 unsigned char * ptr;
215 int nexthdr;
216};
217
218#ifdef CONFIG_NET_EMATCH
219
220struct tcf_ematch_ops;
221
222/**
223 * struct tcf_ematch - extended match (ematch)
224 *
225 * @matchid: identifier to allow userspace to reidentify a match
226 * @flags: flags specifying attributes and the relation to other matches
227 * @ops: the operations lookup table of the corresponding ematch module
228 * @datalen: length of the ematch specific configuration data
229 * @data: ematch specific data
230 */
fd2c3ef7 231struct tcf_ematch {
1da177e4
LT
232 struct tcf_ematch_ops * ops;
233 unsigned long data;
234 unsigned int datalen;
235 u16 matchid;
236 u16 flags;
82a470f1 237 struct net *net;
1da177e4
LT
238};
239
240static inline int tcf_em_is_container(struct tcf_ematch *em)
241{
242 return !em->ops;
243}
244
245static inline int tcf_em_is_simple(struct tcf_ematch *em)
246{
247 return em->flags & TCF_EM_SIMPLE;
248}
249
250static inline int tcf_em_is_inverted(struct tcf_ematch *em)
251{
252 return em->flags & TCF_EM_INVERT;
253}
254
255static inline int tcf_em_last_match(struct tcf_ematch *em)
256{
257 return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END;
258}
259
260static inline int tcf_em_early_end(struct tcf_ematch *em, int result)
261{
262 if (tcf_em_last_match(em))
263 return 1;
264
265 if (result == 0 && em->flags & TCF_EM_REL_AND)
266 return 1;
267
268 if (result != 0 && em->flags & TCF_EM_REL_OR)
269 return 1;
270
271 return 0;
272}
273
274/**
275 * struct tcf_ematch_tree - ematch tree handle
276 *
277 * @hdr: ematch tree header supplied by userspace
278 * @matches: array of ematches
279 */
fd2c3ef7 280struct tcf_ematch_tree {
1da177e4
LT
281 struct tcf_ematch_tree_hdr hdr;
282 struct tcf_ematch * matches;
283
284};
285
286/**
287 * struct tcf_ematch_ops - ematch module operations
288 *
289 * @kind: identifier (kind) of this ematch module
290 * @datalen: length of expected configuration data (optional)
291 * @change: called during validation (optional)
292 * @match: called during ematch tree evaluation, must return 1/0
293 * @destroy: called during destroyage (optional)
294 * @dump: called during dumping process (optional)
295 * @owner: owner, must be set to THIS_MODULE
296 * @link: link to previous/next ematch module (internal use)
297 */
fd2c3ef7 298struct tcf_ematch_ops {
1da177e4
LT
299 int kind;
300 int datalen;
82a470f1 301 int (*change)(struct net *net, void *,
1da177e4
LT
302 int, struct tcf_ematch *);
303 int (*match)(struct sk_buff *, struct tcf_ematch *,
304 struct tcf_pkt_info *);
82a470f1 305 void (*destroy)(struct tcf_ematch *);
1da177e4
LT
306 int (*dump)(struct sk_buff *, struct tcf_ematch *);
307 struct module *owner;
308 struct list_head link;
309};
310
5c15257f
JP
311int tcf_em_register(struct tcf_ematch_ops *);
312void tcf_em_unregister(struct tcf_ematch_ops *);
313int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
314 struct tcf_ematch_tree *);
82a470f1 315void tcf_em_tree_destroy(struct tcf_ematch_tree *);
5c15257f
JP
316int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
317int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
318 struct tcf_pkt_info *);
1da177e4 319
1da177e4
LT
320/**
321 * tcf_em_tree_match - evaulate an ematch tree
322 *
323 * @skb: socket buffer of the packet in question
324 * @tree: ematch tree to be used for evaluation
325 * @info: packet information examined by classifier
326 *
327 * This function matches @skb against the ematch tree in @tree by going
328 * through all ematches respecting their logic relations returning
329 * as soon as the result is obvious.
330 *
331 * Returns 1 if the ematch tree as-one matches, no ematches are configured
332 * or ematch is not enabled in the kernel, otherwise 0 is returned.
333 */
334static inline int tcf_em_tree_match(struct sk_buff *skb,
335 struct tcf_ematch_tree *tree,
336 struct tcf_pkt_info *info)
337{
338 if (tree->hdr.nmatches)
339 return __tcf_em_tree_match(skb, tree, info);
340 else
341 return 1;
342}
343
db3d99c0
PM
344#define MODULE_ALIAS_TCF_EMATCH(kind) MODULE_ALIAS("ematch-kind-" __stringify(kind))
345
1da177e4
LT
346#else /* CONFIG_NET_EMATCH */
347
fd2c3ef7 348struct tcf_ematch_tree {
1da177e4
LT
349};
350
351#define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
82a470f1 352#define tcf_em_tree_destroy(t) do { (void)(t); } while(0)
1da177e4 353#define tcf_em_tree_dump(skb, t, tlv) (0)
1da177e4
LT
354#define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
355
356#endif /* CONFIG_NET_EMATCH */
357
358static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
359{
360 switch (layer) {
361 case TCF_LAYER_LINK:
362 return skb->data;
363 case TCF_LAYER_NETWORK:
d56f90a7 364 return skb_network_header(skb);
1da177e4 365 case TCF_LAYER_TRANSPORT:
9c70220b 366 return skb_transport_header(skb);
1da177e4
LT
367 }
368
369 return NULL;
370}
371
eddc9ec5
ACM
372static inline int tcf_valid_offset(const struct sk_buff *skb,
373 const unsigned char *ptr, const int len)
1da177e4 374{
da521b2c
DM
375 return likely((ptr + len) <= skb_tail_pointer(skb) &&
376 ptr >= skb->head &&
377 (ptr <= (ptr + len)));
1da177e4
LT
378}
379
380#ifdef CONFIG_NET_CLS_IND
0eeb8ffc
DL
381#include <net/net_namespace.h>
382
1da177e4 383static inline int
2519a602 384tcf_change_indev(struct net *net, struct nlattr *indev_tlv)
1da177e4 385{
2519a602
WC
386 char indev[IFNAMSIZ];
387 struct net_device *dev;
388
add93b61 389 if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
1da177e4 390 return -EINVAL;
2519a602
WC
391 dev = __dev_get_by_name(net, indev);
392 if (!dev)
393 return -ENODEV;
394 return dev->ifindex;
1da177e4
LT
395}
396
2519a602
WC
397static inline bool
398tcf_match_indev(struct sk_buff *skb, int ifindex)
1da177e4 399{
2519a602
WC
400 if (!ifindex)
401 return true;
402 if (!skb->skb_iif)
403 return false;
404 return ifindex == skb->skb_iif;
1da177e4
LT
405}
406#endif /* CONFIG_NET_CLS_IND */
407
5fd9fc4e 408struct tc_cls_common_offload {
5fd9fc4e
JP
409 u32 chain_index;
410 __be16 protocol;
d7c1c8d2 411 u32 prio;
7690f2a5 412 u32 classid;
5fd9fc4e
JP
413};
414
415static inline void
416tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
417 const struct tcf_proto *tp)
418{
5fd9fc4e
JP
419 cls_common->chain_index = tp->chain->index;
420 cls_common->protocol = tp->protocol;
d7c1c8d2 421 cls_common->prio = tp->prio;
7690f2a5 422 cls_common->classid = tp->classid;
5fd9fc4e
JP
423}
424
a1b7c5fd
JF
425struct tc_cls_u32_knode {
426 struct tcf_exts *exts;
e014860e 427 struct tc_u32_sel *sel;
a1b7c5fd
JF
428 u32 handle;
429 u32 val;
430 u32 mask;
431 u32 link_handle;
e014860e 432 u8 fshift;
a1b7c5fd
JF
433};
434
435struct tc_cls_u32_hnode {
436 u32 handle;
437 u32 prio;
438 unsigned int divisor;
439};
440
441enum tc_clsu32_command {
442 TC_CLSU32_NEW_KNODE,
443 TC_CLSU32_REPLACE_KNODE,
444 TC_CLSU32_DELETE_KNODE,
445 TC_CLSU32_NEW_HNODE,
446 TC_CLSU32_REPLACE_HNODE,
447 TC_CLSU32_DELETE_HNODE,
448};
449
450struct tc_cls_u32_offload {
5fd9fc4e 451 struct tc_cls_common_offload common;
a1b7c5fd
JF
452 /* knode values */
453 enum tc_clsu32_command command;
454 union {
455 struct tc_cls_u32_knode knode;
456 struct tc_cls_u32_hnode hnode;
457 };
458};
459
7b06e8ae 460static inline bool tc_can_offload(const struct net_device *dev)
6843e7a2 461{
2b6ab0d3
JF
462 if (!(dev->features & NETIF_F_HW_TC))
463 return false;
9e8ce79c
JF
464 if (!dev->netdev_ops->ndo_setup_tc)
465 return false;
9e8ce79c 466 return true;
6843e7a2
JF
467}
468
55330f05
HHZ
469static inline bool tc_skip_hw(u32 flags)
470{
471 return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
472}
473
7b06e8ae 474static inline bool tc_should_offload(const struct net_device *dev, u32 flags)
55330f05
HHZ
475{
476 if (tc_skip_hw(flags))
477 return false;
7b06e8ae 478 return tc_can_offload(dev);
55330f05
HHZ
479}
480
d34e3e18
SS
481static inline bool tc_skip_sw(u32 flags)
482{
483 return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false;
484}
485
486/* SKIP_HW and SKIP_SW are mutually exclusive flags. */
487static inline bool tc_flags_valid(u32 flags)
488{
489 if (flags & ~(TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW))
490 return false;
491
492 if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW)))
493 return false;
494
495 return true;
496}
497
e696028a
OG
498static inline bool tc_in_hw(u32 flags)
499{
500 return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false;
501}
502
5b33f488
AV
503enum tc_fl_command {
504 TC_CLSFLOWER_REPLACE,
505 TC_CLSFLOWER_DESTROY,
10cbc684 506 TC_CLSFLOWER_STATS,
5b33f488
AV
507};
508
509struct tc_cls_flower_offload {
5fd9fc4e 510 struct tc_cls_common_offload common;
5b33f488 511 enum tc_fl_command command;
8208d21b 512 unsigned long cookie;
5b33f488
AV
513 struct flow_dissector *dissector;
514 struct fl_flow_key *mask;
515 struct fl_flow_key *key;
516 struct tcf_exts *exts;
3e0e8266 517 bool egress_dev;
5b33f488
AV
518};
519
b87f7936
YG
520enum tc_matchall_command {
521 TC_CLSMATCHALL_REPLACE,
522 TC_CLSMATCHALL_DESTROY,
523};
524
525struct tc_cls_matchall_offload {
5fd9fc4e 526 struct tc_cls_common_offload common;
b87f7936
YG
527 enum tc_matchall_command command;
528 struct tcf_exts *exts;
529 unsigned long cookie;
530};
531
332ae8e2
JK
532enum tc_clsbpf_command {
533 TC_CLSBPF_ADD,
534 TC_CLSBPF_REPLACE,
535 TC_CLSBPF_DESTROY,
68d64063 536 TC_CLSBPF_STATS,
332ae8e2
JK
537};
538
539struct tc_cls_bpf_offload {
5fd9fc4e 540 struct tc_cls_common_offload common;
332ae8e2
JK
541 enum tc_clsbpf_command command;
542 struct tcf_exts *exts;
543 struct bpf_prog *prog;
544 const char *name;
545 bool exts_integrated;
0d01d45f 546 u32 gen_flags;
332ae8e2
JK
547};
548
1045ba77
JHS
549
550/* This structure holds cookie structure that is passed from user
551 * to the kernel for actions and classifiers
552 */
553struct tc_cookie {
554 u8 *data;
555 u32 len;
556};
1da177e4 557#endif