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 1441da177e4SLinus Torvalds static inline unsigned long 14534e3759cSJiri Pirko cls_set_class(struct Qdisc *q, unsigned long *clp, unsigned long cl) 1461da177e4SLinus Torvalds { 1471da177e4SLinus Torvalds unsigned long old_cl; 1481da177e4SLinus Torvalds 14934e3759cSJiri Pirko sch_tree_lock(q); 1501da177e4SLinus Torvalds old_cl = __cls_set_class(clp, cl); 15134e3759cSJiri Pirko sch_tree_unlock(q); 1521da177e4SLinus Torvalds return old_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 unsigned long cl; 1601da177e4SLinus Torvalds 16134e3759cSJiri Pirko /* Check q as it is not set for shared blocks. In that case, 16234e3759cSJiri Pirko * setting class is not supported. 16334e3759cSJiri Pirko */ 16434e3759cSJiri Pirko if (!q) 16534e3759cSJiri Pirko return; 16634e3759cSJiri Pirko cl = q->ops->cl_ops->bind_tcf(q, base, r->classid); 16734e3759cSJiri Pirko cl = cls_set_class(q, &r->class, cl); 1681da177e4SLinus Torvalds if (cl) 16934e3759cSJiri Pirko q->ops->cl_ops->unbind_tcf(q, cl); 1701da177e4SLinus Torvalds } 1711da177e4SLinus Torvalds 1721da177e4SLinus Torvalds static inline void 1731da177e4SLinus Torvalds tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r) 1741da177e4SLinus Torvalds { 17534e3759cSJiri Pirko struct Qdisc *q = tp->chain->block->q; 1761da177e4SLinus Torvalds unsigned long cl; 1771da177e4SLinus Torvalds 17834e3759cSJiri Pirko if (!q) 17934e3759cSJiri Pirko return; 1801da177e4SLinus Torvalds if ((cl = __cls_set_class(&r->class, 0)) != 0) 18134e3759cSJiri Pirko q->ops->cl_ops->unbind_tcf(q, cl); 1821da177e4SLinus Torvalds } 1831da177e4SLinus Torvalds 184fd2c3ef7SEric Dumazet struct tcf_exts { 1851da177e4SLinus Torvalds #ifdef CONFIG_NET_CLS_ACT 18633be6271SWANG Cong __u32 type; /* for backward compat(TCA_OLD_COMPAT) */ 18722dc13c8SWANG Cong int nr_actions; 18822dc13c8SWANG Cong struct tc_action **actions; 189e4b95c41SCong Wang struct net *net; 1901da177e4SLinus Torvalds #endif 1911da177e4SLinus Torvalds /* Map to export classifier specific extension TLV types to the 1921da177e4SLinus Torvalds * generic extensions API. Unsupported extensions must be set to 0. 1931da177e4SLinus Torvalds */ 1941da177e4SLinus Torvalds int action; 1951da177e4SLinus Torvalds int police; 1961da177e4SLinus Torvalds }; 1971da177e4SLinus Torvalds 19814215108SCong Wang static inline int tcf_exts_init(struct tcf_exts *exts, struct net *net, 19914215108SCong Wang int action, int police) 20033be6271SWANG Cong { 20133be6271SWANG Cong #ifdef CONFIG_NET_CLS_ACT 2025da57f42SWANG Cong exts->type = 0; 20322dc13c8SWANG Cong exts->nr_actions = 0; 20414215108SCong Wang exts->net = net; 20522dc13c8SWANG Cong exts->actions = kcalloc(TCA_ACT_MAX_PRIO, sizeof(struct tc_action *), 20622dc13c8SWANG Cong GFP_KERNEL); 207b9a24bb7SWANG Cong if (!exts->actions) 208b9a24bb7SWANG Cong return -ENOMEM; 20933be6271SWANG Cong #endif 2105da57f42SWANG Cong exts->action = action; 2115da57f42SWANG Cong exts->police = police; 212b9a24bb7SWANG Cong return 0; 21333be6271SWANG Cong } 21433be6271SWANG Cong 215e4b95c41SCong Wang /* Return false if the netns is being destroyed in cleanup_net(). Callers 216e4b95c41SCong Wang * need to do cleanup synchronously in this case, otherwise may race with 217e4b95c41SCong Wang * tc_action_net_exit(). Return true for other cases. 218e4b95c41SCong Wang */ 219e4b95c41SCong Wang static inline bool tcf_exts_get_net(struct tcf_exts *exts) 220e4b95c41SCong Wang { 221e4b95c41SCong Wang #ifdef CONFIG_NET_CLS_ACT 222e4b95c41SCong Wang exts->net = maybe_get_net(exts->net); 223e4b95c41SCong Wang return exts->net != NULL; 224e4b95c41SCong Wang #else 225e4b95c41SCong Wang return true; 226e4b95c41SCong Wang #endif 227e4b95c41SCong Wang } 228e4b95c41SCong Wang 229e4b95c41SCong Wang static inline void tcf_exts_put_net(struct tcf_exts *exts) 230e4b95c41SCong Wang { 231e4b95c41SCong Wang #ifdef CONFIG_NET_CLS_ACT 232e4b95c41SCong Wang if (exts->net) 233e4b95c41SCong Wang put_net(exts->net); 234e4b95c41SCong Wang #endif 235e4b95c41SCong Wang } 236e4b95c41SCong Wang 23722dc13c8SWANG Cong #ifdef CONFIG_NET_CLS_ACT 238244cd96aSCong Wang #define tcf_exts_for_each_action(i, a, exts) \ 239244cd96aSCong Wang for (i = 0; i < TCA_ACT_MAX_PRIO && ((a) = (exts)->actions[i]); i++) 240244cd96aSCong Wang #else 241244cd96aSCong Wang #define tcf_exts_for_each_action(i, a, exts) \ 242191672caSArnd Bergmann for (; 0; (void)(i), (void)(a), (void)(exts)) 24322dc13c8SWANG Cong #endif 24422dc13c8SWANG Cong 245d897a638SJakub Kicinski static inline void 246d897a638SJakub Kicinski tcf_exts_stats_update(const struct tcf_exts *exts, 247d897a638SJakub Kicinski u64 bytes, u64 packets, u64 lastuse) 248d897a638SJakub Kicinski { 249d897a638SJakub Kicinski #ifdef CONFIG_NET_CLS_ACT 250d897a638SJakub Kicinski int i; 251d897a638SJakub Kicinski 252d897a638SJakub Kicinski preempt_disable(); 253d897a638SJakub Kicinski 254d897a638SJakub Kicinski for (i = 0; i < exts->nr_actions; i++) { 255d897a638SJakub Kicinski struct tc_action *a = exts->actions[i]; 256d897a638SJakub Kicinski 25728169abaSEelco Chaudron tcf_action_stats_update(a, bytes, packets, lastuse, true); 258d897a638SJakub Kicinski } 259d897a638SJakub Kicinski 260d897a638SJakub Kicinski preempt_enable(); 261d897a638SJakub Kicinski #endif 262d897a638SJakub Kicinski } 263d897a638SJakub Kicinski 2641da177e4SLinus Torvalds /** 2653bcc0cecSJiri Pirko * tcf_exts_has_actions - check if at least one action is present 2663bcc0cecSJiri Pirko * @exts: tc filter extensions handle 2673bcc0cecSJiri Pirko * 2683bcc0cecSJiri Pirko * Returns true if at least one action is present. 2693bcc0cecSJiri Pirko */ 2703bcc0cecSJiri Pirko static inline bool tcf_exts_has_actions(struct tcf_exts *exts) 2713bcc0cecSJiri Pirko { 2722734437eSWANG Cong #ifdef CONFIG_NET_CLS_ACT 2733bcc0cecSJiri Pirko return exts->nr_actions; 2743bcc0cecSJiri Pirko #else 2753bcc0cecSJiri Pirko return false; 2763bcc0cecSJiri Pirko #endif 2773bcc0cecSJiri Pirko } 2782734437eSWANG Cong 2793bcc0cecSJiri Pirko /** 280af69afc5SJiri Pirko * tcf_exts_exec - execute tc filter extensions 281af69afc5SJiri Pirko * @skb: socket buffer 282af69afc5SJiri Pirko * @exts: tc filter extensions handle 283af69afc5SJiri Pirko * @res: desired result 284af69afc5SJiri Pirko * 285af089e70SJiri Pirko * Executes all configured extensions. Returns TC_ACT_OK on a normal execution, 286af69afc5SJiri Pirko * a negative number if the filter must be considered unmatched or 287af69afc5SJiri Pirko * a positive action code (TC_ACT_*) which must be returned to the 288af69afc5SJiri Pirko * underlying layer. 289af69afc5SJiri Pirko */ 290af69afc5SJiri Pirko static inline int 291af69afc5SJiri Pirko tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts, 292af69afc5SJiri Pirko struct tcf_result *res) 293af69afc5SJiri Pirko { 294af69afc5SJiri Pirko #ifdef CONFIG_NET_CLS_ACT 295ec1a9ccaSJiri Pirko return tcf_action_exec(skb, exts->actions, exts->nr_actions, res); 296af69afc5SJiri Pirko #endif 297af089e70SJiri Pirko return TC_ACT_OK; 298af69afc5SJiri Pirko } 299af69afc5SJiri Pirko 3005c15257fSJoe Perches int tcf_exts_validate(struct net *net, struct tcf_proto *tp, 301c1b52739SBenjamin LaHaise struct nlattr **tb, struct nlattr *rate_tlv, 302ec6743a1SVlad Buslov struct tcf_exts *exts, bool ovr, bool rtnl_held, 30350a56190SAlexander Aring struct netlink_ext_ack *extack); 30418d0264fSWANG Cong void tcf_exts_destroy(struct tcf_exts *exts); 3059b0d4446SJiri Pirko void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src); 3065da57f42SWANG Cong int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts); 3075da57f42SWANG Cong int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts); 3081da177e4SLinus Torvalds 3091da177e4SLinus Torvalds /** 3101da177e4SLinus Torvalds * struct tcf_pkt_info - packet information 3111da177e4SLinus Torvalds */ 312fd2c3ef7SEric Dumazet struct tcf_pkt_info { 3131da177e4SLinus Torvalds unsigned char * ptr; 3141da177e4SLinus Torvalds int nexthdr; 3151da177e4SLinus Torvalds }; 3161da177e4SLinus Torvalds 3171da177e4SLinus Torvalds #ifdef CONFIG_NET_EMATCH 3181da177e4SLinus Torvalds 3191da177e4SLinus Torvalds struct tcf_ematch_ops; 3201da177e4SLinus Torvalds 3211da177e4SLinus Torvalds /** 3221da177e4SLinus Torvalds * struct tcf_ematch - extended match (ematch) 3231da177e4SLinus Torvalds * 3241da177e4SLinus Torvalds * @matchid: identifier to allow userspace to reidentify a match 3251da177e4SLinus Torvalds * @flags: flags specifying attributes and the relation to other matches 3261da177e4SLinus Torvalds * @ops: the operations lookup table of the corresponding ematch module 3271da177e4SLinus Torvalds * @datalen: length of the ematch specific configuration data 3281da177e4SLinus Torvalds * @data: ematch specific data 3291da177e4SLinus Torvalds */ 330fd2c3ef7SEric Dumazet struct tcf_ematch { 3311da177e4SLinus Torvalds struct tcf_ematch_ops * ops; 3321da177e4SLinus Torvalds unsigned long data; 3331da177e4SLinus Torvalds unsigned int datalen; 3341da177e4SLinus Torvalds u16 matchid; 3351da177e4SLinus Torvalds u16 flags; 33682a470f1SJohn Fastabend struct net *net; 3371da177e4SLinus Torvalds }; 3381da177e4SLinus Torvalds 3391da177e4SLinus Torvalds static inline int tcf_em_is_container(struct tcf_ematch *em) 3401da177e4SLinus Torvalds { 3411da177e4SLinus Torvalds return !em->ops; 3421da177e4SLinus Torvalds } 3431da177e4SLinus Torvalds 3441da177e4SLinus Torvalds static inline int tcf_em_is_simple(struct tcf_ematch *em) 3451da177e4SLinus Torvalds { 3461da177e4SLinus Torvalds return em->flags & TCF_EM_SIMPLE; 3471da177e4SLinus Torvalds } 3481da177e4SLinus Torvalds 3491da177e4SLinus Torvalds static inline int tcf_em_is_inverted(struct tcf_ematch *em) 3501da177e4SLinus Torvalds { 3511da177e4SLinus Torvalds return em->flags & TCF_EM_INVERT; 3521da177e4SLinus Torvalds } 3531da177e4SLinus Torvalds 3541da177e4SLinus Torvalds static inline int tcf_em_last_match(struct tcf_ematch *em) 3551da177e4SLinus Torvalds { 3561da177e4SLinus Torvalds return (em->flags & TCF_EM_REL_MASK) == TCF_EM_REL_END; 3571da177e4SLinus Torvalds } 3581da177e4SLinus Torvalds 3591da177e4SLinus Torvalds static inline int tcf_em_early_end(struct tcf_ematch *em, int result) 3601da177e4SLinus Torvalds { 3611da177e4SLinus Torvalds if (tcf_em_last_match(em)) 3621da177e4SLinus Torvalds return 1; 3631da177e4SLinus Torvalds 3641da177e4SLinus Torvalds if (result == 0 && em->flags & TCF_EM_REL_AND) 3651da177e4SLinus Torvalds return 1; 3661da177e4SLinus Torvalds 3671da177e4SLinus Torvalds if (result != 0 && em->flags & TCF_EM_REL_OR) 3681da177e4SLinus Torvalds return 1; 3691da177e4SLinus Torvalds 3701da177e4SLinus Torvalds return 0; 3711da177e4SLinus Torvalds } 3721da177e4SLinus Torvalds 3731da177e4SLinus Torvalds /** 3741da177e4SLinus Torvalds * struct tcf_ematch_tree - ematch tree handle 3751da177e4SLinus Torvalds * 3761da177e4SLinus Torvalds * @hdr: ematch tree header supplied by userspace 3771da177e4SLinus Torvalds * @matches: array of ematches 3781da177e4SLinus Torvalds */ 379fd2c3ef7SEric Dumazet struct tcf_ematch_tree { 3801da177e4SLinus Torvalds struct tcf_ematch_tree_hdr hdr; 3811da177e4SLinus Torvalds struct tcf_ematch * matches; 3821da177e4SLinus Torvalds 3831da177e4SLinus Torvalds }; 3841da177e4SLinus Torvalds 3851da177e4SLinus Torvalds /** 3861da177e4SLinus Torvalds * struct tcf_ematch_ops - ematch module operations 3871da177e4SLinus Torvalds * 3881da177e4SLinus Torvalds * @kind: identifier (kind) of this ematch module 3891da177e4SLinus Torvalds * @datalen: length of expected configuration data (optional) 3901da177e4SLinus Torvalds * @change: called during validation (optional) 3911da177e4SLinus Torvalds * @match: called during ematch tree evaluation, must return 1/0 3921da177e4SLinus Torvalds * @destroy: called during destroyage (optional) 3931da177e4SLinus Torvalds * @dump: called during dumping process (optional) 3941da177e4SLinus Torvalds * @owner: owner, must be set to THIS_MODULE 3951da177e4SLinus Torvalds * @link: link to previous/next ematch module (internal use) 3961da177e4SLinus Torvalds */ 397fd2c3ef7SEric Dumazet struct tcf_ematch_ops { 3981da177e4SLinus Torvalds int kind; 3991da177e4SLinus Torvalds int datalen; 40082a470f1SJohn Fastabend int (*change)(struct net *net, void *, 4011da177e4SLinus Torvalds int, struct tcf_ematch *); 4021da177e4SLinus Torvalds int (*match)(struct sk_buff *, struct tcf_ematch *, 4031da177e4SLinus Torvalds struct tcf_pkt_info *); 40482a470f1SJohn Fastabend void (*destroy)(struct tcf_ematch *); 4051da177e4SLinus Torvalds int (*dump)(struct sk_buff *, struct tcf_ematch *); 4061da177e4SLinus Torvalds struct module *owner; 4071da177e4SLinus Torvalds struct list_head link; 4081da177e4SLinus Torvalds }; 4091da177e4SLinus Torvalds 4105c15257fSJoe Perches int tcf_em_register(struct tcf_ematch_ops *); 4115c15257fSJoe Perches void tcf_em_unregister(struct tcf_ematch_ops *); 4125c15257fSJoe Perches int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *, 4131da177e4SLinus Torvalds struct tcf_ematch_tree *); 41482a470f1SJohn Fastabend void tcf_em_tree_destroy(struct tcf_ematch_tree *); 4155c15257fSJoe Perches int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int); 4165c15257fSJoe Perches int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *, 4171da177e4SLinus Torvalds struct tcf_pkt_info *); 4181da177e4SLinus Torvalds 4191da177e4SLinus Torvalds /** 4201da177e4SLinus Torvalds * tcf_em_tree_match - evaulate an ematch tree 4211da177e4SLinus Torvalds * 4221da177e4SLinus Torvalds * @skb: socket buffer of the packet in question 4231da177e4SLinus Torvalds * @tree: ematch tree to be used for evaluation 4241da177e4SLinus Torvalds * @info: packet information examined by classifier 4251da177e4SLinus Torvalds * 4261da177e4SLinus Torvalds * This function matches @skb against the ematch tree in @tree by going 4271da177e4SLinus Torvalds * through all ematches respecting their logic relations returning 4281da177e4SLinus Torvalds * as soon as the result is obvious. 4291da177e4SLinus Torvalds * 4301da177e4SLinus Torvalds * Returns 1 if the ematch tree as-one matches, no ematches are configured 4311da177e4SLinus Torvalds * or ematch is not enabled in the kernel, otherwise 0 is returned. 4321da177e4SLinus Torvalds */ 4331da177e4SLinus Torvalds static inline int tcf_em_tree_match(struct sk_buff *skb, 4341da177e4SLinus Torvalds struct tcf_ematch_tree *tree, 4351da177e4SLinus Torvalds struct tcf_pkt_info *info) 4361da177e4SLinus Torvalds { 4371da177e4SLinus Torvalds if (tree->hdr.nmatches) 4381da177e4SLinus Torvalds return __tcf_em_tree_match(skb, tree, info); 4391da177e4SLinus Torvalds else 4401da177e4SLinus Torvalds return 1; 4411da177e4SLinus Torvalds } 4421da177e4SLinus Torvalds 443db3d99c0SPatrick McHardy #define MODULE_ALIAS_TCF_EMATCH(kind) MODULE_ALIAS("ematch-kind-" __stringify(kind)) 444db3d99c0SPatrick McHardy 4451da177e4SLinus Torvalds #else /* CONFIG_NET_EMATCH */ 4461da177e4SLinus Torvalds 447fd2c3ef7SEric Dumazet struct tcf_ematch_tree { 4481da177e4SLinus Torvalds }; 4491da177e4SLinus Torvalds 4501da177e4SLinus Torvalds #define tcf_em_tree_validate(tp, tb, t) ((void)(t), 0) 45182a470f1SJohn Fastabend #define tcf_em_tree_destroy(t) do { (void)(t); } while(0) 4521da177e4SLinus Torvalds #define tcf_em_tree_dump(skb, t, tlv) (0) 4531da177e4SLinus Torvalds #define tcf_em_tree_match(skb, t, info) ((void)(info), 1) 4541da177e4SLinus Torvalds 4551da177e4SLinus Torvalds #endif /* CONFIG_NET_EMATCH */ 4561da177e4SLinus Torvalds 4571da177e4SLinus Torvalds static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer) 4581da177e4SLinus Torvalds { 4591da177e4SLinus Torvalds switch (layer) { 4601da177e4SLinus Torvalds case TCF_LAYER_LINK: 461d3303a65SWolfgang Bumiller return skb_mac_header(skb); 4621da177e4SLinus Torvalds case TCF_LAYER_NETWORK: 463d56f90a7SArnaldo Carvalho de Melo return skb_network_header(skb); 4641da177e4SLinus Torvalds case TCF_LAYER_TRANSPORT: 4659c70220bSArnaldo Carvalho de Melo return skb_transport_header(skb); 4661da177e4SLinus Torvalds } 4671da177e4SLinus Torvalds 4681da177e4SLinus Torvalds return NULL; 4691da177e4SLinus Torvalds } 4701da177e4SLinus Torvalds 471eddc9ec5SArnaldo Carvalho de Melo static inline int tcf_valid_offset(const struct sk_buff *skb, 472eddc9ec5SArnaldo Carvalho de Melo const unsigned char *ptr, const int len) 4731da177e4SLinus Torvalds { 474da521b2cSDavid S. Miller return likely((ptr + len) <= skb_tail_pointer(skb) && 475da521b2cSDavid S. Miller ptr >= skb->head && 476da521b2cSDavid S. Miller (ptr <= (ptr + len))); 4771da177e4SLinus Torvalds } 4781da177e4SLinus Torvalds 4791da177e4SLinus Torvalds static inline int 4801057c55fSAlexander Aring tcf_change_indev(struct net *net, struct nlattr *indev_tlv, 4811057c55fSAlexander Aring struct netlink_ext_ack *extack) 4821da177e4SLinus Torvalds { 4832519a602SWANG Cong char indev[IFNAMSIZ]; 484c01003c2SPatrick McHardy struct net_device *dev; 485c01003c2SPatrick McHardy 4861057c55fSAlexander Aring if (nla_strlcpy(indev, indev_tlv, IFNAMSIZ) >= IFNAMSIZ) { 4871057c55fSAlexander Aring NL_SET_ERR_MSG(extack, "Interface name too long"); 4882519a602SWANG Cong return -EINVAL; 4891057c55fSAlexander Aring } 4902519a602SWANG Cong dev = __dev_get_by_name(net, indev); 4912519a602SWANG Cong if (!dev) 4922519a602SWANG Cong return -ENODEV; 4932519a602SWANG Cong return dev->ifindex; 4941da177e4SLinus Torvalds } 4951da177e4SLinus Torvalds 4962519a602SWANG Cong static inline bool 4972519a602SWANG Cong tcf_match_indev(struct sk_buff *skb, int ifindex) 4982519a602SWANG Cong { 4992519a602SWANG Cong if (!ifindex) 5002519a602SWANG Cong return true; 5012519a602SWANG Cong if (!skb->skb_iif) 5022519a602SWANG Cong return false; 5032519a602SWANG Cong return ifindex == skb->skb_iif; 5041da177e4SLinus Torvalds } 5051da177e4SLinus Torvalds 5063a7b6861SPablo Neira Ayuso int tc_setup_flow_action(struct flow_action *flow_action, 5079838b20aSVlad Buslov const struct tcf_exts *exts, bool rtnl_held); 5085a6ff4b1SVlad Buslov void tc_cleanup_flow_action(struct flow_action *flow_action); 5095a6ff4b1SVlad Buslov 510aeb3fecdSCong Wang int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type, 51140119211SVlad Buslov void *type_data, bool err_stop, bool rtnl_held); 51240119211SVlad Buslov int tc_setup_cb_add(struct tcf_block *block, struct tcf_proto *tp, 51340119211SVlad Buslov enum tc_setup_type type, void *type_data, bool err_stop, 51440119211SVlad Buslov u32 *flags, unsigned int *in_hw_count, bool rtnl_held); 51540119211SVlad Buslov int tc_setup_cb_replace(struct tcf_block *block, struct tcf_proto *tp, 51640119211SVlad Buslov enum tc_setup_type type, void *type_data, bool err_stop, 51740119211SVlad Buslov u32 *old_flags, unsigned int *old_in_hw_count, 51840119211SVlad Buslov u32 *new_flags, unsigned int *new_in_hw_count, 51940119211SVlad Buslov bool rtnl_held); 52040119211SVlad Buslov int tc_setup_cb_destroy(struct tcf_block *block, struct tcf_proto *tp, 52140119211SVlad Buslov enum tc_setup_type type, void *type_data, bool err_stop, 52240119211SVlad Buslov u32 *flags, unsigned int *in_hw_count, bool rtnl_held); 52340119211SVlad Buslov int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp, 52440119211SVlad Buslov bool add, flow_setup_cb_t *cb, 52540119211SVlad Buslov enum tc_setup_type type, void *type_data, 52640119211SVlad Buslov void *cb_priv, u32 *flags, unsigned int *in_hw_count); 527e3ab786bSPablo Neira Ayuso unsigned int tcf_exts_num_actions(struct tcf_exts *exts); 528717503b9SJiri Pirko 529a1b7c5fdSJohn Fastabend struct tc_cls_u32_knode { 530a1b7c5fdSJohn Fastabend struct tcf_exts *exts; 531068ceb35SJakub Kicinski struct tcf_result *res; 532e014860eSJohn Fastabend struct tc_u32_sel *sel; 533a1b7c5fdSJohn Fastabend u32 handle; 534a1b7c5fdSJohn Fastabend u32 val; 535a1b7c5fdSJohn Fastabend u32 mask; 536a1b7c5fdSJohn Fastabend u32 link_handle; 537e014860eSJohn Fastabend u8 fshift; 538a1b7c5fdSJohn Fastabend }; 539a1b7c5fdSJohn Fastabend 540a1b7c5fdSJohn Fastabend struct tc_cls_u32_hnode { 541a1b7c5fdSJohn Fastabend u32 handle; 542a1b7c5fdSJohn Fastabend u32 prio; 543a1b7c5fdSJohn Fastabend unsigned int divisor; 544a1b7c5fdSJohn Fastabend }; 545a1b7c5fdSJohn Fastabend 546a1b7c5fdSJohn Fastabend enum tc_clsu32_command { 547a1b7c5fdSJohn Fastabend TC_CLSU32_NEW_KNODE, 548a1b7c5fdSJohn Fastabend TC_CLSU32_REPLACE_KNODE, 549a1b7c5fdSJohn Fastabend TC_CLSU32_DELETE_KNODE, 550a1b7c5fdSJohn Fastabend TC_CLSU32_NEW_HNODE, 551a1b7c5fdSJohn Fastabend TC_CLSU32_REPLACE_HNODE, 552a1b7c5fdSJohn Fastabend TC_CLSU32_DELETE_HNODE, 553a1b7c5fdSJohn Fastabend }; 554a1b7c5fdSJohn Fastabend 555a1b7c5fdSJohn Fastabend struct tc_cls_u32_offload { 556f9e30088SPablo Neira Ayuso struct flow_cls_common_offload common; 557a1b7c5fdSJohn Fastabend /* knode values */ 558a1b7c5fdSJohn Fastabend enum tc_clsu32_command command; 559a1b7c5fdSJohn Fastabend union { 560a1b7c5fdSJohn Fastabend struct tc_cls_u32_knode knode; 561a1b7c5fdSJohn Fastabend struct tc_cls_u32_hnode hnode; 562a1b7c5fdSJohn Fastabend }; 563a1b7c5fdSJohn Fastabend }; 564a1b7c5fdSJohn Fastabend 5657b06e8aeSJiri Pirko static inline bool tc_can_offload(const struct net_device *dev) 5666843e7a2SJohn Fastabend { 56770b5aee4SJiri Pirko return dev->features & NETIF_F_HW_TC; 5686843e7a2SJohn Fastabend } 5696843e7a2SJohn Fastabend 570f9eda14fSQuentin Monnet static inline bool tc_can_offload_extack(const struct net_device *dev, 571f9eda14fSQuentin Monnet struct netlink_ext_ack *extack) 572f9eda14fSQuentin Monnet { 573f9eda14fSQuentin Monnet bool can = tc_can_offload(dev); 574f9eda14fSQuentin Monnet 575f9eda14fSQuentin Monnet if (!can) 576f9eda14fSQuentin Monnet NL_SET_ERR_MSG(extack, "TC offload is disabled on net device"); 577f9eda14fSQuentin Monnet 578f9eda14fSQuentin Monnet return can; 579f9eda14fSQuentin Monnet } 580f9eda14fSQuentin Monnet 581878db9f0SJakub Kicinski static inline bool 582878db9f0SJakub Kicinski tc_cls_can_offload_and_chain0(const struct net_device *dev, 583f9e30088SPablo Neira Ayuso struct flow_cls_common_offload *common) 584878db9f0SJakub Kicinski { 585878db9f0SJakub Kicinski if (!tc_can_offload_extack(dev, common->extack)) 586878db9f0SJakub Kicinski return false; 587878db9f0SJakub Kicinski if (common->chain_index) { 588878db9f0SJakub Kicinski NL_SET_ERR_MSG(common->extack, 589878db9f0SJakub Kicinski "Driver supports only offload of chain 0"); 590878db9f0SJakub Kicinski return false; 591878db9f0SJakub Kicinski } 592878db9f0SJakub Kicinski return true; 593878db9f0SJakub Kicinski } 594878db9f0SJakub Kicinski 59555330f05SHadar Hen Zion static inline bool tc_skip_hw(u32 flags) 59655330f05SHadar Hen Zion { 59755330f05SHadar Hen Zion return (flags & TCA_CLS_FLAGS_SKIP_HW) ? true : false; 59855330f05SHadar Hen Zion } 59955330f05SHadar Hen Zion 600d34e3e18SSamudrala, Sridhar static inline bool tc_skip_sw(u32 flags) 601d34e3e18SSamudrala, Sridhar { 602d34e3e18SSamudrala, Sridhar return (flags & TCA_CLS_FLAGS_SKIP_SW) ? true : false; 603d34e3e18SSamudrala, Sridhar } 604d34e3e18SSamudrala, Sridhar 605d34e3e18SSamudrala, Sridhar /* SKIP_HW and SKIP_SW are mutually exclusive flags. */ 606d34e3e18SSamudrala, Sridhar static inline bool tc_flags_valid(u32 flags) 607d34e3e18SSamudrala, Sridhar { 60881c7288bSMarcelo Ricardo Leitner if (flags & ~(TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW | 60981c7288bSMarcelo Ricardo Leitner TCA_CLS_FLAGS_VERBOSE)) 610d34e3e18SSamudrala, Sridhar return false; 611d34e3e18SSamudrala, Sridhar 61281c7288bSMarcelo Ricardo Leitner flags &= TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW; 613d34e3e18SSamudrala, Sridhar if (!(flags ^ (TCA_CLS_FLAGS_SKIP_HW | TCA_CLS_FLAGS_SKIP_SW))) 614d34e3e18SSamudrala, Sridhar return false; 615d34e3e18SSamudrala, Sridhar 616d34e3e18SSamudrala, Sridhar return true; 617d34e3e18SSamudrala, Sridhar } 618d34e3e18SSamudrala, Sridhar 619e696028aSOr Gerlitz static inline bool tc_in_hw(u32 flags) 620e696028aSOr Gerlitz { 621e696028aSOr Gerlitz return (flags & TCA_CLS_FLAGS_IN_HW) ? true : false; 622e696028aSOr Gerlitz } 623e696028aSOr Gerlitz 62434832e1cSJakub Kicinski static inline void 625f9e30088SPablo Neira Ayuso tc_cls_common_offload_init(struct flow_cls_common_offload *cls_common, 62634832e1cSJakub Kicinski const struct tcf_proto *tp, u32 flags, 62734832e1cSJakub Kicinski struct netlink_ext_ack *extack) 62834832e1cSJakub Kicinski { 62934832e1cSJakub Kicinski cls_common->chain_index = tp->chain->index; 63034832e1cSJakub Kicinski cls_common->protocol = tp->protocol; 631ef01adaeSPablo Neira Ayuso cls_common->prio = tp->prio >> 16; 63281c7288bSMarcelo Ricardo Leitner if (tc_skip_sw(flags) || flags & TCA_CLS_FLAGS_VERBOSE) 63334832e1cSJakub Kicinski cls_common->extack = extack; 63434832e1cSJakub Kicinski } 63534832e1cSJakub Kicinski 636b87f7936SYotam Gigi enum tc_matchall_command { 637b87f7936SYotam Gigi TC_CLSMATCHALL_REPLACE, 638b87f7936SYotam Gigi TC_CLSMATCHALL_DESTROY, 639b7fe4ab8SPieter Jansen van Vuuren TC_CLSMATCHALL_STATS, 640b87f7936SYotam Gigi }; 641b87f7936SYotam Gigi 642b87f7936SYotam Gigi struct tc_cls_matchall_offload { 643f9e30088SPablo Neira Ayuso struct flow_cls_common_offload common; 644b87f7936SYotam Gigi enum tc_matchall_command command; 645f00cbf19SPieter Jansen van Vuuren struct flow_rule *rule; 646b7fe4ab8SPieter Jansen van Vuuren struct flow_stats stats; 647b87f7936SYotam Gigi unsigned long cookie; 648b87f7936SYotam Gigi }; 649b87f7936SYotam Gigi 650332ae8e2SJakub Kicinski enum tc_clsbpf_command { 651102740bdSJakub Kicinski TC_CLSBPF_OFFLOAD, 65268d64063SJakub Kicinski TC_CLSBPF_STATS, 653332ae8e2SJakub Kicinski }; 654332ae8e2SJakub Kicinski 655332ae8e2SJakub Kicinski struct tc_cls_bpf_offload { 656f9e30088SPablo Neira Ayuso struct flow_cls_common_offload common; 657332ae8e2SJakub Kicinski enum tc_clsbpf_command command; 658332ae8e2SJakub Kicinski struct tcf_exts *exts; 659332ae8e2SJakub Kicinski struct bpf_prog *prog; 660102740bdSJakub Kicinski struct bpf_prog *oldprog; 661332ae8e2SJakub Kicinski const char *name; 662332ae8e2SJakub Kicinski bool exts_integrated; 663332ae8e2SJakub Kicinski }; 664332ae8e2SJakub Kicinski 6654e8b86c0SAmritha Nambiar struct tc_mqprio_qopt_offload { 6664e8b86c0SAmritha Nambiar /* struct tc_mqprio_qopt must always be the first element */ 6674e8b86c0SAmritha Nambiar struct tc_mqprio_qopt qopt; 6684e8b86c0SAmritha Nambiar u16 mode; 6694e8b86c0SAmritha Nambiar u16 shaper; 6704e8b86c0SAmritha Nambiar u32 flags; 6714e8b86c0SAmritha Nambiar u64 min_rate[TC_QOPT_MAX_QUEUE]; 6724e8b86c0SAmritha Nambiar u64 max_rate[TC_QOPT_MAX_QUEUE]; 6734e8b86c0SAmritha Nambiar }; 6741045ba77SJamal Hadi Salim 6751045ba77SJamal Hadi Salim /* This structure holds cookie structure that is passed from user 6761045ba77SJamal Hadi Salim * to the kernel for actions and classifiers 6771045ba77SJamal Hadi Salim */ 6781045ba77SJamal Hadi Salim struct tc_cookie { 6791045ba77SJamal Hadi Salim u8 *data; 6801045ba77SJamal Hadi Salim u32 len; 681eec94fdbSVlad Buslov struct rcu_head rcu; 6821045ba77SJamal Hadi Salim }; 683602f3bafSNogah Frankel 684f34b4aacSNogah Frankel struct tc_qopt_offload_stats { 685f34b4aacSNogah Frankel struct gnet_stats_basic_packed *bstats; 686f34b4aacSNogah Frankel struct gnet_stats_queue *qstats; 687f34b4aacSNogah Frankel }; 688f34b4aacSNogah Frankel 689f971b132SJakub Kicinski enum tc_mq_command { 690f971b132SJakub Kicinski TC_MQ_CREATE, 691f971b132SJakub Kicinski TC_MQ_DESTROY, 69247c669a4SJakub Kicinski TC_MQ_STATS, 693d577a3d2SJakub Kicinski TC_MQ_GRAFT, 694d577a3d2SJakub Kicinski }; 695d577a3d2SJakub Kicinski 696d577a3d2SJakub Kicinski struct tc_mq_opt_offload_graft_params { 697d577a3d2SJakub Kicinski unsigned long queue; 698d577a3d2SJakub Kicinski u32 child_handle; 699f971b132SJakub Kicinski }; 700f971b132SJakub Kicinski 701f971b132SJakub Kicinski struct tc_mq_qopt_offload { 702f971b132SJakub Kicinski enum tc_mq_command command; 703f971b132SJakub Kicinski u32 handle; 704d577a3d2SJakub Kicinski union { 70547c669a4SJakub Kicinski struct tc_qopt_offload_stats stats; 706d577a3d2SJakub Kicinski struct tc_mq_opt_offload_graft_params graft_params; 707d577a3d2SJakub Kicinski }; 708f971b132SJakub Kicinski }; 709f971b132SJakub Kicinski 710602f3bafSNogah Frankel enum tc_red_command { 711602f3bafSNogah Frankel TC_RED_REPLACE, 712602f3bafSNogah Frankel TC_RED_DESTROY, 713602f3bafSNogah Frankel TC_RED_STATS, 714602f3bafSNogah Frankel TC_RED_XSTATS, 715bf2a752bSJakub Kicinski TC_RED_GRAFT, 716602f3bafSNogah Frankel }; 717602f3bafSNogah Frankel 718602f3bafSNogah Frankel struct tc_red_qopt_offload_params { 719602f3bafSNogah Frankel u32 min; 720602f3bafSNogah Frankel u32 max; 721602f3bafSNogah Frankel u32 probability; 722c0b7490bSJakub Kicinski u32 limit; 723602f3bafSNogah Frankel bool is_ecn; 724190852a5SJakub Kicinski bool is_harddrop; 725416ef9b1SJakub Kicinski struct gnet_stats_queue *qstats; 726602f3bafSNogah Frankel }; 727602f3bafSNogah Frankel 728602f3bafSNogah Frankel struct tc_red_qopt_offload { 729602f3bafSNogah Frankel enum tc_red_command command; 730602f3bafSNogah Frankel u32 handle; 731602f3bafSNogah Frankel u32 parent; 732602f3bafSNogah Frankel union { 733602f3bafSNogah Frankel struct tc_red_qopt_offload_params set; 734f34b4aacSNogah Frankel struct tc_qopt_offload_stats stats; 735602f3bafSNogah Frankel struct red_stats *xstats; 736bf2a752bSJakub Kicinski u32 child_handle; 737602f3bafSNogah Frankel }; 738602f3bafSNogah Frankel }; 739602f3bafSNogah Frankel 740890d8d23SJakub Kicinski enum tc_gred_command { 741890d8d23SJakub Kicinski TC_GRED_REPLACE, 742890d8d23SJakub Kicinski TC_GRED_DESTROY, 743e49efd52SJakub Kicinski TC_GRED_STATS, 744890d8d23SJakub Kicinski }; 745890d8d23SJakub Kicinski 746890d8d23SJakub Kicinski struct tc_gred_vq_qopt_offload_params { 747890d8d23SJakub Kicinski bool present; 748890d8d23SJakub Kicinski u32 limit; 749890d8d23SJakub Kicinski u32 prio; 750890d8d23SJakub Kicinski u32 min; 751890d8d23SJakub Kicinski u32 max; 752890d8d23SJakub Kicinski bool is_ecn; 753890d8d23SJakub Kicinski bool is_harddrop; 754890d8d23SJakub Kicinski u32 probability; 755890d8d23SJakub Kicinski /* Only need backlog, see struct tc_prio_qopt_offload_params */ 756890d8d23SJakub Kicinski u32 *backlog; 757890d8d23SJakub Kicinski }; 758890d8d23SJakub Kicinski 759890d8d23SJakub Kicinski struct tc_gred_qopt_offload_params { 760890d8d23SJakub Kicinski bool grio_on; 761890d8d23SJakub Kicinski bool wred_on; 762890d8d23SJakub Kicinski unsigned int dp_cnt; 763890d8d23SJakub Kicinski unsigned int dp_def; 764890d8d23SJakub Kicinski struct gnet_stats_queue *qstats; 765890d8d23SJakub Kicinski struct tc_gred_vq_qopt_offload_params tab[MAX_DPs]; 766890d8d23SJakub Kicinski }; 767890d8d23SJakub Kicinski 768e49efd52SJakub Kicinski struct tc_gred_qopt_offload_stats { 769e49efd52SJakub Kicinski struct gnet_stats_basic_packed bstats[MAX_DPs]; 770e49efd52SJakub Kicinski struct gnet_stats_queue qstats[MAX_DPs]; 771e49efd52SJakub Kicinski struct red_stats *xstats[MAX_DPs]; 772e49efd52SJakub Kicinski }; 773e49efd52SJakub Kicinski 774890d8d23SJakub Kicinski struct tc_gred_qopt_offload { 775890d8d23SJakub Kicinski enum tc_gred_command command; 776890d8d23SJakub Kicinski u32 handle; 777890d8d23SJakub Kicinski u32 parent; 778890d8d23SJakub Kicinski union { 779890d8d23SJakub Kicinski struct tc_gred_qopt_offload_params set; 780e49efd52SJakub Kicinski struct tc_gred_qopt_offload_stats stats; 781890d8d23SJakub Kicinski }; 782890d8d23SJakub Kicinski }; 783890d8d23SJakub Kicinski 7847fdb61b4SNogah Frankel enum tc_prio_command { 7857fdb61b4SNogah Frankel TC_PRIO_REPLACE, 7867fdb61b4SNogah Frankel TC_PRIO_DESTROY, 7877fdb61b4SNogah Frankel TC_PRIO_STATS, 788b9c7a7acSNogah Frankel TC_PRIO_GRAFT, 7897fdb61b4SNogah Frankel }; 7907fdb61b4SNogah Frankel 7917fdb61b4SNogah Frankel struct tc_prio_qopt_offload_params { 7927fdb61b4SNogah Frankel int bands; 7937fdb61b4SNogah Frankel u8 priomap[TC_PRIO_MAX + 1]; 7949586a992SPetr Machata /* At the point of un-offloading the Qdisc, the reported backlog and 7959586a992SPetr Machata * qlen need to be reduced by the portion that is in HW. 7967fdb61b4SNogah Frankel */ 7977fdb61b4SNogah Frankel struct gnet_stats_queue *qstats; 7987fdb61b4SNogah Frankel }; 7997fdb61b4SNogah Frankel 800b9c7a7acSNogah Frankel struct tc_prio_qopt_offload_graft_params { 801b9c7a7acSNogah Frankel u8 band; 802b9c7a7acSNogah Frankel u32 child_handle; 803b9c7a7acSNogah Frankel }; 804b9c7a7acSNogah Frankel 8057fdb61b4SNogah Frankel struct tc_prio_qopt_offload { 8067fdb61b4SNogah Frankel enum tc_prio_command command; 8077fdb61b4SNogah Frankel u32 handle; 8087fdb61b4SNogah Frankel u32 parent; 8097fdb61b4SNogah Frankel union { 8107fdb61b4SNogah Frankel struct tc_prio_qopt_offload_params replace_params; 8117fdb61b4SNogah Frankel struct tc_qopt_offload_stats stats; 812b9c7a7acSNogah Frankel struct tc_prio_qopt_offload_graft_params graft_params; 8137fdb61b4SNogah Frankel }; 8147fdb61b4SNogah Frankel }; 815b9c7a7acSNogah Frankel 81698b0e5f6SJakub Kicinski enum tc_root_command { 81798b0e5f6SJakub Kicinski TC_ROOT_GRAFT, 81898b0e5f6SJakub Kicinski }; 81998b0e5f6SJakub Kicinski 82098b0e5f6SJakub Kicinski struct tc_root_qopt_offload { 82198b0e5f6SJakub Kicinski enum tc_root_command command; 82298b0e5f6SJakub Kicinski u32 handle; 82398b0e5f6SJakub Kicinski bool ingress; 82498b0e5f6SJakub Kicinski }; 82598b0e5f6SJakub Kicinski 826d35eb52bSPetr Machata enum tc_ets_command { 827d35eb52bSPetr Machata TC_ETS_REPLACE, 828d35eb52bSPetr Machata TC_ETS_DESTROY, 829d35eb52bSPetr Machata TC_ETS_STATS, 830d35eb52bSPetr Machata TC_ETS_GRAFT, 831d35eb52bSPetr Machata }; 832d35eb52bSPetr Machata 833d35eb52bSPetr Machata struct tc_ets_qopt_offload_replace_params { 834d35eb52bSPetr Machata unsigned int bands; 835d35eb52bSPetr Machata u8 priomap[TC_PRIO_MAX + 1]; 836d35eb52bSPetr Machata unsigned int quanta[TCQ_ETS_MAX_BANDS]; /* 0 for strict bands. */ 837d35eb52bSPetr Machata unsigned int weights[TCQ_ETS_MAX_BANDS]; 838d35eb52bSPetr Machata struct gnet_stats_queue *qstats; 839d35eb52bSPetr Machata }; 840d35eb52bSPetr Machata 841d35eb52bSPetr Machata struct tc_ets_qopt_offload_graft_params { 842d35eb52bSPetr Machata u8 band; 843d35eb52bSPetr Machata u32 child_handle; 844d35eb52bSPetr Machata }; 845d35eb52bSPetr Machata 846d35eb52bSPetr Machata struct tc_ets_qopt_offload { 847d35eb52bSPetr Machata enum tc_ets_command command; 848d35eb52bSPetr Machata u32 handle; 849d35eb52bSPetr Machata u32 parent; 850d35eb52bSPetr Machata union { 851d35eb52bSPetr Machata struct tc_ets_qopt_offload_replace_params replace_params; 852d35eb52bSPetr Machata struct tc_qopt_offload_stats stats; 853d35eb52bSPetr Machata struct tc_ets_qopt_offload_graft_params graft_params; 854d35eb52bSPetr Machata }; 855d35eb52bSPetr Machata }; 856d35eb52bSPetr Machata 857ef6aadccSPetr Machata enum tc_tbf_command { 858ef6aadccSPetr Machata TC_TBF_REPLACE, 859ef6aadccSPetr Machata TC_TBF_DESTROY, 860ef6aadccSPetr Machata TC_TBF_STATS, 861ef6aadccSPetr Machata }; 862ef6aadccSPetr Machata 863ef6aadccSPetr Machata struct tc_tbf_qopt_offload_replace_params { 864ef6aadccSPetr Machata struct psched_ratecfg rate; 865ef6aadccSPetr Machata u32 max_size; 866ef6aadccSPetr Machata struct gnet_stats_queue *qstats; 867ef6aadccSPetr Machata }; 868ef6aadccSPetr Machata 869ef6aadccSPetr Machata struct tc_tbf_qopt_offload { 870ef6aadccSPetr Machata enum tc_tbf_command command; 871ef6aadccSPetr Machata u32 handle; 872ef6aadccSPetr Machata u32 parent; 873ef6aadccSPetr Machata union { 874ef6aadccSPetr Machata struct tc_tbf_qopt_offload_replace_params replace_params; 875ef6aadccSPetr Machata struct tc_qopt_offload_stats stats; 876ef6aadccSPetr Machata }; 877ef6aadccSPetr Machata }; 878ef6aadccSPetr Machata 8791da177e4SLinus Torvalds #endif 880