]> asedeno.scripts.mit.edu Git - linux.git/blob - include/net/pkt_cls.h
60d39789e4f07d19269df1acf2c57d1d6058b348
[linux.git] / include / net / pkt_cls.h
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
10 struct tcf_walker {
11         int     stop;
12         int     skip;
13         int     count;
14         int     (*fn)(struct tcf_proto *, void *node, struct tcf_walker *);
15 };
16
17 int register_tcf_proto_ops(struct tcf_proto_ops *ops);
18 int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
19
20 #ifdef CONFIG_NET_CLS
21 struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
22                                 bool create);
23 void tcf_chain_put(struct tcf_chain *chain);
24 int tcf_block_get(struct tcf_block **p_block,
25                   struct tcf_proto __rcu **p_filter_chain);
26 void tcf_block_put(struct tcf_block *block);
27 int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
28                  struct tcf_result *res, bool compat_mode);
29
30 #else
31 static inline
32 int tcf_block_get(struct tcf_block **p_block,
33                   struct tcf_proto __rcu **p_filter_chain)
34 {
35         return 0;
36 }
37
38 static inline void tcf_block_put(struct tcf_block *block)
39 {
40 }
41
42 static 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 }
47 #endif
48
49 static inline unsigned long
50 __cls_set_class(unsigned long *clp, unsigned long cl)
51 {
52         return xchg(clp, cl);
53 }
54
55 static inline unsigned long
56 cls_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
68 static inline void
69 tcf_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
79 static inline void
80 tcf_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
88 struct tcf_exts {
89 #ifdef CONFIG_NET_CLS_ACT
90         __u32   type; /* for backward compat(TCA_OLD_COMPAT) */
91         int nr_actions;
92         struct tc_action **actions;
93 #endif
94         /* Map to export classifier specific extension TLV types to the
95          * generic extensions API. Unsupported extensions must be set to 0.
96          */
97         int action;
98         int police;
99 };
100
101 static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
102 {
103 #ifdef CONFIG_NET_CLS_ACT
104         exts->type = 0;
105         exts->nr_actions = 0;
106         exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
107                                 GFP_KERNEL);
108         if (!exts->actions)
109                 return -ENOMEM;
110 #endif
111         exts->action = action;
112         exts->police = police;
113         return 0;
114 }
115
116 static 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
125                 list_add_tail(&a->list, actions);
126         }
127 #endif
128 }
129
130 static inline void
131 tcf_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
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  */
155 static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
156 {
157 #ifdef CONFIG_NET_CLS_ACT
158         return exts->nr_actions;
159 #else
160         return false;
161 #endif
162 }
163
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  */
170 static 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 }
178
179 /**
180  * tcf_exts_exec - execute tc filter extensions
181  * @skb: socket buffer
182  * @exts: tc filter extensions handle
183  * @res: desired result
184  *
185  * Executes all configured extensions. Returns TC_ACT_OK on a normal execution,
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  */
190 static inline int
191 tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
192               struct tcf_result *res)
193 {
194 #ifdef CONFIG_NET_CLS_ACT
195         return tcf_action_exec(skb, exts->actions, exts->nr_actions, res);
196 #endif
197         return TC_ACT_OK;
198 }
199
200 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
201                       struct nlattr **tb, struct nlattr *rate_tlv,
202                       struct tcf_exts *exts, bool ovr);
203 void tcf_exts_destroy(struct tcf_exts *exts);
204 void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
205 int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
206 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
207
208 /**
209  * struct tcf_pkt_info - packet information
210  */
211 struct tcf_pkt_info {
212         unsigned char *         ptr;
213         int                     nexthdr;
214 };
215
216 #ifdef CONFIG_NET_EMATCH
217
218 struct tcf_ematch_ops;
219
220 /**
221  * struct tcf_ematch - extended match (ematch)
222  * 
223  * @matchid: identifier to allow userspace to reidentify a match
224  * @flags: flags specifying attributes and the relation to other matches
225  * @ops: the operations lookup table of the corresponding ematch module
226  * @datalen: length of the ematch specific configuration data
227  * @data: ematch specific data
228  */
229 struct tcf_ematch {
230         struct tcf_ematch_ops * ops;
231         unsigned long           data;
232         unsigned int            datalen;
233         u16                     matchid;
234         u16                     flags;
235         struct net              *net;
236 };
237
238 static inline int tcf_em_is_container(struct tcf_ematch *em)
239 {
240         return !em->ops;
241 }
242
243 static inline int tcf_em_is_simple(struct tcf_ematch *em)
244 {
245         return em->flags & TCF_EM_SIMPLE;
246 }
247
248 static inline int tcf_em_is_inverted(struct tcf_ematch *em)
249 {
250         return em->flags & TCF_EM_INVERT;
251 }
252
253 static inline int tcf_em_last_match(struct tcf_ematch *em)
254 {
255         return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END;
256 }
257
258 static inline int tcf_em_early_end(struct tcf_ematch *em, int result)
259 {
260         if (tcf_em_last_match(em))
261                 return 1;
262
263         if (result == 0 && em->flags & TCF_EM_REL_AND)
264                 return 1;
265
266         if (result != 0 && em->flags & TCF_EM_REL_OR)
267                 return 1;
268
269         return 0;
270 }
271         
272 /**
273  * struct tcf_ematch_tree - ematch tree handle
274  *
275  * @hdr: ematch tree header supplied by userspace
276  * @matches: array of ematches
277  */
278 struct tcf_ematch_tree {
279         struct tcf_ematch_tree_hdr hdr;
280         struct tcf_ematch *     matches;
281         
282 };
283
284 /**
285  * struct tcf_ematch_ops - ematch module operations
286  * 
287  * @kind: identifier (kind) of this ematch module
288  * @datalen: length of expected configuration data (optional)
289  * @change: called during validation (optional)
290  * @match: called during ematch tree evaluation, must return 1/0
291  * @destroy: called during destroyage (optional)
292  * @dump: called during dumping process (optional)
293  * @owner: owner, must be set to THIS_MODULE
294  * @link: link to previous/next ematch module (internal use)
295  */
296 struct tcf_ematch_ops {
297         int                     kind;
298         int                     datalen;
299         int                     (*change)(struct net *net, void *,
300                                           int, struct tcf_ematch *);
301         int                     (*match)(struct sk_buff *, struct tcf_ematch *,
302                                          struct tcf_pkt_info *);
303         void                    (*destroy)(struct tcf_ematch *);
304         int                     (*dump)(struct sk_buff *, struct tcf_ematch *);
305         struct module           *owner;
306         struct list_head        link;
307 };
308
309 int tcf_em_register(struct tcf_ematch_ops *);
310 void tcf_em_unregister(struct tcf_ematch_ops *);
311 int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
312                          struct tcf_ematch_tree *);
313 void tcf_em_tree_destroy(struct tcf_ematch_tree *);
314 int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
315 int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
316                         struct tcf_pkt_info *);
317
318 /**
319  * tcf_em_tree_match - evaulate an ematch tree
320  *
321  * @skb: socket buffer of the packet in question
322  * @tree: ematch tree to be used for evaluation
323  * @info: packet information examined by classifier
324  *
325  * This function matches @skb against the ematch tree in @tree by going
326  * through all ematches respecting their logic relations returning
327  * as soon as the result is obvious.
328  *
329  * Returns 1 if the ematch tree as-one matches, no ematches are configured
330  * or ematch is not enabled in the kernel, otherwise 0 is returned.
331  */
332 static inline int tcf_em_tree_match(struct sk_buff *skb,
333                                     struct tcf_ematch_tree *tree,
334                                     struct tcf_pkt_info *info)
335 {
336         if (tree->hdr.nmatches)
337                 return __tcf_em_tree_match(skb, tree, info);
338         else
339                 return 1;
340 }
341
342 #define MODULE_ALIAS_TCF_EMATCH(kind)   MODULE_ALIAS("ematch-kind-" __stringify(kind))
343
344 #else /* CONFIG_NET_EMATCH */
345
346 struct tcf_ematch_tree {
347 };
348
349 #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
350 #define tcf_em_tree_destroy(t) do { (void)(t); } while(0)
351 #define tcf_em_tree_dump(skb, t, tlv) (0)
352 #define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
353
354 #endif /* CONFIG_NET_EMATCH */
355
356 static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
357 {
358         switch (layer) {
359                 case TCF_LAYER_LINK:
360                         return skb->data;
361                 case TCF_LAYER_NETWORK:
362                         return skb_network_header(skb);
363                 case TCF_LAYER_TRANSPORT:
364                         return skb_transport_header(skb);
365         }
366
367         return NULL;
368 }
369
370 static inline int tcf_valid_offset(const struct sk_buff *skb,
371                                    const unsigned char *ptr, const int len)
372 {
373         return likely((ptr + len) <= skb_tail_pointer(skb) &&
374                       ptr >= skb->head &&
375                       (ptr <= (ptr + len)));
376 }
377
378 #ifdef CONFIG_NET_CLS_IND
379 #include <net/net_namespace.h>
380
381 static inline int
382 tcf_change_indev(struct net *net, struct nlattr *indev_tlv)
383 {
384         char indev[IFNAMSIZ];
385         struct net_device *dev;
386
387         if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
388                 return -EINVAL;
389         dev = __dev_get_by_name(net, indev);
390         if (!dev)
391                 return -ENODEV;
392         return dev->ifindex;
393 }
394
395 static inline bool
396 tcf_match_indev(struct sk_buff *skb, int ifindex)
397 {
398         if (!ifindex)
399                 return true;
400         if  (!skb->skb_iif)
401                 return false;
402         return ifindex == skb->skb_iif;
403 }
404 #endif /* CONFIG_NET_CLS_IND */
405
406 int tc_setup_cb_call(struct tcf_exts *exts, enum tc_setup_type type,
407                      void *type_data, bool err_stop);
408
409 struct tc_cls_common_offload {
410         u32 chain_index;
411         __be16 protocol;
412         u32 prio;
413         u32 classid;
414 };
415
416 static inline void
417 tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
418                            const struct tcf_proto *tp)
419 {
420         cls_common->chain_index = tp->chain->index;
421         cls_common->protocol = tp->protocol;
422         cls_common->prio = tp->prio;
423         cls_common->classid = tp->classid;
424 }
425
426 struct tc_cls_u32_knode {
427         struct tcf_exts *exts;
428         struct tc_u32_sel *sel;
429         u32 handle;
430         u32 val;
431         u32 mask;
432         u32 link_handle;
433         u8 fshift;
434 };
435
436 struct tc_cls_u32_hnode {
437         u32 handle;
438         u32 prio;
439         unsigned int divisor;
440 };
441
442 enum tc_clsu32_command {
443         TC_CLSU32_NEW_KNODE,
444         TC_CLSU32_REPLACE_KNODE,
445         TC_CLSU32_DELETE_KNODE,
446         TC_CLSU32_NEW_HNODE,
447         TC_CLSU32_REPLACE_HNODE,
448         TC_CLSU32_DELETE_HNODE,
449 };
450
451 struct tc_cls_u32_offload {
452         struct tc_cls_common_offload common;
453         /* knode values */
454         enum tc_clsu32_command command;
455         union {
456                 struct tc_cls_u32_knode knode;
457                 struct tc_cls_u32_hnode hnode;
458         };
459 };
460
461 static inline bool tc_can_offload(const struct net_device *dev)
462 {
463         if (!(dev->features & NETIF_F_HW_TC))
464                 return false;
465         if (!dev->netdev_ops->ndo_setup_tc)
466                 return false;
467         return true;
468 }
469
470 static inline bool tc_skip_hw(u32 flags)
471 {
472         return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
473 }
474
475 static inline bool tc_should_offload(const struct net_device *dev, u32 flags)
476 {
477         if (tc_skip_hw(flags))
478                 return false;
479         return tc_can_offload(dev);
480 }
481
482 static inline bool tc_skip_sw(u32 flags)
483 {
484         return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false;
485 }
486
487 /* SKIP_HW and SKIP_SW are mutually exclusive flags. */
488 static inline bool tc_flags_valid(u32 flags)
489 {
490         if (flags & ~(TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW))
491                 return false;
492
493         if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW)))
494                 return false;
495
496         return true;
497 }
498
499 static inline bool tc_in_hw(u32 flags)
500 {
501         return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false;
502 }
503
504 enum tc_fl_command {
505         TC_CLSFLOWER_REPLACE,
506         TC_CLSFLOWER_DESTROY,
507         TC_CLSFLOWER_STATS,
508 };
509
510 struct tc_cls_flower_offload {
511         struct tc_cls_common_offload common;
512         enum tc_fl_command command;
513         unsigned long cookie;
514         struct flow_dissector *dissector;
515         struct fl_flow_key *mask;
516         struct fl_flow_key *key;
517         struct tcf_exts *exts;
518 };
519
520 enum tc_matchall_command {
521         TC_CLSMATCHALL_REPLACE,
522         TC_CLSMATCHALL_DESTROY,
523 };
524
525 struct tc_cls_matchall_offload {
526         struct tc_cls_common_offload common;
527         enum tc_matchall_command command;
528         struct tcf_exts *exts;
529         unsigned long cookie;
530 };
531
532 enum tc_clsbpf_command {
533         TC_CLSBPF_ADD,
534         TC_CLSBPF_REPLACE,
535         TC_CLSBPF_DESTROY,
536         TC_CLSBPF_STATS,
537 };
538
539 struct tc_cls_bpf_offload {
540         struct tc_cls_common_offload common;
541         enum tc_clsbpf_command command;
542         struct tcf_exts *exts;
543         struct bpf_prog *prog;
544         const char *name;
545         bool exts_integrated;
546         u32 gen_flags;
547 };
548
549 struct tc_mqprio_qopt_offload {
550         /* struct tc_mqprio_qopt must always be the first element */
551         struct tc_mqprio_qopt qopt;
552         u16 mode;
553         u16 shaper;
554         u32 flags;
555         u64 min_rate[TC_QOPT_MAX_QUEUE];
556         u64 max_rate[TC_QOPT_MAX_QUEUE];
557 };
558
559 /* This structure holds cookie structure that is passed from user
560  * to the kernel for actions and classifiers
561  */
562 struct tc_cookie {
563         u8  *data;
564         u32 len;
565 };
566 #endif