#ifndef __NET_PKT_CLS_H
#define __NET_PKT_CLS_H
#include <linux/pkt_cls.h>
#include <linux/workqueue.h>
#include <net/sch_generic.h>
#include <net/act_api.h>
#include <net/net_namespace.h>
#define TC_ACT_CONSUMED …
struct tcf_walker { … };
int register_tcf_proto_ops(struct tcf_proto_ops *ops);
void unregister_tcf_proto_ops(struct tcf_proto_ops *ops);
#define NET_CLS_ALIAS_PREFIX …
#define MODULE_ALIAS_NET_CLS(kind) …
struct tcf_block_ext_info { … };
struct tcf_qevent { … };
struct tcf_block_cb;
bool tcf_queue_work(struct rcu_work *rwork, work_func_t func);
#ifdef CONFIG_NET_CLS
struct tcf_chain *tcf_chain_get_by_act(struct tcf_block *block,
u32 chain_index);
void tcf_chain_put_by_act(struct tcf_chain *chain);
struct tcf_chain *tcf_get_next_chain(struct tcf_block *block,
struct tcf_chain *chain);
struct tcf_proto *tcf_get_next_proto(struct tcf_chain *chain,
struct tcf_proto *tp);
void tcf_block_netif_keep_dst(struct tcf_block *block);
int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
struct netlink_ext_ack *extack);
int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
struct tcf_block_ext_info *ei,
struct netlink_ext_ack *extack);
void tcf_block_put(struct tcf_block *block);
void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
struct tcf_block_ext_info *ei);
int tcf_exts_init_ex(struct tcf_exts *exts, struct net *net, int action,
int police, struct tcf_proto *tp, u32 handle, bool used_action_miss);
static inline bool tcf_block_shared(struct tcf_block *block)
{ … }
static inline bool tcf_block_non_null_shared(struct tcf_block *block)
{ … }
#ifdef CONFIG_NET_CLS_ACT
DECLARE_STATIC_KEY_FALSE(tcf_bypass_check_needed_key);
static inline bool tcf_block_bypass_sw(struct tcf_block *block)
{ … }
#endif
static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
{ … }
int tcf_classify(struct sk_buff *skb,
const struct tcf_block *block,
const struct tcf_proto *tp, struct tcf_result *res,
bool compat_mode);
static inline bool tc_cls_stats_dump(struct tcf_proto *tp,
struct tcf_walker *arg,
void *filter)
{ … }
#else
static inline bool tcf_block_shared(struct tcf_block *block)
{
return false;
}
static inline bool tcf_block_non_null_shared(struct tcf_block *block)
{
return false;
}
static inline
int tcf_block_get(struct tcf_block **p_block,
struct tcf_proto __rcu **p_filter_chain, struct Qdisc *q,
struct netlink_ext_ack *extack)
{
return 0;
}
static inline
int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q,
struct tcf_block_ext_info *ei,
struct netlink_ext_ack *extack)
{
return 0;
}
static inline void tcf_block_put(struct tcf_block *block)
{
}
static inline
void tcf_block_put_ext(struct tcf_block *block, struct Qdisc *q,
struct tcf_block_ext_info *ei)
{
}
static inline struct Qdisc *tcf_block_q(struct tcf_block *block)
{
return NULL;
}
static inline int tcf_classify(struct sk_buff *skb,
const struct tcf_block *block,
const struct tcf_proto *tp,
struct tcf_result *res, bool compat_mode)
{
return TC_ACT_UNSPEC;
}
#endif
static inline unsigned long
__cls_set_class(unsigned long *clp, unsigned long cl)
{ … }
static inline void
__tcf_bind_filter(struct Qdisc *q, struct tcf_result *r, unsigned long base)
{ … }
static inline void
tcf_bind_filter(struct tcf_proto *tp, struct tcf_result *r, unsigned long base)
{ … }
static inline void
__tcf_unbind_filter(struct Qdisc *q, struct tcf_result *r)
{ … }
static inline void
tcf_unbind_filter(struct tcf_proto *tp, struct tcf_result *r)
{ … }
static inline void tc_cls_bind_class(u32 classid, unsigned long cl,
void *q, struct tcf_result *res,
unsigned long base)
{ … }
struct tcf_exts { … };
static inline int tcf_exts_init(struct tcf_exts *exts, struct net *net,
int action, int police)
{ … }
static inline bool tcf_exts_get_net(struct tcf_exts *exts)
{ … }
static inline void tcf_exts_put_net(struct tcf_exts *exts)
{ … }
#ifdef CONFIG_NET_CLS_ACT
#define tcf_exts_for_each_action(i, a, exts) …
#else
#define tcf_exts_for_each_action …
#endif
#define tcf_act_for_each_action(i, a, actions) …
static inline bool tc_act_in_hw(struct tc_action *act)
{ … }
static inline void
tcf_exts_hw_stats_update(const struct tcf_exts *exts,
struct flow_stats *stats,
bool use_act_stats)
{ … }
static inline bool tcf_exts_has_actions(struct tcf_exts *exts)
{ … }
static inline int
tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
struct tcf_result *res)
{ … }
static inline int
tcf_exts_exec_ex(struct sk_buff *skb, struct tcf_exts *exts, int act_index,
struct tcf_result *res)
{ … }
int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
struct nlattr **tb, struct nlattr *rate_tlv,
struct tcf_exts *exts, u32 flags,
struct netlink_ext_ack *extack);
int tcf_exts_validate_ex(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
struct nlattr *rate_tlv, struct tcf_exts *exts,
u32 flags, u32 fl_flags, struct netlink_ext_ack *extack);
void tcf_exts_destroy(struct tcf_exts *exts);
void tcf_exts_change(struct tcf_exts *dst, struct tcf_exts *src);
int tcf_exts_dump(struct sk_buff *skb, struct tcf_exts *exts);
int tcf_exts_terse_dump(struct sk_buff *skb, struct tcf_exts *exts);
int tcf_exts_dump_stats(struct sk_buff *skb, struct tcf_exts *exts);
struct tcf_pkt_info { … };
#ifdef CONFIG_NET_EMATCH
struct tcf_ematch_ops;
struct tcf_ematch { … };
static inline int tcf_em_is_container(struct tcf_ematch *em)
{ … }
static inline int tcf_em_is_simple(struct tcf_ematch *em)
{ … }
static inline int tcf_em_is_inverted(struct tcf_ematch *em)
{ … }
static inline int tcf_em_last_match(struct tcf_ematch *em)
{ … }
static inline int tcf_em_early_end(struct tcf_ematch *em, int result)
{ … }
struct tcf_ematch_tree { … };
struct tcf_ematch_ops { … };
int tcf_em_register(struct tcf_ematch_ops *);
void tcf_em_unregister(struct tcf_ematch_ops *);
int tcf_em_tree_validate(struct tcf_proto *, struct nlattr *,
struct tcf_ematch_tree *);
void tcf_em_tree_destroy(struct tcf_ematch_tree *);
int tcf_em_tree_dump(struct sk_buff *, struct tcf_ematch_tree *, int);
int __tcf_em_tree_match(struct sk_buff *, struct tcf_ematch_tree *,
struct tcf_pkt_info *);
static inline int tcf_em_tree_match(struct sk_buff *skb,
struct tcf_ematch_tree *tree,
struct tcf_pkt_info *info)
{ … }
#define MODULE_ALIAS_TCF_EMATCH(kind) …
#else
struct tcf_ematch_tree {
};
#define tcf_em_tree_validate …
#define tcf_em_tree_destroy …
#define tcf_em_tree_dump …
#define tcf_em_tree_match …
#endif
static inline unsigned char * tcf_get_base_ptr(struct sk_buff *skb, int layer)
{ … }
static inline int tcf_valid_offset(const struct sk_buff *skb,
const unsigned char *ptr, const int len)
{ … }
static inline int
tcf_change_indev(struct net *net, struct nlattr *indev_tlv,
struct netlink_ext_ack *extack)
{ … }
static inline bool
tcf_match_indev(struct sk_buff *skb, int ifindex)
{ … }
int tc_setup_offload_action(struct flow_action *flow_action,
const struct tcf_exts *exts,
struct netlink_ext_ack *extack);
void tc_cleanup_offload_action(struct flow_action *flow_action);
int tc_setup_action(struct flow_action *flow_action,
struct tc_action *actions[],
u32 miss_cookie_base,
struct netlink_ext_ack *extack);
int tc_setup_cb_call(struct tcf_block *block, enum tc_setup_type type,
void *type_data, bool err_stop, bool rtnl_held);
int tc_setup_cb_add(struct tcf_block *block, struct tcf_proto *tp,
enum tc_setup_type type, void *type_data, bool err_stop,
u32 *flags, unsigned int *in_hw_count, bool rtnl_held);
int tc_setup_cb_replace(struct tcf_block *block, struct tcf_proto *tp,
enum tc_setup_type type, void *type_data, bool err_stop,
u32 *old_flags, unsigned int *old_in_hw_count,
u32 *new_flags, unsigned int *new_in_hw_count,
bool rtnl_held);
int tc_setup_cb_destroy(struct tcf_block *block, struct tcf_proto *tp,
enum tc_setup_type type, void *type_data, bool err_stop,
u32 *flags, unsigned int *in_hw_count, bool rtnl_held);
int tc_setup_cb_reoffload(struct tcf_block *block, struct tcf_proto *tp,
bool add, flow_setup_cb_t *cb,
enum tc_setup_type type, void *type_data,
void *cb_priv, u32 *flags, unsigned int *in_hw_count);
unsigned int tcf_exts_num_actions(struct tcf_exts *exts);
#ifdef CONFIG_NET_CLS_ACT
int tcf_qevent_init(struct tcf_qevent *qe, struct Qdisc *sch,
enum flow_block_binder_type binder_type,
struct nlattr *block_index_attr,
struct netlink_ext_ack *extack);
void tcf_qevent_destroy(struct tcf_qevent *qe, struct Qdisc *sch);
int tcf_qevent_validate_change(struct tcf_qevent *qe, struct nlattr *block_index_attr,
struct netlink_ext_ack *extack);
struct sk_buff *tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, struct sk_buff *skb,
struct sk_buff **to_free, int *ret);
int tcf_qevent_dump(struct sk_buff *skb, int attr_name, struct tcf_qevent *qe);
#else
static inline int tcf_qevent_init(struct tcf_qevent *qe, struct Qdisc *sch,
enum flow_block_binder_type binder_type,
struct nlattr *block_index_attr,
struct netlink_ext_ack *extack)
{
return 0;
}
static inline void tcf_qevent_destroy(struct tcf_qevent *qe, struct Qdisc *sch)
{
}
static inline int tcf_qevent_validate_change(struct tcf_qevent *qe, struct nlattr *block_index_attr,
struct netlink_ext_ack *extack)
{
return 0;
}
static inline struct sk_buff *
tcf_qevent_handle(struct tcf_qevent *qe, struct Qdisc *sch, struct sk_buff *skb,
struct sk_buff **to_free, int *ret)
{
return skb;
}
static inline int tcf_qevent_dump(struct sk_buff *skb, int attr_name, struct tcf_qevent *qe)
{
return 0;
}
#endif
struct tc_cls_u32_knode { … };
struct tc_cls_u32_hnode { … };
enum tc_clsu32_command { … };
struct tc_cls_u32_offload { … };
static inline bool tc_can_offload(const struct net_device *dev)
{ … }
static inline bool tc_can_offload_extack(const struct net_device *dev,
struct netlink_ext_ack *extack)
{ … }
static inline bool
tc_cls_can_offload_and_chain0(const struct net_device *dev,
struct flow_cls_common_offload *common)
{ … }
static inline bool tc_skip_hw(u32 flags)
{ … }
static inline bool tc_skip_sw(u32 flags)
{ … }
static inline bool tc_flags_valid(u32 flags)
{ … }
static inline bool tc_in_hw(u32 flags)
{ … }
static inline void
tc_cls_common_offload_init(struct flow_cls_common_offload *cls_common,
const struct tcf_proto *tp, u32 flags,
struct netlink_ext_ack *extack)
{ … }
#if IS_ENABLED(CONFIG_NET_TC_SKB_EXT)
static inline struct tc_skb_ext *tc_skb_ext_alloc(struct sk_buff *skb)
{ … }
#endif
enum tc_matchall_command { … };
struct tc_cls_matchall_offload { … };
enum tc_clsbpf_command { … };
struct tc_cls_bpf_offload { … };
struct tc_cookie { … };
struct tc_qopt_offload_stats { … };
enum tc_mq_command { … };
struct tc_mq_opt_offload_graft_params { … };
struct tc_mq_qopt_offload { … };
enum tc_htb_command { … };
struct tc_htb_qopt_offload { … };
#define TC_HTB_CLASSID_ROOT …
enum tc_red_command { … };
struct tc_red_qopt_offload_params { … };
struct tc_red_qopt_offload { … };
enum tc_gred_command { … };
struct tc_gred_vq_qopt_offload_params { … };
struct tc_gred_qopt_offload_params { … };
struct tc_gred_qopt_offload_stats { … };
struct tc_gred_qopt_offload { … };
enum tc_prio_command { … };
struct tc_prio_qopt_offload_params { … };
struct tc_prio_qopt_offload_graft_params { … };
struct tc_prio_qopt_offload { … };
enum tc_root_command { … };
struct tc_root_qopt_offload { … };
enum tc_ets_command { … };
struct tc_ets_qopt_offload_replace_params { … };
struct tc_ets_qopt_offload_graft_params { … };
struct tc_ets_qopt_offload { … };
enum tc_tbf_command { … };
struct tc_tbf_qopt_offload_replace_params { … };
struct tc_tbf_qopt_offload { … };
enum tc_fifo_command { … };
struct tc_fifo_qopt_offload { … };
#ifdef CONFIG_NET_CLS_ACT
DECLARE_STATIC_KEY_FALSE(tc_skb_ext_tc);
void tc_skb_ext_tc_enable(void);
void tc_skb_ext_tc_disable(void);
#define tc_skb_ext_tc_enabled() …
#else
static inline void tc_skb_ext_tc_enable(void) { }
static inline void tc_skb_ext_tc_disable(void) { }
#define tc_skb_ext_tc_enabled …
#endif
#endif