1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */ 21da177e4SLinus Torvalds #ifndef __NET_PKT_CLS_H 31da177e4SLinus Torvalds #define __NET_PKT_CLS_H 41da177e4SLinus Torvalds 51da177e4SLinus Torvalds #include <linux/pkt_cls.h> 67aa0045dSCong Wang #include <linux/workqueue.h> 71da177e4SLinus Torvalds #include <net/sch_generic.h> 81da177e4SLinus Torvalds #include <net/act_api.h> 9a5148626SJiri Pirko #include <net/net_namespace.h> 101da177e4SLinus Torvalds 11cd11b164SPaolo Abeni /* TC action not accessible from user space */ 12720f22feSJohn Hurley #define TC_ACT_CONSUMED (TC_ACT_VALUE_MAX + 1) 13cd11b164SPaolo Abeni 141da177e4SLinus Torvalds /* Basic packet classifier frontend definitions. */ 151da177e4SLinus Torvalds 16fd2c3ef7SEric Dumazet struct tcf_walker { 171da177e4SLinus Torvalds int stop; 181da177e4SLinus Torvalds int skip; 191da177e4SLinus Torvalds int count; 206676d5e4SVlad Buslov bool nonempty; 2101683a14SVlad Buslov unsigned long cookie; 228113c095SWANG Cong int (*fn)(struct tcf_proto *, void *node, struct tcf_walker *); 231da177e4SLinus Torvalds }; 241da177e4SLinus Torvalds 255c15257fSJoe Perches int register_tcf_proto_ops(struct tcf_proto_ops *ops); 265c15257fSJoe Perches int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); 271da177e4SLinus Torvalds 288c4083b3SJiri Pirko struct tcf_block_ext_info { 2932f8c409SPablo Neira Ayuso enum flow_block_binder_type binder_type; 30c7eb7d72SJiri Pirko tcf_chain_head_change_t *chain_head_change; 31c7eb7d72SJiri Pirko void *chain_head_change_priv; 3248617387SJiri Pirko u32 block_index; 338c4083b3SJiri Pirko }; 348c4083b3SJiri Pirko 35acb67442SJiri Pirko struct tcf_block_cb; 36aaa908ffSCong Wang bool tcf_queue_work(struct rcu_work *rwork, work_func_t func); 37acb67442SJiri Pirko 388ae70032SJiri Pirko #ifdef CONFIG_NET_CLS 391f3ed383SJiri Pirko struct tcf_chain *tcf_chain_get_by_act(struct tcf_block *block, 401f3ed383SJiri Pirko u32 chain_index); 411f3ed383SJiri Pirko void tcf_chain_put_by_act(struct tcf_chain *chain); 42bbf73830SVlad Buslov struct tcf_chain *tcf_get_next_chain(struct tcf_block *block, 43bbf73830SVlad Buslov struct tcf_chain *chain); 44fe2923afSVlad Buslov struct tcf_proto *tcf_get_next_proto(struct tcf_chain *chain, 4512db03b6SVlad Buslov struct tcf_proto *tp, bool rtnl_held); 46f36fe1c4SJiri Pirko void tcf_block_netif_keep_dst(struct tcf_block *block); 476529eabaSJiri Pirko int tcf_block_get(struct tcf_block **p_block, 488d1a77f9SAlexander Aring struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, 498d1a77f9SAlexander Aring struct netlink_ext_ack *extack); 50c7eb7d72SJiri Pirko int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, 518d1a77f9SAlexander Aring struct tcf_block_ext_info *ei, 528d1a77f9SAlexander Aring struct netlink_ext_ack *extack); 536529eabaSJiri Pirko void tcf_block_put(struct tcf_block *block); 54c7eb7d72SJiri Pirko void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, 558c4083b3SJiri Pirko struct tcf_block_ext_info *ei); 5644186460SJiri Pirko 5748617387SJiri Pirko static inline bool tcf_block_shared(struct tcf_block *block) 5848617387SJiri Pirko { 5948617387SJiri Pirko return block->index; 6048617387SJiri Pirko } 6148617387SJiri Pirko 62c1a970d0SVlad Buslov static inline bool tcf_block_non_null_shared(struct tcf_block *block) 63c1a970d0SVlad Buslov { 64c1a970d0SVlad Buslov return block && block->index; 65c1a970d0SVlad Buslov } 66c1a970d0SVlad Buslov 6744186460SJiri Pirko static inline struct Qdisc *tcf_block_q(struct tcf_block *block) 6844186460SJiri Pirko { 6948617387SJiri Pirko WARN_ON(tcf_block_shared(block)); 7044186460SJiri Pirko return block->q; 7144186460SJiri Pirko } 7244186460SJiri Pirko 7387d83093SJiri Pirko int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, 7487d83093SJiri Pirko struct tcf_result *res, bool compat_mode); 7587d83093SJiri Pirko 768ae70032SJiri Pirko #else 7788c44a52SPieter Jansen van Vuuren static inline bool tcf_block_shared(struct tcf_block *block) 7888c44a52SPieter Jansen van Vuuren { 7988c44a52SPieter Jansen van Vuuren return false; 8088c44a52SPieter Jansen van Vuuren } 8188c44a52SPieter Jansen van Vuuren 82c1a970d0SVlad Buslov static inline bool tcf_block_non_null_shared(struct tcf_block *block) 83c1a970d0SVlad Buslov { 84c1a970d0SVlad Buslov return false; 85c1a970d0SVlad Buslov } 86c1a970d0SVlad Buslov 876529eabaSJiri Pirko static inline 886529eabaSJiri Pirko int tcf_block_get(struct tcf_block **p_block, 893c149091SSudip Mukherjee struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q, 903c149091SSudip Mukherjee struct netlink_ext_ack *extack) 916529eabaSJiri Pirko { 926529eabaSJiri Pirko return 0; 936529eabaSJiri Pirko } 946529eabaSJiri Pirko 958c4083b3SJiri Pirko static inline 96c7eb7d72SJiri Pirko int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, 9733c30a8bSQuentin Monnet struct tcf_block_ext_info *ei, 9833c30a8bSQuentin Monnet struct netlink_ext_ack *extack) 998c4083b3SJiri Pirko { 1008c4083b3SJiri Pirko return 0; 1018c4083b3SJiri Pirko } 1028c4083b3SJiri Pirko 1036529eabaSJiri Pirko static inline void tcf_block_put(struct tcf_block *block) 1048ae70032SJiri Pirko { 1058ae70032SJiri Pirko } 10687d83093SJiri Pirko 1078c4083b3SJiri Pirko static inline 108c7eb7d72SJiri Pirko void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q, 1098c4083b3SJiri Pirko struct tcf_block_ext_info *ei) 1108c4083b3SJiri Pirko { 1118c4083b3SJiri Pirko } 1128c4083b3SJiri Pirko 11344186460SJiri Pirko static inline struct Qdisc *tcf_block_q(struct tcf_block *block) 11444186460SJiri Pirko { 11544186460SJiri Pirko return NULL; 11644186460SJiri Pirko } 11744186460SJiri Pirko 118acb67442SJiri Pirko static inline 119a7323311SPablo Neira Ayuso int tc_setup_cb_block_register(struct tcf_block *block, flow_setup_cb_t *cb, 120acb67442SJiri Pirko void *cb_priv) 121acb67442SJiri Pirko { 122acb67442SJiri Pirko return 0; 123acb67442SJiri Pirko } 124acb67442SJiri Pirko 125acb67442SJiri Pirko static inline 126a7323311SPablo Neira Ayuso void tc_setup_cb_block_unregister(struct tcf_block *block, flow_setup_cb_t *cb, 127acb67442SJiri Pirko void *cb_priv) 128acb67442SJiri Pirko { 129acb67442SJiri Pirko } 130acb67442SJiri Pirko 13187d83093SJiri Pirko static inline int tcf_classify(struct sk_buff *skb, const struct tcf_proto *tp, 13287d83093SJiri Pirko struct tcf_result *res, bool compat_mode) 13387d83093SJiri Pirko { 13487d83093SJiri Pirko return TC_ACT_UNSPEC; 13587d83093SJiri Pirko } 1368ae70032SJiri Pirko #endif 137cf1facdaSJiri Pirko 1381da177e4SLinus Torvalds static inline unsigned long 1391da177e4SLinus Torvalds __cls_set_class(unsigned long *clp, unsigned long cl) 1401da177e4SLinus Torvalds { 141a0efb80cSWANG Cong return xchg(clp, cl); 1421da177e4SLinus Torvalds } 1431da177e4SLinus Torvalds 1442e24cd75SCong Wang static inline void 1452e24cd75SCong Wang __tcf_bind_filter(struct Qdisc *q, struct tcf_result *r, unsigned long base) 1461da177e4SLinus Torvalds { 1472e24cd75SCong Wang unsigned long cl; 1481da177e4SLinus Torvalds 1492e24cd75SCong Wang cl = q->ops->cl_ops->bind_tcf(q, base, r->classid); 1502e24cd75SCong Wang cl = __cls_set_class(&r->class, cl); 1512e24cd75SCong Wang if (cl) 1522e24cd75SCong Wang q->ops->cl_ops->unbind_tcf(q, cl); 1531da177e4SLinus Torvalds } 1541da177e4SLinus Torvalds 1551da177e4SLinus Torvalds static inline void 1561da177e4SLinus Torvalds tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base) 1571da177e4SLinus Torvalds { 15834e3759cSJiri Pirko struct Qdisc *q = tp->chain->block->q; 1591da177e4SLinus Torvalds 16034e3759cSJiri Pirko /* Check q as it is not set for shared blocks. In that case, 16134e3759cSJiri Pirko * setting class is not supported. 16234e3759cSJiri Pirko */ 16334e3759cSJiri Pirko if (!q) 16434e3759cSJiri Pirko return; 1652e24cd75SCong Wang sch_tree_lock(q); 1662e24cd75SCong Wang __tcf_bind_filter(q, r, base); 1672e24cd75SCong Wang sch_tree_unlock(q); 1682e24cd75SCong Wang } 1692e24cd75SCong Wang 1702e24cd75SCong Wang static inline void 1712e24cd75SCong Wang __tcf_unbind_filter(struct Qdisc *q, struct tcf_result *r) 1722e24cd75SCong Wang { 1732e24cd75SCong Wang unsigned long cl; 1742e24cd75SCong Wang 1752e24cd75SCong Wang if ((cl = __cls_set_class(&r->class, 0)) != 0) 17634e3759cSJiri Pirko q->ops->cl_ops->unbind_tcf(q, cl); 1771da177e4SLinus Torvalds } 1781da177e4SLinus Torvalds 1791da177e4SLinus Torvalds static inline void 1801da177e4SLinus Torvalds tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r) 1811da177e4SLinus Torvalds { 18234e3759cSJiri Pirko struct Qdisc *q = tp->chain->block->q; 1831da177e4SLinus Torvalds 18434e3759cSJiri Pirko if (!q) 18534e3759cSJiri Pirko return; 1862e24cd75SCong Wang __tcf_unbind_filter(q, r); 1871da177e4SLinus Torvalds } 1881da177e4SLinus Torvalds 189fd2c3ef7SEric Dumazet struct tcf_exts { 1901da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ACT 19133be6271SWANG Cong __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ 19222dc13c8SWANG Cong int nr_actions; 19322dc13c8SWANG Cong struct tc_action **actions; 194e4b95c41SCong Wang struct net *net; 1951da177e4SLinus Torvalds #endif 1961da177e4SLinus Torvalds /* Map to export classifier specific extension TLV types to the 1971da177e4SLinus Torvalds * generic extensions API. Unsupported extensions must be set to 0. 1981da177e4SLinus Torvalds */ 1991da177e4SLinus Torvalds int action; 2001da177e4SLinus Torvalds int police; 2011da177e4SLinus Torvalds }; 2021da177e4SLinus Torvalds 20314215108SCong Wang static inline int tcf_exts_init(struct tcf_exts *exts, struct net *net, 20414215108SCong Wang int action, int police) 20533be6271SWANG Cong { 20633be6271SWANG Cong #ifdef CONFIG_NET_CLS_ACT 2075da57f42SWANG Cong exts->type = 0; 20822dc13c8SWANG Cong exts->nr_actions = 0; 20914215108SCong Wang exts->net = net; 21022dc13c8SWANG Cong exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *), 21122dc13c8SWANG Cong GFP_KERNEL); 212b9a24bb7SWANG Cong if (!exts->actions) 213b9a24bb7SWANG Cong return -ENOMEM; 21433be6271SWANG Cong #endif 2155da57f42SWANG Cong exts->action = action; 2165da57f42SWANG Cong exts->police = police; 217b9a24bb7SWANG Cong return 0; 21833be6271SWANG Cong } 21933be6271SWANG Cong 220e4b95c41SCong Wang /* Return false if the netns is being destroyed in cleanup_net(). Callers 221e4b95c41SCong Wang * need to do cleanup synchronously in this case, otherwise may race with 222e4b95c41SCong Wang * tc_action_net_exit(). Return true for other cases. 223e4b95c41SCong Wang */ 224e4b95c41SCong Wang static inline bool tcf_exts_get_net(struct tcf_exts *exts) 225e4b95c41SCong Wang { 226e4b95c41SCong Wang #ifdef CONFIG_NET_CLS_ACT 227e4b95c41SCong Wang exts->net = maybe_get_net(exts->net); 228e4b95c41SCong Wang return exts->net != NULL; 229e4b95c41SCong Wang #else 230e4b95c41SCong Wang return true; 231e4b95c41SCong Wang #endif 232e4b95c41SCong Wang } 233e4b95c41SCong Wang 234e4b95c41SCong Wang static inline void tcf_exts_put_net(struct tcf_exts *exts) 235e4b95c41SCong Wang { 236e4b95c41SCong Wang #ifdef CONFIG_NET_CLS_ACT 237e4b95c41SCong Wang if (exts->net) 238e4b95c41SCong Wang put_net(exts->net); 239e4b95c41SCong Wang #endif 240e4b95c41SCong Wang } 241e4b95c41SCong Wang 24222dc13c8SWANG Cong #ifdef CONFIG_NET_CLS_ACT 243244cd96aSCong Wang #define tcf_exts_for_each_action(i, a, exts) \ 244244cd96aSCong Wang for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = (exts)->actions[i]); i++) 245244cd96aSCong Wang #else 246244cd96aSCong Wang #define tcf_exts_for_each_action(i, a, exts) \ 247191672caSArnd Bergmann for (; 0; (void)(i), (void)(a), (void)(exts)) 24822dc13c8SWANG Cong #endif 24922dc13c8SWANG Cong 250d897a638SJakub Kicinski static inline void 251d897a638SJakub Kicinski tcf_exts_stats_update(const struct tcf_exts *exts, 252d897a638SJakub Kicinski u64 bytes, u64 packets, u64 lastuse) 253d897a638SJakub Kicinski { 254d897a638SJakub Kicinski #ifdef CONFIG_NET_CLS_ACT 255d897a638SJakub Kicinski int i; 256d897a638SJakub Kicinski 257d897a638SJakub Kicinski preempt_disable(); 258d897a638SJakub Kicinski 259d897a638SJakub Kicinski for (i = 0; i < exts->nr_actions; i++) { 260d897a638SJakub Kicinski struct tc_action *a = exts->actions[i]; 261d897a638SJakub Kicinski 26228169abaSEelco Chaudron tcf_action_stats_update(a, bytes, packets, lastuse, true); 263d897a638SJakub Kicinski } 264d897a638SJakub Kicinski 265d897a638SJakub Kicinski preempt_enable(); 266d897a638SJakub Kicinski #endif 267d897a638SJakub Kicinski } 268d897a638SJakub Kicinski 2691da177e4SLinus Torvalds /** 2703bcc0cecSJiri Pirko * tcf_exts_has_actions - check if at least one action is present 2713bcc0cecSJiri Pirko * @exts: tc filter extensions handle 2723bcc0cecSJiri Pirko * 2733bcc0cecSJiri Pirko * Returns true if at least one action is present. 2743bcc0cecSJiri Pirko */ 2753bcc0cecSJiri Pirko static inline bool tcf_exts_has_actions(struct tcf_exts *exts) 2763bcc0cecSJiri Pirko { 2772734437eSWANG Cong #ifdef CONFIG_NET_CLS_ACT 2783bcc0cecSJiri Pirko return exts->nr_actions; 2793bcc0cecSJiri Pirko #else 2803bcc0cecSJiri Pirko return false; 2813bcc0cecSJiri Pirko #endif 2823bcc0cecSJiri Pirko } 2832734437eSWANG Cong 2843bcc0cecSJiri Pirko /** 285af69afc5SJiri Pirko * tcf_exts_exec - execute tc filter extensions 286af69afc5SJiri Pirko * @skb: socket buffer 287af69afc5SJiri Pirko * @exts: tc filter extensions handle 288af69afc5SJiri Pirko * @res: desired result 289af69afc5SJiri Pirko * 290af089e70SJiri Pirko * Executes all configured extensions. Returns TC_ACT_OK on a normal execution, 291af69afc5SJiri Pirko * a negative number if the filter must be considered unmatched or 292af69afc5SJiri Pirko * a positive action code (TC_ACT_*) which must be returned to the 293af69afc5SJiri Pirko * underlying layer. 294af69afc5SJiri Pirko */ 295af69afc5SJiri Pirko static inline int 296af69afc5SJiri Pirko tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts, 297af69afc5SJiri Pirko struct tcf_result *res) 298af69afc5SJiri Pirko { 299af69afc5SJiri Pirko #ifdef CONFIG_NET_CLS_ACT 300ec1a9ccaSJiri Pirko return tcf_action_exec(skb, exts->actions, exts->nr_actions, res); 301af69afc5SJiri Pirko #endif 302af089e70SJiri Pirko return TC_ACT_OK; 303af69afc5SJiri Pirko } 304af69afc5SJiri Pirko 3055c15257fSJoe Perches int tcf_exts_validate(struct net *net, struct tcf_proto *tp, 306c1b52739SBenjamin LaHaise struct nlattr **tb, struct nlattr *rate_tlv, 307ec6743a1SVlad Buslov struct tcf_exts *exts, bool ovr, bool rtnl_held, 30850a56190SAlexander Aring struct netlink_ext_ack *extack); 30918d0264fSWANG Cong void tcf_exts_destroy(struct tcf_exts *exts); 3109b0d4446SJiri Pirko void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src); 3115da57f42SWANG Cong int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts); 3125da57f42SWANG Cong int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts); 3131da177e4SLinus Torvalds 3141da177e4SLinus Torvalds /** 3151da177e4SLinus Torvalds * struct tcf_pkt_info - packet information 3161da177e4SLinus Torvalds */ 317fd2c3ef7SEric Dumazet struct tcf_pkt_info { 3181da177e4SLinus Torvalds unsigned char * ptr; 3191da177e4SLinus Torvalds int nexthdr; 3201da177e4SLinus Torvalds }; 3211da177e4SLinus Torvalds 3221da177e4SLinus Torvalds #ifdef CONFIG_NET_EMATCH 3231da177e4SLinus Torvalds 3241da177e4SLinus Torvalds struct tcf_ematch_ops; 3251da177e4SLinus Torvalds 3261da177e4SLinus Torvalds /** 3271da177e4SLinus Torvalds * struct tcf_ematch - extended match (ematch) 3281da177e4SLinus Torvalds * 3291da177e4SLinus Torvalds * @matchid: identifier to allow userspace to reidentify a match 3301da177e4SLinus Torvalds * @flags: flags specifying attributes and the relation to other matches 3311da177e4SLinus Torvalds * @ops: the operations lookup table of the corresponding ematch module 3321da177e4SLinus Torvalds * @datalen: length of the ematch specific configuration data 3331da177e4SLinus Torvalds * @data: ematch specific data 3341da177e4SLinus Torvalds */ 335fd2c3ef7SEric Dumazet struct tcf_ematch { 3361da177e4SLinus Torvalds struct tcf_ematch_ops * ops; 3371da177e4SLinus Torvalds unsigned long data; 3381da177e4SLinus Torvalds unsigned int datalen; 3391da177e4SLinus Torvalds u16 matchid; 3401da177e4SLinus Torvalds u16 flags; 34182a470f1SJohn Fastabend struct net *net; 3421da177e4SLinus Torvalds }; 3431da177e4SLinus Torvalds 3441da177e4SLinus Torvalds static inline int tcf_em_is_container(struct tcf_ematch *em) 3451da177e4SLinus Torvalds { 3461da177e4SLinus Torvalds return !em->ops; 3471da177e4SLinus Torvalds } 3481da177e4SLinus Torvalds 3491da177e4SLinus Torvalds static inline int tcf_em_is_simple(struct tcf_ematch *em) 3501da177e4SLinus Torvalds { 3511da177e4SLinus Torvalds return em->flags & TCF_EM_SIMPLE; 3521da177e4SLinus Torvalds } 3531da177e4SLinus Torvalds 3541da177e4SLinus Torvalds static inline int tcf_em_is_inverted(struct tcf_ematch *em) 3551da177e4SLinus Torvalds { 3561da177e4SLinus Torvalds return em->flags & TCF_EM_INVERT; 3571da177e4SLinus Torvalds } 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvalds static inline int tcf_em_last_match(struct tcf_ematch *em) 3601da177e4SLinus Torvalds { 3611da177e4SLinus Torvalds return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END; 3621da177e4SLinus Torvalds } 3631da177e4SLinus Torvalds 3641da177e4SLinus Torvalds static inline int tcf_em_early_end(struct tcf_ematch *em, int result) 3651da177e4SLinus Torvalds { 3661da177e4SLinus Torvalds if (tcf_em_last_match(em)) 3671da177e4SLinus Torvalds return 1; 3681da177e4SLinus Torvalds 3691da177e4SLinus Torvalds if (result == 0 && em->flags & TCF_EM_REL_AND) 3701da177e4SLinus Torvalds return 1; 3711da177e4SLinus Torvalds 3721da177e4SLinus Torvalds if (result != 0 && em->flags & TCF_EM_REL_OR) 3731da177e4SLinus Torvalds return 1; 3741da177e4SLinus Torvalds 3751da177e4SLinus Torvalds return 0; 3761da177e4SLinus Torvalds } 3771da177e4SLinus Torvalds 3781da177e4SLinus Torvalds /** 3791da177e4SLinus Torvalds * struct tcf_ematch_tree - ematch tree handle 3801da177e4SLinus Torvalds * 3811da177e4SLinus Torvalds * @hdr: ematch tree header supplied by userspace 3821da177e4SLinus Torvalds * @matches: array of ematches 3831da177e4SLinus Torvalds */ 384fd2c3ef7SEric Dumazet struct tcf_ematch_tree { 3851da177e4SLinus Torvalds struct tcf_ematch_tree_hdr hdr; 3861da177e4SLinus Torvalds struct tcf_ematch * matches; 3871da177e4SLinus Torvalds 3881da177e4SLinus Torvalds }; 3891da177e4SLinus Torvalds 3901da177e4SLinus Torvalds /** 3911da177e4SLinus Torvalds * struct tcf_ematch_ops - ematch module operations 3921da177e4SLinus Torvalds * 3931da177e4SLinus Torvalds * @kind: identifier (kind) of this ematch module 3941da177e4SLinus Torvalds * @datalen: length of expected configuration data (optional) 3951da177e4SLinus Torvalds * @change: called during validation (optional) 3961da177e4SLinus Torvalds * @match: called during ematch tree evaluation, must return 1/0 3971da177e4SLinus Torvalds * @destroy: called during destroyage (optional) 3981da177e4SLinus Torvalds * @dump: called during dumping process (optional) 3991da177e4SLinus Torvalds * @owner: owner, must be set to THIS_MODULE 4001da177e4SLinus Torvalds * @link: link to previous/next ematch module (internal use) 4011da177e4SLinus Torvalds */ 402fd2c3ef7SEric Dumazet struct tcf_ematch_ops { 4031da177e4SLinus Torvalds int kind; 4041da177e4SLinus Torvalds int datalen; 40582a470f1SJohn Fastabend int (*change)(struct net *net, void *, 4061da177e4SLinus Torvalds int, struct tcf_ematch *); 4071da177e4SLinus Torvalds int (*match)(struct sk_buff *, struct tcf_ematch *, 4081da177e4SLinus Torvalds struct tcf_pkt_info *); 40982a470f1SJohn Fastabend void (*destroy)(struct tcf_ematch *); 4101da177e4SLinus Torvalds int (*dump)(struct sk_buff *, struct tcf_ematch *); 4111da177e4SLinus Torvalds struct module *owner; 4121da177e4SLinus Torvalds struct list_head link; 4131da177e4SLinus Torvalds }; 4141da177e4SLinus Torvalds 4155c15257fSJoe Perches int tcf_em_register(struct tcf_ematch_ops *); 4165c15257fSJoe Perches void tcf_em_unregister(struct tcf_ematch_ops *); 4175c15257fSJoe Perches int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *, 4181da177e4SLinus Torvalds struct tcf_ematch_tree *); 41982a470f1SJohn Fastabend void tcf_em_tree_destroy(struct tcf_ematch_tree *); 4205c15257fSJoe Perches int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int); 4215c15257fSJoe Perches int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *, 4221da177e4SLinus Torvalds struct tcf_pkt_info *); 4231da177e4SLinus Torvalds 4241da177e4SLinus Torvalds /** 4251da177e4SLinus Torvalds * tcf_em_tree_match - evaulate an ematch tree 4261da177e4SLinus Torvalds * 4271da177e4SLinus Torvalds * @skb: socket buffer of the packet in question 4281da177e4SLinus Torvalds * @tree: ematch tree to be used for evaluation 4291da177e4SLinus Torvalds * @info: packet information examined by classifier 4301da177e4SLinus Torvalds * 4311da177e4SLinus Torvalds * This function matches @skb against the ematch tree in @tree by going 4321da177e4SLinus Torvalds * through all ematches respecting their logic relations returning 4331da177e4SLinus Torvalds * as soon as the result is obvious. 4341da177e4SLinus Torvalds * 4351da177e4SLinus Torvalds * Returns 1 if the ematch tree as-one matches, no ematches are configured 4361da177e4SLinus Torvalds * or ematch is not enabled in the kernel, otherwise 0 is returned. 4371da177e4SLinus Torvalds */ 4381da177e4SLinus Torvalds static inline int tcf_em_tree_match(struct sk_buff *skb, 4391da177e4SLinus Torvalds struct tcf_ematch_tree *tree, 4401da177e4SLinus Torvalds struct tcf_pkt_info *info) 4411da177e4SLinus Torvalds { 4421da177e4SLinus Torvalds if (tree->hdr.nmatches) 4431da177e4SLinus Torvalds return __tcf_em_tree_match(skb, tree, info); 4441da177e4SLinus Torvalds else 4451da177e4SLinus Torvalds return 1; 4461da177e4SLinus Torvalds } 4471da177e4SLinus Torvalds 448db3d99c0SPatrick McHardy #define MODULE_ALIAS_TCF_EMATCH(kind) MODULE_ALIAS("ematch-kind-" __stringify(kind)) 449db3d99c0SPatrick McHardy 4501da177e4SLinus Torvalds #else /* CONFIG_NET_EMATCH */ 4511da177e4SLinus Torvalds 452fd2c3ef7SEric Dumazet struct tcf_ematch_tree { 4531da177e4SLinus Torvalds }; 4541da177e4SLinus Torvalds 4551da177e4SLinus Torvalds #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0) 45682a470f1SJohn Fastabend #define tcf_em_tree_destroy(t) do { (void)(t); } while(0) 4571da177e4SLinus Torvalds #define tcf_em_tree_dump(skb, t, tlv) (0) 4581da177e4SLinus Torvalds #define tcf_em_tree_match(skb, t, info) ((void)(info), 1) 4591da177e4SLinus Torvalds 4601da177e4SLinus Torvalds #endif /* CONFIG_NET_EMATCH */ 4611da177e4SLinus Torvalds 4621da177e4SLinus Torvalds static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer) 4631da177e4SLinus Torvalds { 4641da177e4SLinus Torvalds switch (layer) { 4651da177e4SLinus Torvalds case TCF_LAYER_LINK: 466d3303a65SWolfgang Bumiller return skb_mac_header(skb); 4671da177e4SLinus Torvalds case TCF_LAYER_NETWORK: 468d56f90a7SArnaldo Carvalho de Melo return skb_network_header(skb); 4691da177e4SLinus Torvalds case TCF_LAYER_TRANSPORT: 4709c70220bSArnaldo Carvalho de Melo return skb_transport_header(skb); 4711da177e4SLinus Torvalds } 4721da177e4SLinus Torvalds 4731da177e4SLinus Torvalds return NULL; 4741da177e4SLinus Torvalds } 4751da177e4SLinus Torvalds 476eddc9ec5SArnaldo Carvalho de Melo static inline int tcf_valid_offset(const struct sk_buff *skb, 477eddc9ec5SArnaldo Carvalho de Melo const unsigned char *ptr, const int len) 4781da177e4SLinus Torvalds { 479da521b2cSDavid S. Miller return likely((ptr + len) <= skb_tail_pointer(skb) && 480da521b2cSDavid S. Miller ptr >= skb->head && 481da521b2cSDavid S. Miller (ptr <= (ptr + len))); 4821da177e4SLinus Torvalds } 4831da177e4SLinus Torvalds 4841da177e4SLinus Torvalds static inline int 4851057c55fSAlexander Aring tcf_change_indev(struct net *net, struct nlattr *indev_tlv, 4861057c55fSAlexander Aring struct netlink_ext_ack *extack) 4871da177e4SLinus Torvalds { 4882519a602SWANG Cong char indev[IFNAMSIZ]; 489c01003c2SPatrick McHardy struct net_device *dev; 490c01003c2SPatrick McHardy 4911057c55fSAlexander Aring if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) { 4921057c55fSAlexander Aring NL_SET_ERR_MSG(extack, "Interface name too long"); 4932519a602SWANG Cong return -EINVAL; 4941057c55fSAlexander Aring } 4952519a602SWANG Cong dev = __dev_get_by_name(net, indev); 4962519a602SWANG Cong if (!dev) 4972519a602SWANG Cong return -ENODEV; 4982519a602SWANG Cong return dev->ifindex; 4991da177e4SLinus Torvalds } 5001da177e4SLinus Torvalds 5012519a602SWANG Cong static inline bool 5022519a602SWANG Cong tcf_match_indev(struct sk_buff *skb, int ifindex) 5032519a602SWANG Cong { 5042519a602SWANG Cong if (!ifindex) 5052519a602SWANG Cong return true; 5062519a602SWANG Cong if (!skb->skb_iif) 5072519a602SWANG Cong return false; 5082519a602SWANG Cong return ifindex == skb->skb_iif; 5091da177e4SLinus Torvalds } 5101da177e4SLinus Torvalds 5113a7b6861SPablo Neira Ayuso int tc_setup_flow_action(struct flow_action *flow_action, 5129838b20aSVlad Buslov const struct tcf_exts *exts, bool rtnl_held); 5135a6ff4b1SVlad Buslov void tc_cleanup_flow_action(struct flow_action *flow_action); 5145a6ff4b1SVlad Buslov 515aeb3fecdSCong Wang int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type, 51640119211SVlad Buslov void *type_data, bool err_stop, bool rtnl_held); 51740119211SVlad Buslov int tc_setup_cb_add(struct tcf_block *block, struct tcf_proto *tp, 51840119211SVlad Buslov enum tc_setup_type type, void *type_data, bool err_stop, 51940119211SVlad Buslov u32 *flags, unsigned int *in_hw_count, bool rtnl_held); 52040119211SVlad Buslov int tc_setup_cb_replace(struct tcf_block *block, struct tcf_proto *tp, 52140119211SVlad Buslov enum tc_setup_type type, void *type_data, bool err_stop, 52240119211SVlad Buslov u32 *old_flags, unsigned int *old_in_hw_count, 52340119211SVlad Buslov u32 *new_flags, unsigned int *new_in_hw_count, 52440119211SVlad Buslov bool rtnl_held); 52540119211SVlad Buslov int tc_setup_cb_destroy(struct tcf_block *block, struct tcf_proto *tp, 52640119211SVlad Buslov enum tc_setup_type type, void *type_data, bool err_stop, 52740119211SVlad Buslov u32 *flags, unsigned int *in_hw_count, bool rtnl_held); 52840119211SVlad Buslov int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp, 52940119211SVlad Buslov bool add, flow_setup_cb_t *cb, 53040119211SVlad Buslov enum tc_setup_type type, void *type_data, 53140119211SVlad Buslov void *cb_priv, u32 *flags, unsigned int *in_hw_count); 532e3ab786bSPablo Neira Ayuso unsigned int tcf_exts_num_actions(struct tcf_exts *exts); 533717503b9SJiri Pirko 534a1b7c5fdSJohn Fastabend struct tc_cls_u32_knode { 535a1b7c5fdSJohn Fastabend struct tcf_exts *exts; 536068ceb35SJakub Kicinski struct tcf_result *res; 537e014860eSJohn Fastabend struct tc_u32_sel *sel; 538a1b7c5fdSJohn Fastabend u32 handle; 539a1b7c5fdSJohn Fastabend u32 val; 540a1b7c5fdSJohn Fastabend u32 mask; 541a1b7c5fdSJohn Fastabend u32 link_handle; 542e014860eSJohn Fastabend u8 fshift; 543a1b7c5fdSJohn Fastabend }; 544a1b7c5fdSJohn Fastabend 545a1b7c5fdSJohn Fastabend struct tc_cls_u32_hnode { 546a1b7c5fdSJohn Fastabend u32 handle; 547a1b7c5fdSJohn Fastabend u32 prio; 548a1b7c5fdSJohn Fastabend unsigned int divisor; 549a1b7c5fdSJohn Fastabend }; 550a1b7c5fdSJohn Fastabend 551a1b7c5fdSJohn Fastabend enum tc_clsu32_command { 552a1b7c5fdSJohn Fastabend TC_CLSU32_NEW_KNODE, 553a1b7c5fdSJohn Fastabend TC_CLSU32_REPLACE_KNODE, 554a1b7c5fdSJohn Fastabend TC_CLSU32_DELETE_KNODE, 555a1b7c5fdSJohn Fastabend TC_CLSU32_NEW_HNODE, 556a1b7c5fdSJohn Fastabend TC_CLSU32_REPLACE_HNODE, 557a1b7c5fdSJohn Fastabend TC_CLSU32_DELETE_HNODE, 558a1b7c5fdSJohn Fastabend }; 559a1b7c5fdSJohn Fastabend 560a1b7c5fdSJohn Fastabend struct tc_cls_u32_offload { 561f9e30088SPablo Neira Ayuso struct flow_cls_common_offload common; 562a1b7c5fdSJohn Fastabend /* knode values */ 563a1b7c5fdSJohn Fastabend enum tc_clsu32_command command; 564a1b7c5fdSJohn Fastabend union { 565a1b7c5fdSJohn Fastabend struct tc_cls_u32_knode knode; 566a1b7c5fdSJohn Fastabend struct tc_cls_u32_hnode hnode; 567a1b7c5fdSJohn Fastabend }; 568a1b7c5fdSJohn Fastabend }; 569a1b7c5fdSJohn Fastabend 5707b06e8aeSJiri Pirko static inline bool tc_can_offload(const struct net_device *dev) 5716843e7a2SJohn Fastabend { 57270b5aee4SJiri Pirko return dev->features & NETIF_F_HW_TC; 5736843e7a2SJohn Fastabend } 5746843e7a2SJohn Fastabend 575f9eda14fSQuentin Monnet static inline bool tc_can_offload_extack(const struct net_device *dev, 576f9eda14fSQuentin Monnet struct netlink_ext_ack *extack) 577f9eda14fSQuentin Monnet { 578f9eda14fSQuentin Monnet bool can = tc_can_offload(dev); 579f9eda14fSQuentin Monnet 580f9eda14fSQuentin Monnet if (!can) 581f9eda14fSQuentin Monnet NL_SET_ERR_MSG(extack, "TC offload is disabled on net device"); 582f9eda14fSQuentin Monnet 583f9eda14fSQuentin Monnet return can; 584f9eda14fSQuentin Monnet } 585f9eda14fSQuentin Monnet 586878db9f0SJakub Kicinski static inline bool 587878db9f0SJakub Kicinski tc_cls_can_offload_and_chain0(const struct net_device *dev, 588f9e30088SPablo Neira Ayuso struct flow_cls_common_offload *common) 589878db9f0SJakub Kicinski { 590878db9f0SJakub Kicinski if (!tc_can_offload_extack(dev, common->extack)) 591878db9f0SJakub Kicinski return false; 592878db9f0SJakub Kicinski if (common->chain_index) { 593878db9f0SJakub Kicinski NL_SET_ERR_MSG(common->extack, 594878db9f0SJakub Kicinski "Driver supports only offload of chain 0"); 595878db9f0SJakub Kicinski return false; 596878db9f0SJakub Kicinski } 597878db9f0SJakub Kicinski return true; 598878db9f0SJakub Kicinski } 599878db9f0SJakub Kicinski 60055330f05SHadar Hen Zion static inline bool tc_skip_hw(u32 flags) 60155330f05SHadar Hen Zion { 60255330f05SHadar Hen Zion return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false; 60355330f05SHadar Hen Zion } 60455330f05SHadar Hen Zion 605d34e3e18SSamudrala, Sridhar static inline bool tc_skip_sw(u32 flags) 606d34e3e18SSamudrala, Sridhar { 607d34e3e18SSamudrala, Sridhar return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false; 608d34e3e18SSamudrala, Sridhar } 609d34e3e18SSamudrala, Sridhar 610d34e3e18SSamudrala, Sridhar /* SKIP_HW and SKIP_SW are mutually exclusive flags. */ 611d34e3e18SSamudrala, Sridhar static inline bool tc_flags_valid(u32 flags) 612d34e3e18SSamudrala, Sridhar { 61381c7288bSMarcelo Ricardo Leitner if (flags & ~(TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW | 61481c7288bSMarcelo Ricardo Leitner TCA_CLS_FLAGS_VERBOSE)) 615d34e3e18SSamudrala, Sridhar return false; 616d34e3e18SSamudrala, Sridhar 61781c7288bSMarcelo Ricardo Leitner flags &= TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW; 618d34e3e18SSamudrala, Sridhar if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW))) 619d34e3e18SSamudrala, Sridhar return false; 620d34e3e18SSamudrala, Sridhar 621d34e3e18SSamudrala, Sridhar return true; 622d34e3e18SSamudrala, Sridhar } 623d34e3e18SSamudrala, Sridhar 624e696028aSOr Gerlitz static inline bool tc_in_hw(u32 flags) 625e696028aSOr Gerlitz { 626e696028aSOr Gerlitz return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false; 627e696028aSOr Gerlitz } 628e696028aSOr Gerlitz 62934832e1cSJakub Kicinski static inline void 630f9e30088SPablo Neira Ayuso tc_cls_common_offload_init(struct flow_cls_common_offload *cls_common, 63134832e1cSJakub Kicinski const struct tcf_proto *tp, u32 flags, 63234832e1cSJakub Kicinski struct netlink_ext_ack *extack) 63334832e1cSJakub Kicinski { 63434832e1cSJakub Kicinski cls_common->chain_index = tp->chain->index; 63534832e1cSJakub Kicinski cls_common->protocol = tp->protocol; 636ef01adaeSPablo Neira Ayuso cls_common->prio = tp->prio >> 16; 63781c7288bSMarcelo Ricardo Leitner if (tc_skip_sw(flags) || flags & TCA_CLS_FLAGS_VERBOSE) 63834832e1cSJakub Kicinski cls_common->extack = extack; 63934832e1cSJakub Kicinski } 64034832e1cSJakub Kicinski 641b87f7936SYotam Gigi enum tc_matchall_command { 642b87f7936SYotam Gigi TC_CLSMATCHALL_REPLACE, 643b87f7936SYotam Gigi TC_CLSMATCHALL_DESTROY, 644b7fe4ab8SPieter Jansen van Vuuren TC_CLSMATCHALL_STATS, 645b87f7936SYotam Gigi }; 646b87f7936SYotam Gigi 647b87f7936SYotam Gigi struct tc_cls_matchall_offload { 648f9e30088SPablo Neira Ayuso struct flow_cls_common_offload common; 649b87f7936SYotam Gigi enum tc_matchall_command command; 650f00cbf19SPieter Jansen van Vuuren struct flow_rule *rule; 651b7fe4ab8SPieter Jansen van Vuuren struct flow_stats stats; 652b87f7936SYotam Gigi unsigned long cookie; 653b87f7936SYotam Gigi }; 654b87f7936SYotam Gigi 655332ae8e2SJakub Kicinski enum tc_clsbpf_command { 656102740bdSJakub Kicinski TC_CLSBPF_OFFLOAD, 65768d64063SJakub Kicinski TC_CLSBPF_STATS, 658332ae8e2SJakub Kicinski }; 659332ae8e2SJakub Kicinski 660332ae8e2SJakub Kicinski struct tc_cls_bpf_offload { 661f9e30088SPablo Neira Ayuso struct flow_cls_common_offload common; 662332ae8e2SJakub Kicinski enum tc_clsbpf_command command; 663332ae8e2SJakub Kicinski struct tcf_exts *exts; 664332ae8e2SJakub Kicinski struct bpf_prog *prog; 665102740bdSJakub Kicinski struct bpf_prog *oldprog; 666332ae8e2SJakub Kicinski const char *name; 667332ae8e2SJakub Kicinski bool exts_integrated; 668332ae8e2SJakub Kicinski }; 669332ae8e2SJakub Kicinski 6704e8b86c0SAmritha Nambiar struct tc_mqprio_qopt_offload { 6714e8b86c0SAmritha Nambiar /* struct tc_mqprio_qopt must always be the first element */ 6724e8b86c0SAmritha Nambiar struct tc_mqprio_qopt qopt; 6734e8b86c0SAmritha Nambiar u16 mode; 6744e8b86c0SAmritha Nambiar u16 shaper; 6754e8b86c0SAmritha Nambiar u32 flags; 6764e8b86c0SAmritha Nambiar u64 min_rate[TC_QOPT_MAX_QUEUE]; 6774e8b86c0SAmritha Nambiar u64 max_rate[TC_QOPT_MAX_QUEUE]; 6784e8b86c0SAmritha Nambiar }; 6791045ba77SJamal Hadi Salim 6801045ba77SJamal Hadi Salim /* This structure holds cookie structure that is passed from user 6811045ba77SJamal Hadi Salim * to the kernel for actions and classifiers 6821045ba77SJamal Hadi Salim */ 6831045ba77SJamal Hadi Salim struct tc_cookie { 6841045ba77SJamal Hadi Salim u8 *data; 6851045ba77SJamal Hadi Salim u32 len; 686eec94fdbSVlad Buslov struct rcu_head rcu; 6871045ba77SJamal Hadi Salim }; 688602f3bafSNogah Frankel 689f34b4aacSNogah Frankel struct tc_qopt_offload_stats { 690f34b4aacSNogah Frankel struct gnet_stats_basic_packed *bstats; 691f34b4aacSNogah Frankel struct gnet_stats_queue *qstats; 692f34b4aacSNogah Frankel }; 693f34b4aacSNogah Frankel 694f971b132SJakub Kicinski enum tc_mq_command { 695f971b132SJakub Kicinski TC_MQ_CREATE, 696f971b132SJakub Kicinski TC_MQ_DESTROY, 69747c669a4SJakub Kicinski TC_MQ_STATS, 698d577a3d2SJakub Kicinski TC_MQ_GRAFT, 699d577a3d2SJakub Kicinski }; 700d577a3d2SJakub Kicinski 701d577a3d2SJakub Kicinski struct tc_mq_opt_offload_graft_params { 702d577a3d2SJakub Kicinski unsigned long queue; 703d577a3d2SJakub Kicinski u32 child_handle; 704f971b132SJakub Kicinski }; 705f971b132SJakub Kicinski 706f971b132SJakub Kicinski struct tc_mq_qopt_offload { 707f971b132SJakub Kicinski enum tc_mq_command command; 708f971b132SJakub Kicinski u32 handle; 709d577a3d2SJakub Kicinski union { 71047c669a4SJakub Kicinski struct tc_qopt_offload_stats stats; 711d577a3d2SJakub Kicinski struct tc_mq_opt_offload_graft_params graft_params; 712d577a3d2SJakub Kicinski }; 713f971b132SJakub Kicinski }; 714f971b132SJakub Kicinski 715602f3bafSNogah Frankel enum tc_red_command { 716602f3bafSNogah Frankel TC_RED_REPLACE, 717602f3bafSNogah Frankel TC_RED_DESTROY, 718602f3bafSNogah Frankel TC_RED_STATS, 719602f3bafSNogah Frankel TC_RED_XSTATS, 720bf2a752bSJakub Kicinski TC_RED_GRAFT, 721602f3bafSNogah Frankel }; 722602f3bafSNogah Frankel 723602f3bafSNogah Frankel struct tc_red_qopt_offload_params { 724602f3bafSNogah Frankel u32 min; 725602f3bafSNogah Frankel u32 max; 726602f3bafSNogah Frankel u32 probability; 727c0b7490bSJakub Kicinski u32 limit; 728602f3bafSNogah Frankel bool is_ecn; 729190852a5SJakub Kicinski bool is_harddrop; 730416ef9b1SJakub Kicinski struct gnet_stats_queue *qstats; 731602f3bafSNogah Frankel }; 732602f3bafSNogah Frankel 733602f3bafSNogah Frankel struct tc_red_qopt_offload { 734602f3bafSNogah Frankel enum tc_red_command command; 735602f3bafSNogah Frankel u32 handle; 736602f3bafSNogah Frankel u32 parent; 737602f3bafSNogah Frankel union { 738602f3bafSNogah Frankel struct tc_red_qopt_offload_params set; 739f34b4aacSNogah Frankel struct tc_qopt_offload_stats stats; 740602f3bafSNogah Frankel struct red_stats *xstats; 741bf2a752bSJakub Kicinski u32 child_handle; 742602f3bafSNogah Frankel }; 743602f3bafSNogah Frankel }; 744602f3bafSNogah Frankel 745890d8d23SJakub Kicinski enum tc_gred_command { 746890d8d23SJakub Kicinski TC_GRED_REPLACE, 747890d8d23SJakub Kicinski TC_GRED_DESTROY, 748e49efd52SJakub Kicinski TC_GRED_STATS, 749890d8d23SJakub Kicinski }; 750890d8d23SJakub Kicinski 751890d8d23SJakub Kicinski struct tc_gred_vq_qopt_offload_params { 752890d8d23SJakub Kicinski bool present; 753890d8d23SJakub Kicinski u32 limit; 754890d8d23SJakub Kicinski u32 prio; 755890d8d23SJakub Kicinski u32 min; 756890d8d23SJakub Kicinski u32 max; 757890d8d23SJakub Kicinski bool is_ecn; 758890d8d23SJakub Kicinski bool is_harddrop; 759890d8d23SJakub Kicinski u32 probability; 760890d8d23SJakub Kicinski /* Only need backlog, see struct tc_prio_qopt_offload_params */ 761890d8d23SJakub Kicinski u32 *backlog; 762890d8d23SJakub Kicinski }; 763890d8d23SJakub Kicinski 764890d8d23SJakub Kicinski struct tc_gred_qopt_offload_params { 765890d8d23SJakub Kicinski bool grio_on; 766890d8d23SJakub Kicinski bool wred_on; 767890d8d23SJakub Kicinski unsigned int dp_cnt; 768890d8d23SJakub Kicinski unsigned int dp_def; 769890d8d23SJakub Kicinski struct gnet_stats_queue *qstats; 770890d8d23SJakub Kicinski struct tc_gred_vq_qopt_offload_params tab[MAX_DPs]; 771890d8d23SJakub Kicinski }; 772890d8d23SJakub Kicinski 773e49efd52SJakub Kicinski struct tc_gred_qopt_offload_stats { 774e49efd52SJakub Kicinski struct gnet_stats_basic_packed bstats[MAX_DPs]; 775e49efd52SJakub Kicinski struct gnet_stats_queue qstats[MAX_DPs]; 776e49efd52SJakub Kicinski struct red_stats *xstats[MAX_DPs]; 777e49efd52SJakub Kicinski }; 778e49efd52SJakub Kicinski 779890d8d23SJakub Kicinski struct tc_gred_qopt_offload { 780890d8d23SJakub Kicinski enum tc_gred_command command; 781890d8d23SJakub Kicinski u32 handle; 782890d8d23SJakub Kicinski u32 parent; 783890d8d23SJakub Kicinski union { 784890d8d23SJakub Kicinski struct tc_gred_qopt_offload_params set; 785e49efd52SJakub Kicinski struct tc_gred_qopt_offload_stats stats; 786890d8d23SJakub Kicinski }; 787890d8d23SJakub Kicinski }; 788890d8d23SJakub Kicinski 7897fdb61b4SNogah Frankel enum tc_prio_command { 7907fdb61b4SNogah Frankel TC_PRIO_REPLACE, 7917fdb61b4SNogah Frankel TC_PRIO_DESTROY, 7927fdb61b4SNogah Frankel TC_PRIO_STATS, 793b9c7a7acSNogah Frankel TC_PRIO_GRAFT, 7947fdb61b4SNogah Frankel }; 7957fdb61b4SNogah Frankel 7967fdb61b4SNogah Frankel struct tc_prio_qopt_offload_params { 7977fdb61b4SNogah Frankel int bands; 7987fdb61b4SNogah Frankel u8 priomap[TC_PRIO_MAX + 1]; 7999586a992SPetr Machata /* At the point of un-offloading the Qdisc, the reported backlog and 8009586a992SPetr Machata * qlen need to be reduced by the portion that is in HW. 8017fdb61b4SNogah Frankel */ 8027fdb61b4SNogah Frankel struct gnet_stats_queue *qstats; 8037fdb61b4SNogah Frankel }; 8047fdb61b4SNogah Frankel 805b9c7a7acSNogah Frankel struct tc_prio_qopt_offload_graft_params { 806b9c7a7acSNogah Frankel u8 band; 807b9c7a7acSNogah Frankel u32 child_handle; 808b9c7a7acSNogah Frankel }; 809b9c7a7acSNogah Frankel 8107fdb61b4SNogah Frankel struct tc_prio_qopt_offload { 8117fdb61b4SNogah Frankel enum tc_prio_command command; 8127fdb61b4SNogah Frankel u32 handle; 8137fdb61b4SNogah Frankel u32 parent; 8147fdb61b4SNogah Frankel union { 8157fdb61b4SNogah Frankel struct tc_prio_qopt_offload_params replace_params; 8167fdb61b4SNogah Frankel struct tc_qopt_offload_stats stats; 817b9c7a7acSNogah Frankel struct tc_prio_qopt_offload_graft_params graft_params; 8187fdb61b4SNogah Frankel }; 8197fdb61b4SNogah Frankel }; 820b9c7a7acSNogah Frankel 82198b0e5f6SJakub Kicinski enum tc_root_command { 82298b0e5f6SJakub Kicinski TC_ROOT_GRAFT, 82398b0e5f6SJakub Kicinski }; 82498b0e5f6SJakub Kicinski 82598b0e5f6SJakub Kicinski struct tc_root_qopt_offload { 82698b0e5f6SJakub Kicinski enum tc_root_command command; 82798b0e5f6SJakub Kicinski u32 handle; 82898b0e5f6SJakub Kicinski bool ingress; 82998b0e5f6SJakub Kicinski }; 83098b0e5f6SJakub Kicinski 831d35eb52bSPetr Machata enum tc_ets_command { 832d35eb52bSPetr Machata TC_ETS_REPLACE, 833d35eb52bSPetr Machata TC_ETS_DESTROY, 834d35eb52bSPetr Machata TC_ETS_STATS, 835d35eb52bSPetr Machata TC_ETS_GRAFT, 836d35eb52bSPetr Machata }; 837d35eb52bSPetr Machata 838d35eb52bSPetr Machata struct tc_ets_qopt_offload_replace_params { 839d35eb52bSPetr Machata unsigned int bands; 840d35eb52bSPetr Machata u8 priomap[TC_PRIO_MAX + 1]; 841d35eb52bSPetr Machata unsigned int quanta[TCQ_ETS_MAX_BANDS]; /* 0 for strict bands. */ 842d35eb52bSPetr Machata unsigned int weights[TCQ_ETS_MAX_BANDS]; 843d35eb52bSPetr Machata struct gnet_stats_queue *qstats; 844d35eb52bSPetr Machata }; 845d35eb52bSPetr Machata 846d35eb52bSPetr Machata struct tc_ets_qopt_offload_graft_params { 847d35eb52bSPetr Machata u8 band; 848d35eb52bSPetr Machata u32 child_handle; 849d35eb52bSPetr Machata }; 850d35eb52bSPetr Machata 851d35eb52bSPetr Machata struct tc_ets_qopt_offload { 852d35eb52bSPetr Machata enum tc_ets_command command; 853d35eb52bSPetr Machata u32 handle; 854d35eb52bSPetr Machata u32 parent; 855d35eb52bSPetr Machata union { 856d35eb52bSPetr Machata struct tc_ets_qopt_offload_replace_params replace_params; 857d35eb52bSPetr Machata struct tc_qopt_offload_stats stats; 858d35eb52bSPetr Machata struct tc_ets_qopt_offload_graft_params graft_params; 859d35eb52bSPetr Machata }; 860d35eb52bSPetr Machata }; 861d35eb52bSPetr Machata 862ef6aadccSPetr Machata enum tc_tbf_command { 863ef6aadccSPetr Machata TC_TBF_REPLACE, 864ef6aadccSPetr Machata TC_TBF_DESTROY, 865ef6aadccSPetr Machata TC_TBF_STATS, 866ef6aadccSPetr Machata }; 867ef6aadccSPetr Machata 868ef6aadccSPetr Machata struct tc_tbf_qopt_offload_replace_params { 869ef6aadccSPetr Machata struct psched_ratecfg rate; 870ef6aadccSPetr Machata u32 max_size; 871ef6aadccSPetr Machata struct gnet_stats_queue *qstats; 872ef6aadccSPetr Machata }; 873ef6aadccSPetr Machata 874ef6aadccSPetr Machata struct tc_tbf_qopt_offload { 875ef6aadccSPetr Machata enum tc_tbf_command command; 876ef6aadccSPetr Machata u32 handle; 877ef6aadccSPetr Machata u32 parent; 878ef6aadccSPetr Machata union { 879ef6aadccSPetr Machata struct tc_tbf_qopt_offload_replace_params replace_params; 880ef6aadccSPetr Machata struct tc_qopt_offload_stats stats; 881ef6aadccSPetr Machata }; 882ef6aadccSPetr Machata }; 883ef6aadccSPetr Machata 8841da177e4SLinus Torvalds #endif 885