net: sched: red: don't reset the backlog on every stat dump
[linux-2.6-block.git] / include / net / pkt_cls.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef __NET_PKT_CLS_H
3 #define __NET_PKT_CLS_H
4
5 #include <linux/pkt_cls.h>
6 #include <linux/workqueue.h>
7 #include <net/sch_generic.h>
8 #include <net/act_api.h>
9
10 /* Basic packet classifier frontend definitions. */
11
12 struct tcf_walker {
13         int     stop;
14         int     skip;
15         int     count;
16         int     (*fn)(struct tcf_proto *, void *node, struct tcf_walker *);
17 };
18
19 int register_tcf_proto_ops(struct tcf_proto_ops *ops);
20 int unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
21
22 enum tcf_block_binder_type {
23         TCF_BLOCK_BINDER_TYPE_UNSPEC,
24         TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS,
25         TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS,
26 };
27
28 struct tcf_block_ext_info {
29         enum tcf_block_binder_type binder_type;
30         tcf_chain_head_change_t *chain_head_change;
31         void *chain_head_change_priv;
32 };
33
34 struct tcf_block_cb;
35 bool tcf_queue_work(struct work_struct *work);
36
37 #ifdef CONFIG_NET_CLS
38 struct tcf_chain *tcf_chain_get(struct tcf_block *block, u32 chain_index,
39                                 bool create);
40 void tcf_chain_put(struct tcf_chain *chain);
41 int tcf_block_get(struct tcf_block **p_block,
42                   struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
43                   struct netlink_ext_ack *extack);
44 int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
45                       struct tcf_block_ext_info *ei,
46                       struct netlink_ext_ack *extack);
47 void tcf_block_put(struct tcf_block *block);
48 void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
49                        struct tcf_block_ext_info *ei);
50
51 static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
52 {
53         return block->q;
54 }
55
56 static inline struct net_device *tcf_block_dev(struct tcf_block *block)
57 {
58         return tcf_block_q(block)->dev_queue->dev;
59 }
60
61 void *tcf_block_cb_priv(struct tcf_block_cb *block_cb);
62 struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block,
63                                          tc_setup_cb_t *cb, void *cb_ident);
64 void tcf_block_cb_incref(struct tcf_block_cb *block_cb);
65 unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb);
66 struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block,
67                                              tc_setup_cb_t *cb, void *cb_ident,
68                                              void *cb_priv);
69 int tcf_block_cb_register(struct tcf_block *block,
70                           tc_setup_cb_t *cb, void *cb_ident,
71                           void *cb_priv);
72 void __tcf_block_cb_unregister(struct tcf_block_cb *block_cb);
73 void tcf_block_cb_unregister(struct tcf_block *block,
74                              tc_setup_cb_t *cb, void *cb_ident);
75
76 int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
77                  struct tcf_result *res, bool compat_mode);
78
79 #else
80 static inline
81 int tcf_block_get(struct tcf_block **p_block,
82                   struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
83                   struct netlink_ext_ack *extack)
84 {
85         return 0;
86 }
87
88 static inline
89 int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
90                       struct tcf_block_ext_info *ei,
91                       struct netlink_ext_ack *extack)
92 {
93         return 0;
94 }
95
96 static inline void tcf_block_put(struct tcf_block *block)
97 {
98 }
99
100 static inline
101 void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
102                        struct tcf_block_ext_info *ei)
103 {
104 }
105
106 static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
107 {
108         return NULL;
109 }
110
111 static inline struct net_device *tcf_block_dev(struct tcf_block *block)
112 {
113         return NULL;
114 }
115
116 static inline
117 int tc_setup_cb_block_register(struct tcf_block *block, tc_setup_cb_t *cb,
118                                void *cb_priv)
119 {
120         return 0;
121 }
122
123 static inline
124 void tc_setup_cb_block_unregister(struct tcf_block *block, tc_setup_cb_t *cb,
125                                   void *cb_priv)
126 {
127 }
128
129 static inline
130 void *tcf_block_cb_priv(struct tcf_block_cb *block_cb)
131 {
132         return NULL;
133 }
134
135 static inline
136 struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block,
137                                          tc_setup_cb_t *cb, void *cb_ident)
138 {
139         return NULL;
140 }
141
142 static inline
143 void tcf_block_cb_incref(struct tcf_block_cb *block_cb)
144 {
145 }
146
147 static inline
148 unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb)
149 {
150         return 0;
151 }
152
153 static inline
154 struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block,
155                                              tc_setup_cb_t *cb, void *cb_ident,
156                                              void *cb_priv)
157 {
158         return NULL;
159 }
160
161 static inline
162 int tcf_block_cb_register(struct tcf_block *block,
163                           tc_setup_cb_t *cb, void *cb_ident,
164                           void *cb_priv)
165 {
166         return 0;
167 }
168
169 static inline
170 void __tcf_block_cb_unregister(struct tcf_block_cb *block_cb)
171 {
172 }
173
174 static inline
175 void tcf_block_cb_unregister(struct tcf_block *block,
176                              tc_setup_cb_t *cb, void *cb_ident)
177 {
178 }
179
180 static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp,
181                                struct tcf_result *res, bool compat_mode)
182 {
183         return TC_ACT_UNSPEC;
184 }
185 #endif
186
187 static inline unsigned long
188 __cls_set_class(unsigned long *clp, unsigned long cl)
189 {
190         return xchg(clp, cl);
191 }
192
193 static inline unsigned long
194 cls_set_class(struct Qdisc *q, unsigned long *clp, unsigned long cl)
195 {
196         unsigned long old_cl;
197
198         sch_tree_lock(q);
199         old_cl = __cls_set_class(clp, cl);
200         sch_tree_unlock(q);
201         return old_cl;
202 }
203
204 static inline void
205 tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
206 {
207         struct Qdisc *q = tp->chain->block->q;
208         unsigned long cl;
209
210         /* Check q as it is not set for shared blocks. In that case,
211          * setting class is not supported.
212          */
213         if (!q)
214                 return;
215         cl = q->ops->cl_ops->bind_tcf(q, base, r->classid);
216         cl = cls_set_class(q, &r->class, cl);
217         if (cl)
218                 q->ops->cl_ops->unbind_tcf(q, cl);
219 }
220
221 static inline void
222 tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
223 {
224         struct Qdisc *q = tp->chain->block->q;
225         unsigned long cl;
226
227         if (!q)
228                 return;
229         if ((cl = __cls_set_class(&r->class, 0)) != 0)
230                 q->ops->cl_ops->unbind_tcf(q, cl);
231 }
232
233 struct tcf_exts {
234 #ifdef CONFIG_NET_CLS_ACT
235         __u32   type; /* for backward compat(TCA_OLD_COMPAT) */
236         int nr_actions;
237         struct tc_action **actions;
238         struct net *net;
239 #endif
240         /* Map to export classifier specific extension TLV types to the
241          * generic extensions API. Unsupported extensions must be set to 0.
242          */
243         int action;
244         int police;
245 };
246
247 static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police)
248 {
249 #ifdef CONFIG_NET_CLS_ACT
250         exts->type = 0;
251         exts->nr_actions = 0;
252         exts->net = NULL;
253         exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *),
254                                 GFP_KERNEL);
255         if (!exts->actions)
256                 return -ENOMEM;
257 #endif
258         exts->action = action;
259         exts->police = police;
260         return 0;
261 }
262
263 /* Return false if the netns is being destroyed in cleanup_net(). Callers
264  * need to do cleanup synchronously in this case, otherwise may race with
265  * tc_action_net_exit(). Return true for other cases.
266  */
267 static inline bool tcf_exts_get_net(struct tcf_exts *exts)
268 {
269 #ifdef CONFIG_NET_CLS_ACT
270         exts->net = maybe_get_net(exts->net);
271         return exts->net != NULL;
272 #else
273         return true;
274 #endif
275 }
276
277 static inline void tcf_exts_put_net(struct tcf_exts *exts)
278 {
279 #ifdef CONFIG_NET_CLS_ACT
280         if (exts->net)
281                 put_net(exts->net);
282 #endif
283 }
284
285 static inline void tcf_exts_to_list(const struct tcf_exts *exts,
286                                     struct list_head *actions)
287 {
288 #ifdef CONFIG_NET_CLS_ACT
289         int i;
290
291         for (i = 0; i < exts->nr_actions; i++) {
292                 struct tc_action *a = exts->actions[i];
293
294                 list_add_tail(&a->list, actions);
295         }
296 #endif
297 }
298
299 static inline void
300 tcf_exts_stats_update(const struct tcf_exts *exts,
301                       u64 bytes, u64 packets, u64 lastuse)
302 {
303 #ifdef CONFIG_NET_CLS_ACT
304         int i;
305
306         preempt_disable();
307
308         for (i = 0; i < exts->nr_actions; i++) {
309                 struct tc_action *a = exts->actions[i];
310
311                 tcf_action_stats_update(a, bytes, packets, lastuse);
312         }
313
314         preempt_enable();
315 #endif
316 }
317
318 /**
319  * tcf_exts_has_actions - check if at least one action is present
320  * @exts: tc filter extensions handle
321  *
322  * Returns true if at least one action is present.
323  */
324 static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
325 {
326 #ifdef CONFIG_NET_CLS_ACT
327         return exts->nr_actions;
328 #else
329         return false;
330 #endif
331 }
332
333 /**
334  * tcf_exts_has_one_action - check if exactly one action is present
335  * @exts: tc filter extensions handle
336  *
337  * Returns true if exactly one action is present.
338  */
339 static inline bool tcf_exts_has_one_action(struct tcf_exts *exts)
340 {
341 #ifdef CONFIG_NET_CLS_ACT
342         return exts->nr_actions == 1;
343 #else
344         return false;
345 #endif
346 }
347
348 /**
349  * tcf_exts_exec - execute tc filter extensions
350  * @skb: socket buffer
351  * @exts: tc filter extensions handle
352  * @res: desired result
353  *
354  * Executes all configured extensions. Returns TC_ACT_OK on a normal execution,
355  * a negative number if the filter must be considered unmatched or
356  * a positive action code (TC_ACT_*) which must be returned to the
357  * underlying layer.
358  */
359 static inline int
360 tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
361               struct tcf_result *res)
362 {
363 #ifdef CONFIG_NET_CLS_ACT
364         return tcf_action_exec(skb, exts->actions, exts->nr_actions, res);
365 #endif
366         return TC_ACT_OK;
367 }
368
369 int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
370                       struct nlattr **tb, struct nlattr *rate_tlv,
371                       struct tcf_exts *exts, bool ovr);
372 void tcf_exts_destroy(struct tcf_exts *exts);
373 void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
374 int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
375 int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
376
377 /**
378  * struct tcf_pkt_info - packet information
379  */
380 struct tcf_pkt_info {
381         unsigned char *         ptr;
382         int                     nexthdr;
383 };
384
385 #ifdef CONFIG_NET_EMATCH
386
387 struct tcf_ematch_ops;
388
389 /**
390  * struct tcf_ematch - extended match (ematch)
391  * 
392  * @matchid: identifier to allow userspace to reidentify a match
393  * @flags: flags specifying attributes and the relation to other matches
394  * @ops: the operations lookup table of the corresponding ematch module
395  * @datalen: length of the ematch specific configuration data
396  * @data: ematch specific data
397  */
398 struct tcf_ematch {
399         struct tcf_ematch_ops * ops;
400         unsigned long           data;
401         unsigned int            datalen;
402         u16                     matchid;
403         u16                     flags;
404         struct net              *net;
405 };
406
407 static inline int tcf_em_is_container(struct tcf_ematch *em)
408 {
409         return !em->ops;
410 }
411
412 static inline int tcf_em_is_simple(struct tcf_ematch *em)
413 {
414         return em->flags & TCF_EM_SIMPLE;
415 }
416
417 static inline int tcf_em_is_inverted(struct tcf_ematch *em)
418 {
419         return em->flags & TCF_EM_INVERT;
420 }
421
422 static inline int tcf_em_last_match(struct tcf_ematch *em)
423 {
424         return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END;
425 }
426
427 static inline int tcf_em_early_end(struct tcf_ematch *em, int result)
428 {
429         if (tcf_em_last_match(em))
430                 return 1;
431
432         if (result == 0 && em->flags & TCF_EM_REL_AND)
433                 return 1;
434
435         if (result != 0 && em->flags & TCF_EM_REL_OR)
436                 return 1;
437
438         return 0;
439 }
440         
441 /**
442  * struct tcf_ematch_tree - ematch tree handle
443  *
444  * @hdr: ematch tree header supplied by userspace
445  * @matches: array of ematches
446  */
447 struct tcf_ematch_tree {
448         struct tcf_ematch_tree_hdr hdr;
449         struct tcf_ematch *     matches;
450         
451 };
452
453 /**
454  * struct tcf_ematch_ops - ematch module operations
455  * 
456  * @kind: identifier (kind) of this ematch module
457  * @datalen: length of expected configuration data (optional)
458  * @change: called during validation (optional)
459  * @match: called during ematch tree evaluation, must return 1/0
460  * @destroy: called during destroyage (optional)
461  * @dump: called during dumping process (optional)
462  * @owner: owner, must be set to THIS_MODULE
463  * @link: link to previous/next ematch module (internal use)
464  */
465 struct tcf_ematch_ops {
466         int                     kind;
467         int                     datalen;
468         int                     (*change)(struct net *net, void *,
469                                           int, struct tcf_ematch *);
470         int                     (*match)(struct sk_buff *, struct tcf_ematch *,
471                                          struct tcf_pkt_info *);
472         void                    (*destroy)(struct tcf_ematch *);
473         int                     (*dump)(struct sk_buff *, struct tcf_ematch *);
474         struct module           *owner;
475         struct list_head        link;
476 };
477
478 int tcf_em_register(struct tcf_ematch_ops *);
479 void tcf_em_unregister(struct tcf_ematch_ops *);
480 int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
481                          struct tcf_ematch_tree *);
482 void tcf_em_tree_destroy(struct tcf_ematch_tree *);
483 int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
484 int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
485                         struct tcf_pkt_info *);
486
487 /**
488  * tcf_em_tree_match - evaulate an ematch tree
489  *
490  * @skb: socket buffer of the packet in question
491  * @tree: ematch tree to be used for evaluation
492  * @info: packet information examined by classifier
493  *
494  * This function matches @skb against the ematch tree in @tree by going
495  * through all ematches respecting their logic relations returning
496  * as soon as the result is obvious.
497  *
498  * Returns 1 if the ematch tree as-one matches, no ematches are configured
499  * or ematch is not enabled in the kernel, otherwise 0 is returned.
500  */
501 static inline int tcf_em_tree_match(struct sk_buff *skb,
502                                     struct tcf_ematch_tree *tree,
503                                     struct tcf_pkt_info *info)
504 {
505         if (tree->hdr.nmatches)
506                 return __tcf_em_tree_match(skb, tree, info);
507         else
508                 return 1;
509 }
510
511 #define MODULE_ALIAS_TCF_EMATCH(kind)   MODULE_ALIAS("ematch-kind-" __stringify(kind))
512
513 #else /* CONFIG_NET_EMATCH */
514
515 struct tcf_ematch_tree {
516 };
517
518 #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0)
519 #define tcf_em_tree_destroy(t) do { (void)(t); } while(0)
520 #define tcf_em_tree_dump(skb, t, tlv) (0)
521 #define tcf_em_tree_match(skb, t, info) ((void)(info), 1)
522
523 #endif /* CONFIG_NET_EMATCH */
524
525 static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
526 {
527         switch (layer) {
528                 case TCF_LAYER_LINK:
529                         return skb->data;
530                 case TCF_LAYER_NETWORK:
531                         return skb_network_header(skb);
532                 case TCF_LAYER_TRANSPORT:
533                         return skb_transport_header(skb);
534         }
535
536         return NULL;
537 }
538
539 static inline int tcf_valid_offset(const struct sk_buff *skb,
540                                    const unsigned char *ptr, const int len)
541 {
542         return likely((ptr + len) <= skb_tail_pointer(skb) &&
543                       ptr >= skb->head &&
544                       (ptr <= (ptr + len)));
545 }
546
547 #ifdef CONFIG_NET_CLS_IND
548 #include <net/net_namespace.h>
549
550 static inline int
551 tcf_change_indev(struct net *net, struct nlattr *indev_tlv)
552 {
553         char indev[IFNAMSIZ];
554         struct net_device *dev;
555
556         if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ)
557                 return -EINVAL;
558         dev = __dev_get_by_name(net, indev);
559         if (!dev)
560                 return -ENODEV;
561         return dev->ifindex;
562 }
563
564 static inline bool
565 tcf_match_indev(struct sk_buff *skb, int ifindex)
566 {
567         if (!ifindex)
568                 return true;
569         if  (!skb->skb_iif)
570                 return false;
571         return ifindex == skb->skb_iif;
572 }
573 #endif /* CONFIG_NET_CLS_IND */
574
575 int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts,
576                      enum tc_setup_type type, void *type_data, bool err_stop);
577
578 enum tc_block_command {
579         TC_BLOCK_BIND,
580         TC_BLOCK_UNBIND,
581 };
582
583 struct tc_block_offload {
584         enum tc_block_command command;
585         enum tcf_block_binder_type binder_type;
586         struct tcf_block *block;
587 };
588
589 struct tc_cls_common_offload {
590         u32 chain_index;
591         __be16 protocol;
592         u32 prio;
593 };
594
595 static inline void
596 tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common,
597                            const struct tcf_proto *tp)
598 {
599         cls_common->chain_index = tp->chain->index;
600         cls_common->protocol = tp->protocol;
601         cls_common->prio = tp->prio;
602 }
603
604 struct tc_cls_u32_knode {
605         struct tcf_exts *exts;
606         struct tc_u32_sel *sel;
607         u32 handle;
608         u32 val;
609         u32 mask;
610         u32 link_handle;
611         u8 fshift;
612 };
613
614 struct tc_cls_u32_hnode {
615         u32 handle;
616         u32 prio;
617         unsigned int divisor;
618 };
619
620 enum tc_clsu32_command {
621         TC_CLSU32_NEW_KNODE,
622         TC_CLSU32_REPLACE_KNODE,
623         TC_CLSU32_DELETE_KNODE,
624         TC_CLSU32_NEW_HNODE,
625         TC_CLSU32_REPLACE_HNODE,
626         TC_CLSU32_DELETE_HNODE,
627 };
628
629 struct tc_cls_u32_offload {
630         struct tc_cls_common_offload common;
631         /* knode values */
632         enum tc_clsu32_command command;
633         union {
634                 struct tc_cls_u32_knode knode;
635                 struct tc_cls_u32_hnode hnode;
636         };
637 };
638
639 static inline bool tc_can_offload(const struct net_device *dev)
640 {
641         return dev->features & NETIF_F_HW_TC;
642 }
643
644 static inline bool tc_skip_hw(u32 flags)
645 {
646         return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false;
647 }
648
649 static inline bool tc_skip_sw(u32 flags)
650 {
651         return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false;
652 }
653
654 /* SKIP_HW and SKIP_SW are mutually exclusive flags. */
655 static inline bool tc_flags_valid(u32 flags)
656 {
657         if (flags & ~(TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW))
658                 return false;
659
660         if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW)))
661                 return false;
662
663         return true;
664 }
665
666 static inline bool tc_in_hw(u32 flags)
667 {
668         return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false;
669 }
670
671 enum tc_fl_command {
672         TC_CLSFLOWER_REPLACE,
673         TC_CLSFLOWER_DESTROY,
674         TC_CLSFLOWER_STATS,
675 };
676
677 struct tc_cls_flower_offload {
678         struct tc_cls_common_offload common;
679         enum tc_fl_command command;
680         unsigned long cookie;
681         struct flow_dissector *dissector;
682         struct fl_flow_key *mask;
683         struct fl_flow_key *key;
684         struct tcf_exts *exts;
685         u32 classid;
686 };
687
688 enum tc_matchall_command {
689         TC_CLSMATCHALL_REPLACE,
690         TC_CLSMATCHALL_DESTROY,
691 };
692
693 struct tc_cls_matchall_offload {
694         struct tc_cls_common_offload common;
695         enum tc_matchall_command command;
696         struct tcf_exts *exts;
697         unsigned long cookie;
698 };
699
700 enum tc_clsbpf_command {
701         TC_CLSBPF_OFFLOAD,
702         TC_CLSBPF_STATS,
703 };
704
705 struct tc_cls_bpf_offload {
706         struct tc_cls_common_offload common;
707         enum tc_clsbpf_command command;
708         struct tcf_exts *exts;
709         struct bpf_prog *prog;
710         struct bpf_prog *oldprog;
711         const char *name;
712         bool exts_integrated;
713         u32 gen_flags;
714 };
715
716 struct tc_mqprio_qopt_offload {
717         /* struct tc_mqprio_qopt must always be the first element */
718         struct tc_mqprio_qopt qopt;
719         u16 mode;
720         u16 shaper;
721         u32 flags;
722         u64 min_rate[TC_QOPT_MAX_QUEUE];
723         u64 max_rate[TC_QOPT_MAX_QUEUE];
724 };
725
726 /* This structure holds cookie structure that is passed from user
727  * to the kernel for actions and classifiers
728  */
729 struct tc_cookie {
730         u8  *data;
731         u32 len;
732 };
733
734 struct tc_qopt_offload_stats {
735         struct gnet_stats_basic_packed *bstats;
736         struct gnet_stats_queue *qstats;
737 };
738
739 enum tc_red_command {
740         TC_RED_REPLACE,
741         TC_RED_DESTROY,
742         TC_RED_STATS,
743         TC_RED_XSTATS,
744 };
745
746 struct tc_red_qopt_offload_params {
747         u32 min;
748         u32 max;
749         u32 probability;
750         bool is_ecn;
751         struct gnet_stats_queue *qstats;
752 };
753
754 struct tc_red_qopt_offload {
755         enum tc_red_command command;
756         u32 handle;
757         u32 parent;
758         union {
759                 struct tc_red_qopt_offload_params set;
760                 struct tc_qopt_offload_stats stats;
761                 struct red_stats *xstats;
762         };
763 };
764
765 enum tc_prio_command {
766         TC_PRIO_REPLACE,
767         TC_PRIO_DESTROY,
768         TC_PRIO_STATS,
769 };
770
771 struct tc_prio_qopt_offload_params {
772         int bands;
773         u8 priomap[TC_PRIO_MAX + 1];
774         /* In case that a prio qdisc is offloaded and now is changed to a
775          * non-offloadedable config, it needs to update the backlog & qlen
776          * values to negate the HW backlog & qlen values (and only them).
777          */
778         struct gnet_stats_queue *qstats;
779 };
780
781 struct tc_prio_qopt_offload {
782         enum tc_prio_command command;
783         u32 handle;
784         u32 parent;
785         union {
786                 struct tc_prio_qopt_offload_params replace_params;
787                 struct tc_qopt_offload_stats stats;
788         };
789 };
790 #endif