.. | .. |
---|
6 | 6 | #include <linux/workqueue.h> |
---|
7 | 7 | #include <net/sch_generic.h> |
---|
8 | 8 | #include <net/act_api.h> |
---|
| 9 | +#include <net/net_namespace.h> |
---|
9 | 10 | |
---|
10 | 11 | /* TC action not accessible from user space */ |
---|
11 | | -#define TC_ACT_REINSERT (TC_ACT_VALUE_MAX + 1) |
---|
| 12 | +#define TC_ACT_CONSUMED (TC_ACT_VALUE_MAX + 1) |
---|
12 | 13 | |
---|
13 | 14 | /* Basic packet classifier frontend definitions. */ |
---|
14 | 15 | |
---|
.. | .. |
---|
16 | 17 | int stop; |
---|
17 | 18 | int skip; |
---|
18 | 19 | int count; |
---|
| 20 | + bool nonempty; |
---|
19 | 21 | unsigned long cookie; |
---|
20 | 22 | int (*fn)(struct tcf_proto *, void *node, struct tcf_walker *); |
---|
21 | 23 | }; |
---|
.. | .. |
---|
23 | 25 | int register_tcf_proto_ops(struct tcf_proto_ops *ops); |
---|
24 | 26 | int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); |
---|
25 | 27 | |
---|
26 | | -enum tcf_block_binder_type { |
---|
27 | | - TCF_BLOCK_BINDER_TYPE_UNSPEC, |
---|
28 | | - TCF_BLOCK_BINDER_TYPE_CLSACT_INGRESS, |
---|
29 | | - TCF_BLOCK_BINDER_TYPE_CLSACT_EGRESS, |
---|
30 | | -}; |
---|
31 | | - |
---|
32 | 28 | struct tcf_block_ext_info { |
---|
33 | | - enum tcf_block_binder_type binder_type; |
---|
| 29 | + enum flow_block_binder_type binder_type; |
---|
34 | 30 | tcf_chain_head_change_t *chain_head_change; |
---|
35 | 31 | void *chain_head_change_priv; |
---|
36 | 32 | u32 block_index; |
---|
| 33 | +}; |
---|
| 34 | + |
---|
| 35 | +struct tcf_qevent { |
---|
| 36 | + struct tcf_block *block; |
---|
| 37 | + struct tcf_block_ext_info info; |
---|
| 38 | + struct tcf_proto __rcu *filter_chain; |
---|
37 | 39 | }; |
---|
38 | 40 | |
---|
39 | 41 | struct tcf_block_cb; |
---|
.. | .. |
---|
43 | 45 | struct tcf_chain *tcf_chain_get_by_act(struct tcf_block *block, |
---|
44 | 46 | u32 chain_index); |
---|
45 | 47 | void tcf_chain_put_by_act(struct tcf_chain *chain); |
---|
| 48 | +struct tcf_chain *tcf_get_next_chain(struct tcf_block *block, |
---|
| 49 | + struct tcf_chain *chain); |
---|
| 50 | +struct tcf_proto *tcf_get_next_proto(struct tcf_chain *chain, |
---|
| 51 | + struct tcf_proto *tp, bool rtnl_held); |
---|
46 | 52 | void tcf_block_netif_keep_dst(struct tcf_block *block); |
---|
47 | 53 | int tcf_block_get(struct tcf_block **p_block, |
---|
48 | 54 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, |
---|
.. | .. |
---|
59 | 65 | return block->index; |
---|
60 | 66 | } |
---|
61 | 67 | |
---|
| 68 | +static inline bool tcf_block_non_null_shared(struct tcf_block *block) |
---|
| 69 | +{ |
---|
| 70 | + return block && block->index; |
---|
| 71 | +} |
---|
| 72 | + |
---|
62 | 73 | static inline struct Qdisc *tcf_block_q(struct tcf_block *block) |
---|
63 | 74 | { |
---|
64 | 75 | WARN_ON(tcf_block_shared(block)); |
---|
65 | 76 | return block->q; |
---|
66 | 77 | } |
---|
67 | 78 | |
---|
68 | | -static inline struct net_device *tcf_block_dev(struct tcf_block *block) |
---|
69 | | -{ |
---|
70 | | - return tcf_block_q(block)->dev_queue->dev; |
---|
71 | | -} |
---|
72 | | - |
---|
73 | | -void *tcf_block_cb_priv(struct tcf_block_cb *block_cb); |
---|
74 | | -struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block, |
---|
75 | | - tc_setup_cb_t *cb, void *cb_ident); |
---|
76 | | -void tcf_block_cb_incref(struct tcf_block_cb *block_cb); |
---|
77 | | -unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb); |
---|
78 | | -struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block, |
---|
79 | | - tc_setup_cb_t *cb, void *cb_ident, |
---|
80 | | - void *cb_priv, |
---|
81 | | - struct netlink_ext_ack *extack); |
---|
82 | | -int tcf_block_cb_register(struct tcf_block *block, |
---|
83 | | - tc_setup_cb_t *cb, void *cb_ident, |
---|
84 | | - void *cb_priv, struct netlink_ext_ack *extack); |
---|
85 | | -void __tcf_block_cb_unregister(struct tcf_block *block, |
---|
86 | | - struct tcf_block_cb *block_cb); |
---|
87 | | -void tcf_block_cb_unregister(struct tcf_block *block, |
---|
88 | | - tc_setup_cb_t *cb, void *cb_ident); |
---|
89 | | - |
---|
90 | 79 | int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, |
---|
91 | 80 | struct tcf_result *res, bool compat_mode); |
---|
| 81 | +int tcf_classify_ingress(struct sk_buff *skb, |
---|
| 82 | + const struct tcf_block *ingress_block, |
---|
| 83 | + const struct tcf_proto *tp, struct tcf_result *res, |
---|
| 84 | + bool compat_mode); |
---|
92 | 85 | |
---|
93 | 86 | #else |
---|
| 87 | +static inline bool tcf_block_shared(struct tcf_block *block) |
---|
| 88 | +{ |
---|
| 89 | + return false; |
---|
| 90 | +} |
---|
| 91 | + |
---|
| 92 | +static inline bool tcf_block_non_null_shared(struct tcf_block *block) |
---|
| 93 | +{ |
---|
| 94 | + return false; |
---|
| 95 | +} |
---|
| 96 | + |
---|
94 | 97 | static inline |
---|
95 | 98 | int tcf_block_get(struct tcf_block **p_block, |
---|
96 | 99 | struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, |
---|
.. | .. |
---|
122 | 125 | return NULL; |
---|
123 | 126 | } |
---|
124 | 127 | |
---|
125 | | -static inline struct net_device *tcf_block_dev(struct tcf_block *block) |
---|
126 | | -{ |
---|
127 | | - return NULL; |
---|
128 | | -} |
---|
129 | | - |
---|
130 | 128 | static inline |
---|
131 | | -int tc_setup_cb_block_register(struct tcf_block *block, tc_setup_cb_t *cb, |
---|
| 129 | +int tc_setup_cb_block_register(struct tcf_block *block, flow_setup_cb_t *cb, |
---|
132 | 130 | void *cb_priv) |
---|
133 | 131 | { |
---|
134 | 132 | return 0; |
---|
135 | 133 | } |
---|
136 | 134 | |
---|
137 | 135 | static inline |
---|
138 | | -void tc_setup_cb_block_unregister(struct tcf_block *block, tc_setup_cb_t *cb, |
---|
| 136 | +void tc_setup_cb_block_unregister(struct tcf_block *block, flow_setup_cb_t *cb, |
---|
139 | 137 | void *cb_priv) |
---|
140 | | -{ |
---|
141 | | -} |
---|
142 | | - |
---|
143 | | -static inline |
---|
144 | | -void *tcf_block_cb_priv(struct tcf_block_cb *block_cb) |
---|
145 | | -{ |
---|
146 | | - return NULL; |
---|
147 | | -} |
---|
148 | | - |
---|
149 | | -static inline |
---|
150 | | -struct tcf_block_cb *tcf_block_cb_lookup(struct tcf_block *block, |
---|
151 | | - tc_setup_cb_t *cb, void *cb_ident) |
---|
152 | | -{ |
---|
153 | | - return NULL; |
---|
154 | | -} |
---|
155 | | - |
---|
156 | | -static inline |
---|
157 | | -void tcf_block_cb_incref(struct tcf_block_cb *block_cb) |
---|
158 | | -{ |
---|
159 | | -} |
---|
160 | | - |
---|
161 | | -static inline |
---|
162 | | -unsigned int tcf_block_cb_decref(struct tcf_block_cb *block_cb) |
---|
163 | | -{ |
---|
164 | | - return 0; |
---|
165 | | -} |
---|
166 | | - |
---|
167 | | -static inline |
---|
168 | | -struct tcf_block_cb *__tcf_block_cb_register(struct tcf_block *block, |
---|
169 | | - tc_setup_cb_t *cb, void *cb_ident, |
---|
170 | | - void *cb_priv, |
---|
171 | | - struct netlink_ext_ack *extack) |
---|
172 | | -{ |
---|
173 | | - return NULL; |
---|
174 | | -} |
---|
175 | | - |
---|
176 | | -static inline |
---|
177 | | -int tcf_block_cb_register(struct tcf_block *block, |
---|
178 | | - tc_setup_cb_t *cb, void *cb_ident, |
---|
179 | | - void *cb_priv, struct netlink_ext_ack *extack) |
---|
180 | | -{ |
---|
181 | | - return 0; |
---|
182 | | -} |
---|
183 | | - |
---|
184 | | -static inline |
---|
185 | | -void __tcf_block_cb_unregister(struct tcf_block *block, |
---|
186 | | - struct tcf_block_cb *block_cb) |
---|
187 | | -{ |
---|
188 | | -} |
---|
189 | | - |
---|
190 | | -static inline |
---|
191 | | -void tcf_block_cb_unregister(struct tcf_block *block, |
---|
192 | | - tc_setup_cb_t *cb, void *cb_ident) |
---|
193 | 138 | { |
---|
194 | 139 | } |
---|
195 | 140 | |
---|
.. | .. |
---|
198 | 143 | { |
---|
199 | 144 | return TC_ACT_UNSPEC; |
---|
200 | 145 | } |
---|
| 146 | + |
---|
| 147 | +static inline int tcf_classify_ingress(struct sk_buff *skb, |
---|
| 148 | + const struct tcf_block *ingress_block, |
---|
| 149 | + const struct tcf_proto *tp, |
---|
| 150 | + struct tcf_result *res, bool compat_mode) |
---|
| 151 | +{ |
---|
| 152 | + return TC_ACT_UNSPEC; |
---|
| 153 | +} |
---|
| 154 | + |
---|
201 | 155 | #endif |
---|
202 | 156 | |
---|
203 | 157 | static inline unsigned long |
---|
.. | .. |
---|
265 | 219 | int police; |
---|
266 | 220 | }; |
---|
267 | 221 | |
---|
268 | | -static inline int tcf_exts_init(struct tcf_exts *exts, int action, int police) |
---|
| 222 | +static inline int tcf_exts_init(struct tcf_exts *exts, struct net *net, |
---|
| 223 | + int action, int police) |
---|
269 | 224 | { |
---|
270 | 225 | #ifdef CONFIG_NET_CLS_ACT |
---|
271 | 226 | exts->type = 0; |
---|
272 | 227 | exts->nr_actions = 0; |
---|
273 | | - exts->net = NULL; |
---|
| 228 | + exts->net = net; |
---|
274 | 229 | exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *), |
---|
275 | 230 | GFP_KERNEL); |
---|
276 | 231 | if (!exts->actions) |
---|
.. | .. |
---|
313 | 268 | |
---|
314 | 269 | static inline void |
---|
315 | 270 | tcf_exts_stats_update(const struct tcf_exts *exts, |
---|
316 | | - u64 bytes, u64 packets, u64 lastuse) |
---|
| 271 | + u64 bytes, u64 packets, u64 drops, u64 lastuse, |
---|
| 272 | + u8 used_hw_stats, bool used_hw_stats_valid) |
---|
317 | 273 | { |
---|
318 | 274 | #ifdef CONFIG_NET_CLS_ACT |
---|
319 | 275 | int i; |
---|
.. | .. |
---|
323 | 279 | for (i = 0; i < exts->nr_actions; i++) { |
---|
324 | 280 | struct tc_action *a = exts->actions[i]; |
---|
325 | 281 | |
---|
326 | | - tcf_action_stats_update(a, bytes, packets, lastuse); |
---|
| 282 | + tcf_action_stats_update(a, bytes, packets, drops, |
---|
| 283 | + lastuse, true); |
---|
| 284 | + a->used_hw_stats = used_hw_stats; |
---|
| 285 | + a->used_hw_stats_valid = used_hw_stats_valid; |
---|
327 | 286 | } |
---|
328 | 287 | |
---|
329 | 288 | preempt_enable(); |
---|
.. | .. |
---|
342 | 301 | return exts->nr_actions; |
---|
343 | 302 | #else |
---|
344 | 303 | return false; |
---|
345 | | -#endif |
---|
346 | | -} |
---|
347 | | - |
---|
348 | | -/** |
---|
349 | | - * tcf_exts_has_one_action - check if exactly one action is present |
---|
350 | | - * @exts: tc filter extensions handle |
---|
351 | | - * |
---|
352 | | - * Returns true if exactly one action is present. |
---|
353 | | - */ |
---|
354 | | -static inline bool tcf_exts_has_one_action(struct tcf_exts *exts) |
---|
355 | | -{ |
---|
356 | | -#ifdef CONFIG_NET_CLS_ACT |
---|
357 | | - return exts->nr_actions == 1; |
---|
358 | | -#else |
---|
359 | | - return false; |
---|
360 | | -#endif |
---|
361 | | -} |
---|
362 | | - |
---|
363 | | -static inline struct tc_action *tcf_exts_first_action(struct tcf_exts *exts) |
---|
364 | | -{ |
---|
365 | | -#ifdef CONFIG_NET_CLS_ACT |
---|
366 | | - return exts->actions[0]; |
---|
367 | | -#else |
---|
368 | | - return NULL; |
---|
369 | 304 | #endif |
---|
370 | 305 | } |
---|
371 | 306 | |
---|
.. | .. |
---|
392 | 327 | |
---|
393 | 328 | int tcf_exts_validate(struct net *net, struct tcf_proto *tp, |
---|
394 | 329 | struct nlattr **tb, struct nlattr *rate_tlv, |
---|
395 | | - struct tcf_exts *exts, bool ovr, |
---|
| 330 | + struct tcf_exts *exts, bool ovr, bool rtnl_held, |
---|
396 | 331 | struct netlink_ext_ack *extack); |
---|
397 | 332 | void tcf_exts_destroy(struct tcf_exts *exts); |
---|
398 | 333 | void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src); |
---|
399 | 334 | int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts); |
---|
| 335 | +int tcf_exts_terse_dump(struct sk_buff *skb, struct tcf_exts *exts); |
---|
400 | 336 | int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts); |
---|
401 | 337 | |
---|
402 | 338 | /** |
---|
.. | .. |
---|
569 | 505 | (ptr <= (ptr + len))); |
---|
570 | 506 | } |
---|
571 | 507 | |
---|
572 | | -#ifdef CONFIG_NET_CLS_IND |
---|
573 | | -#include <net/net_namespace.h> |
---|
574 | | - |
---|
575 | 508 | static inline int |
---|
576 | 509 | tcf_change_indev(struct net *net, struct nlattr *indev_tlv, |
---|
577 | 510 | struct netlink_ext_ack *extack) |
---|
.. | .. |
---|
580 | 513 | struct net_device *dev; |
---|
581 | 514 | |
---|
582 | 515 | if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) { |
---|
583 | | - NL_SET_ERR_MSG(extack, "Interface name too long"); |
---|
| 516 | + NL_SET_ERR_MSG_ATTR(extack, indev_tlv, |
---|
| 517 | + "Interface name too long"); |
---|
584 | 518 | return -EINVAL; |
---|
585 | 519 | } |
---|
586 | 520 | dev = __dev_get_by_name(net, indev); |
---|
587 | | - if (!dev) |
---|
| 521 | + if (!dev) { |
---|
| 522 | + NL_SET_ERR_MSG_ATTR(extack, indev_tlv, |
---|
| 523 | + "Network device not found"); |
---|
588 | 524 | return -ENODEV; |
---|
| 525 | + } |
---|
589 | 526 | return dev->ifindex; |
---|
590 | 527 | } |
---|
591 | 528 | |
---|
.. | .. |
---|
598 | 535 | return false; |
---|
599 | 536 | return ifindex == skb->skb_iif; |
---|
600 | 537 | } |
---|
601 | | -#endif /* CONFIG_NET_CLS_IND */ |
---|
602 | 538 | |
---|
603 | | -int tc_setup_cb_call(struct tcf_block *block, struct tcf_exts *exts, |
---|
604 | | - enum tc_setup_type type, void *type_data, bool err_stop); |
---|
| 539 | +int tc_setup_flow_action(struct flow_action *flow_action, |
---|
| 540 | + const struct tcf_exts *exts); |
---|
| 541 | +void tc_cleanup_flow_action(struct flow_action *flow_action); |
---|
605 | 542 | |
---|
606 | | -enum tc_block_command { |
---|
607 | | - TC_BLOCK_BIND, |
---|
608 | | - TC_BLOCK_UNBIND, |
---|
609 | | -}; |
---|
| 543 | +int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type, |
---|
| 544 | + void *type_data, bool err_stop, bool rtnl_held); |
---|
| 545 | +int tc_setup_cb_add(struct tcf_block *block, struct tcf_proto *tp, |
---|
| 546 | + enum tc_setup_type type, void *type_data, bool err_stop, |
---|
| 547 | + u32 *flags, unsigned int *in_hw_count, bool rtnl_held); |
---|
| 548 | +int tc_setup_cb_replace(struct tcf_block *block, struct tcf_proto *tp, |
---|
| 549 | + enum tc_setup_type type, void *type_data, bool err_stop, |
---|
| 550 | + u32 *old_flags, unsigned int *old_in_hw_count, |
---|
| 551 | + u32 *new_flags, unsigned int *new_in_hw_count, |
---|
| 552 | + bool rtnl_held); |
---|
| 553 | +int tc_setup_cb_destroy(struct tcf_block *block, struct tcf_proto *tp, |
---|
| 554 | + enum tc_setup_type type, void *type_data, bool err_stop, |
---|
| 555 | + u32 *flags, unsigned int *in_hw_count, bool rtnl_held); |
---|
| 556 | +int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp, |
---|
| 557 | + bool add, flow_setup_cb_t *cb, |
---|
| 558 | + enum tc_setup_type type, void *type_data, |
---|
| 559 | + void *cb_priv, u32 *flags, unsigned int *in_hw_count); |
---|
| 560 | +unsigned int tcf_exts_num_actions(struct tcf_exts *exts); |
---|
610 | 561 | |
---|
611 | | -struct tc_block_offload { |
---|
612 | | - enum tc_block_command command; |
---|
613 | | - enum tcf_block_binder_type binder_type; |
---|
614 | | - struct tcf_block *block; |
---|
615 | | - struct netlink_ext_ack *extack; |
---|
616 | | -}; |
---|
| 562 | +#ifdef CONFIG_NET_CLS_ACT |
---|
| 563 | +int tcf_qevent_init(struct tcf_qevent *qe, struct Qdisc *sch, |
---|
| 564 | + enum flow_block_binder_type binder_type, |
---|
| 565 | + struct nlattr *block_index_attr, |
---|
| 566 | + struct netlink_ext_ack *extack); |
---|
| 567 | +void tcf_qevent_destroy(struct tcf_qevent *qe, struct Qdisc *sch); |
---|
| 568 | +int tcf_qevent_validate_change(struct tcf_qevent *qe, struct nlattr *block_index_attr, |
---|
| 569 | + struct netlink_ext_ack *extack); |
---|
| 570 | +struct sk_buff *tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, struct sk_buff *skb, |
---|
| 571 | + struct sk_buff **to_free, int *ret); |
---|
| 572 | +int tcf_qevent_dump(struct sk_buff *skb, int attr_name, struct tcf_qevent *qe); |
---|
| 573 | +#else |
---|
| 574 | +static inline int tcf_qevent_init(struct tcf_qevent *qe, struct Qdisc *sch, |
---|
| 575 | + enum flow_block_binder_type binder_type, |
---|
| 576 | + struct nlattr *block_index_attr, |
---|
| 577 | + struct netlink_ext_ack *extack) |
---|
| 578 | +{ |
---|
| 579 | + return 0; |
---|
| 580 | +} |
---|
617 | 581 | |
---|
618 | | -struct tc_cls_common_offload { |
---|
619 | | - u32 chain_index; |
---|
620 | | - __be16 protocol; |
---|
621 | | - u32 prio; |
---|
622 | | - struct netlink_ext_ack *extack; |
---|
623 | | -}; |
---|
| 582 | +static inline void tcf_qevent_destroy(struct tcf_qevent *qe, struct Qdisc *sch) |
---|
| 583 | +{ |
---|
| 584 | +} |
---|
| 585 | + |
---|
| 586 | +static inline int tcf_qevent_validate_change(struct tcf_qevent *qe, struct nlattr *block_index_attr, |
---|
| 587 | + struct netlink_ext_ack *extack) |
---|
| 588 | +{ |
---|
| 589 | + return 0; |
---|
| 590 | +} |
---|
| 591 | + |
---|
| 592 | +static inline struct sk_buff * |
---|
| 593 | +tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, struct sk_buff *skb, |
---|
| 594 | + struct sk_buff **to_free, int *ret) |
---|
| 595 | +{ |
---|
| 596 | + return skb; |
---|
| 597 | +} |
---|
| 598 | + |
---|
| 599 | +static inline int tcf_qevent_dump(struct sk_buff *skb, int attr_name, struct tcf_qevent *qe) |
---|
| 600 | +{ |
---|
| 601 | + return 0; |
---|
| 602 | +} |
---|
| 603 | +#endif |
---|
624 | 604 | |
---|
625 | 605 | struct tc_cls_u32_knode { |
---|
626 | 606 | struct tcf_exts *exts; |
---|
| 607 | + struct tcf_result *res; |
---|
627 | 608 | struct tc_u32_sel *sel; |
---|
628 | 609 | u32 handle; |
---|
629 | 610 | u32 val; |
---|
.. | .. |
---|
648 | 629 | }; |
---|
649 | 630 | |
---|
650 | 631 | struct tc_cls_u32_offload { |
---|
651 | | - struct tc_cls_common_offload common; |
---|
| 632 | + struct flow_cls_common_offload common; |
---|
652 | 633 | /* knode values */ |
---|
653 | 634 | enum tc_clsu32_command command; |
---|
654 | 635 | union { |
---|
.. | .. |
---|
675 | 656 | |
---|
676 | 657 | static inline bool |
---|
677 | 658 | tc_cls_can_offload_and_chain0(const struct net_device *dev, |
---|
678 | | - struct tc_cls_common_offload *common) |
---|
| 659 | + struct flow_cls_common_offload *common) |
---|
679 | 660 | { |
---|
680 | 661 | if (!tc_can_offload_extack(dev, common->extack)) |
---|
681 | 662 | return false; |
---|
.. | .. |
---|
717 | 698 | } |
---|
718 | 699 | |
---|
719 | 700 | static inline void |
---|
720 | | -tc_cls_common_offload_init(struct tc_cls_common_offload *cls_common, |
---|
| 701 | +tc_cls_common_offload_init(struct flow_cls_common_offload *cls_common, |
---|
721 | 702 | const struct tcf_proto *tp, u32 flags, |
---|
722 | 703 | struct netlink_ext_ack *extack) |
---|
723 | 704 | { |
---|
724 | 705 | cls_common->chain_index = tp->chain->index; |
---|
725 | 706 | cls_common->protocol = tp->protocol; |
---|
726 | | - cls_common->prio = tp->prio; |
---|
| 707 | + cls_common->prio = tp->prio >> 16; |
---|
727 | 708 | if (tc_skip_sw(flags) || flags & TCA_CLS_FLAGS_VERBOSE) |
---|
728 | 709 | cls_common->extack = extack; |
---|
729 | 710 | } |
---|
730 | 711 | |
---|
731 | | -enum tc_fl_command { |
---|
732 | | - TC_CLSFLOWER_REPLACE, |
---|
733 | | - TC_CLSFLOWER_DESTROY, |
---|
734 | | - TC_CLSFLOWER_STATS, |
---|
735 | | - TC_CLSFLOWER_TMPLT_CREATE, |
---|
736 | | - TC_CLSFLOWER_TMPLT_DESTROY, |
---|
737 | | -}; |
---|
| 712 | +#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) |
---|
| 713 | +static inline struct tc_skb_ext *tc_skb_ext_alloc(struct sk_buff *skb) |
---|
| 714 | +{ |
---|
| 715 | + struct tc_skb_ext *tc_skb_ext = skb_ext_add(skb, TC_SKB_EXT); |
---|
738 | 716 | |
---|
739 | | -struct tc_cls_flower_offload { |
---|
740 | | - struct tc_cls_common_offload common; |
---|
741 | | - enum tc_fl_command command; |
---|
742 | | - unsigned long cookie; |
---|
743 | | - struct flow_dissector *dissector; |
---|
744 | | - struct fl_flow_key *mask; |
---|
745 | | - struct fl_flow_key *key; |
---|
746 | | - struct tcf_exts *exts; |
---|
747 | | - u32 classid; |
---|
748 | | -}; |
---|
| 717 | + if (tc_skb_ext) |
---|
| 718 | + memset(tc_skb_ext, 0, sizeof(*tc_skb_ext)); |
---|
| 719 | + return tc_skb_ext; |
---|
| 720 | +} |
---|
| 721 | +#endif |
---|
749 | 722 | |
---|
750 | 723 | enum tc_matchall_command { |
---|
751 | 724 | TC_CLSMATCHALL_REPLACE, |
---|
752 | 725 | TC_CLSMATCHALL_DESTROY, |
---|
| 726 | + TC_CLSMATCHALL_STATS, |
---|
753 | 727 | }; |
---|
754 | 728 | |
---|
755 | 729 | struct tc_cls_matchall_offload { |
---|
756 | | - struct tc_cls_common_offload common; |
---|
| 730 | + struct flow_cls_common_offload common; |
---|
757 | 731 | enum tc_matchall_command command; |
---|
758 | | - struct tcf_exts *exts; |
---|
| 732 | + struct flow_rule *rule; |
---|
| 733 | + struct flow_stats stats; |
---|
759 | 734 | unsigned long cookie; |
---|
760 | 735 | }; |
---|
761 | 736 | |
---|
.. | .. |
---|
765 | 740 | }; |
---|
766 | 741 | |
---|
767 | 742 | struct tc_cls_bpf_offload { |
---|
768 | | - struct tc_cls_common_offload common; |
---|
| 743 | + struct flow_cls_common_offload common; |
---|
769 | 744 | enum tc_clsbpf_command command; |
---|
770 | 745 | struct tcf_exts *exts; |
---|
771 | 746 | struct bpf_prog *prog; |
---|
.. | .. |
---|
802 | 777 | TC_MQ_CREATE, |
---|
803 | 778 | TC_MQ_DESTROY, |
---|
804 | 779 | TC_MQ_STATS, |
---|
| 780 | + TC_MQ_GRAFT, |
---|
| 781 | +}; |
---|
| 782 | + |
---|
| 783 | +struct tc_mq_opt_offload_graft_params { |
---|
| 784 | + unsigned long queue; |
---|
| 785 | + u32 child_handle; |
---|
805 | 786 | }; |
---|
806 | 787 | |
---|
807 | 788 | struct tc_mq_qopt_offload { |
---|
808 | 789 | enum tc_mq_command command; |
---|
809 | 790 | u32 handle; |
---|
810 | | - struct tc_qopt_offload_stats stats; |
---|
| 791 | + union { |
---|
| 792 | + struct tc_qopt_offload_stats stats; |
---|
| 793 | + struct tc_mq_opt_offload_graft_params graft_params; |
---|
| 794 | + }; |
---|
811 | 795 | }; |
---|
812 | 796 | |
---|
813 | 797 | enum tc_red_command { |
---|
.. | .. |
---|
815 | 799 | TC_RED_DESTROY, |
---|
816 | 800 | TC_RED_STATS, |
---|
817 | 801 | TC_RED_XSTATS, |
---|
| 802 | + TC_RED_GRAFT, |
---|
818 | 803 | }; |
---|
819 | 804 | |
---|
820 | 805 | struct tc_red_qopt_offload_params { |
---|
821 | 806 | u32 min; |
---|
822 | 807 | u32 max; |
---|
823 | 808 | u32 probability; |
---|
| 809 | + u32 limit; |
---|
824 | 810 | bool is_ecn; |
---|
| 811 | + bool is_harddrop; |
---|
| 812 | + bool is_nodrop; |
---|
825 | 813 | struct gnet_stats_queue *qstats; |
---|
826 | 814 | }; |
---|
827 | 815 | |
---|
.. | .. |
---|
833 | 821 | struct tc_red_qopt_offload_params set; |
---|
834 | 822 | struct tc_qopt_offload_stats stats; |
---|
835 | 823 | struct red_stats *xstats; |
---|
| 824 | + u32 child_handle; |
---|
| 825 | + }; |
---|
| 826 | +}; |
---|
| 827 | + |
---|
| 828 | +enum tc_gred_command { |
---|
| 829 | + TC_GRED_REPLACE, |
---|
| 830 | + TC_GRED_DESTROY, |
---|
| 831 | + TC_GRED_STATS, |
---|
| 832 | +}; |
---|
| 833 | + |
---|
| 834 | +struct tc_gred_vq_qopt_offload_params { |
---|
| 835 | + bool present; |
---|
| 836 | + u32 limit; |
---|
| 837 | + u32 prio; |
---|
| 838 | + u32 min; |
---|
| 839 | + u32 max; |
---|
| 840 | + bool is_ecn; |
---|
| 841 | + bool is_harddrop; |
---|
| 842 | + u32 probability; |
---|
| 843 | + /* Only need backlog, see struct tc_prio_qopt_offload_params */ |
---|
| 844 | + u32 *backlog; |
---|
| 845 | +}; |
---|
| 846 | + |
---|
| 847 | +struct tc_gred_qopt_offload_params { |
---|
| 848 | + bool grio_on; |
---|
| 849 | + bool wred_on; |
---|
| 850 | + unsigned int dp_cnt; |
---|
| 851 | + unsigned int dp_def; |
---|
| 852 | + struct gnet_stats_queue *qstats; |
---|
| 853 | + struct tc_gred_vq_qopt_offload_params tab[MAX_DPs]; |
---|
| 854 | +}; |
---|
| 855 | + |
---|
| 856 | +struct tc_gred_qopt_offload_stats { |
---|
| 857 | + struct gnet_stats_basic_packed bstats[MAX_DPs]; |
---|
| 858 | + struct gnet_stats_queue qstats[MAX_DPs]; |
---|
| 859 | + struct red_stats *xstats[MAX_DPs]; |
---|
| 860 | +}; |
---|
| 861 | + |
---|
| 862 | +struct tc_gred_qopt_offload { |
---|
| 863 | + enum tc_gred_command command; |
---|
| 864 | + u32 handle; |
---|
| 865 | + u32 parent; |
---|
| 866 | + union { |
---|
| 867 | + struct tc_gred_qopt_offload_params set; |
---|
| 868 | + struct tc_gred_qopt_offload_stats stats; |
---|
836 | 869 | }; |
---|
837 | 870 | }; |
---|
838 | 871 | |
---|
.. | .. |
---|
846 | 879 | struct tc_prio_qopt_offload_params { |
---|
847 | 880 | int bands; |
---|
848 | 881 | u8 priomap[TC_PRIO_MAX + 1]; |
---|
849 | | - /* In case that a prio qdisc is offloaded and now is changed to a |
---|
850 | | - * non-offloadedable config, it needs to update the backlog & qlen |
---|
851 | | - * values to negate the HW backlog & qlen values (and only them). |
---|
| 882 | + /* At the point of un-offloading the Qdisc, the reported backlog and |
---|
| 883 | + * qlen need to be reduced by the portion that is in HW. |
---|
852 | 884 | */ |
---|
853 | 885 | struct gnet_stats_queue *qstats; |
---|
854 | 886 | }; |
---|
.. | .. |
---|
869 | 901 | }; |
---|
870 | 902 | }; |
---|
871 | 903 | |
---|
| 904 | +enum tc_root_command { |
---|
| 905 | + TC_ROOT_GRAFT, |
---|
| 906 | +}; |
---|
| 907 | + |
---|
| 908 | +struct tc_root_qopt_offload { |
---|
| 909 | + enum tc_root_command command; |
---|
| 910 | + u32 handle; |
---|
| 911 | + bool ingress; |
---|
| 912 | +}; |
---|
| 913 | + |
---|
| 914 | +enum tc_ets_command { |
---|
| 915 | + TC_ETS_REPLACE, |
---|
| 916 | + TC_ETS_DESTROY, |
---|
| 917 | + TC_ETS_STATS, |
---|
| 918 | + TC_ETS_GRAFT, |
---|
| 919 | +}; |
---|
| 920 | + |
---|
| 921 | +struct tc_ets_qopt_offload_replace_params { |
---|
| 922 | + unsigned int bands; |
---|
| 923 | + u8 priomap[TC_PRIO_MAX + 1]; |
---|
| 924 | + unsigned int quanta[TCQ_ETS_MAX_BANDS]; /* 0 for strict bands. */ |
---|
| 925 | + unsigned int weights[TCQ_ETS_MAX_BANDS]; |
---|
| 926 | + struct gnet_stats_queue *qstats; |
---|
| 927 | +}; |
---|
| 928 | + |
---|
| 929 | +struct tc_ets_qopt_offload_graft_params { |
---|
| 930 | + u8 band; |
---|
| 931 | + u32 child_handle; |
---|
| 932 | +}; |
---|
| 933 | + |
---|
| 934 | +struct tc_ets_qopt_offload { |
---|
| 935 | + enum tc_ets_command command; |
---|
| 936 | + u32 handle; |
---|
| 937 | + u32 parent; |
---|
| 938 | + union { |
---|
| 939 | + struct tc_ets_qopt_offload_replace_params replace_params; |
---|
| 940 | + struct tc_qopt_offload_stats stats; |
---|
| 941 | + struct tc_ets_qopt_offload_graft_params graft_params; |
---|
| 942 | + }; |
---|
| 943 | +}; |
---|
| 944 | + |
---|
| 945 | +enum tc_tbf_command { |
---|
| 946 | + TC_TBF_REPLACE, |
---|
| 947 | + TC_TBF_DESTROY, |
---|
| 948 | + TC_TBF_STATS, |
---|
| 949 | +}; |
---|
| 950 | + |
---|
| 951 | +struct tc_tbf_qopt_offload_replace_params { |
---|
| 952 | + struct psched_ratecfg rate; |
---|
| 953 | + u32 max_size; |
---|
| 954 | + struct gnet_stats_queue *qstats; |
---|
| 955 | +}; |
---|
| 956 | + |
---|
| 957 | +struct tc_tbf_qopt_offload { |
---|
| 958 | + enum tc_tbf_command command; |
---|
| 959 | + u32 handle; |
---|
| 960 | + u32 parent; |
---|
| 961 | + union { |
---|
| 962 | + struct tc_tbf_qopt_offload_replace_params replace_params; |
---|
| 963 | + struct tc_qopt_offload_stats stats; |
---|
| 964 | + }; |
---|
| 965 | +}; |
---|
| 966 | + |
---|
| 967 | +enum tc_fifo_command { |
---|
| 968 | + TC_FIFO_REPLACE, |
---|
| 969 | + TC_FIFO_DESTROY, |
---|
| 970 | + TC_FIFO_STATS, |
---|
| 971 | +}; |
---|
| 972 | + |
---|
| 973 | +struct tc_fifo_qopt_offload { |
---|
| 974 | + enum tc_fifo_command command; |
---|
| 975 | + u32 handle; |
---|
| 976 | + u32 parent; |
---|
| 977 | + union { |
---|
| 978 | + struct tc_qopt_offload_stats stats; |
---|
| 979 | + }; |
---|
| 980 | +}; |
---|
| 981 | + |
---|
872 | 982 | #endif |
---|