| .. | .. |
|---|
| 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 |
|---|