Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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