#include <linux/module.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/kmod.h>
#include <linux/list.h>
#include <linux/hrtimer.h>
#include <linux/slab.h>
#include <linux/hashtable.h>
#include <net/net_namespace.h>
#include <net/sock.h>
#include <net/netlink.h>
#include <net/pkt_sched.h>
#include <net/pkt_cls.h>
#include <net/tc_wrapper.h>
#include <trace/events/qdisc.h>
static DEFINE_RWLOCK(qdisc_mod_lock);
static struct Qdisc_ops *qdisc_base;
int register_qdisc(struct Qdisc_ops *qops)
{ … }
EXPORT_SYMBOL(…);
void unregister_qdisc(struct Qdisc_ops *qops)
{ … }
EXPORT_SYMBOL(…);
void qdisc_get_default(char *name, size_t len)
{ … }
static struct Qdisc_ops *qdisc_lookup_default(const char *name)
{ … }
int qdisc_set_default(const char *name)
{ … }
#ifdef CONFIG_NET_SCH_DEFAULT
static int __init sch_default_qdisc(void)
{ … }
late_initcall(sch_default_qdisc);
#endif
static struct Qdisc *qdisc_match_from_root(struct Qdisc *root, u32 handle)
{ … }
void qdisc_hash_add(struct Qdisc *q, bool invisible)
{ … }
EXPORT_SYMBOL(…);
void qdisc_hash_del(struct Qdisc *q)
{ … }
EXPORT_SYMBOL(…);
struct Qdisc *qdisc_lookup(struct net_device *dev, u32 handle)
{ … }
struct Qdisc *qdisc_lookup_rcu(struct net_device *dev, u32 handle)
{ … }
static struct Qdisc *qdisc_leaf(struct Qdisc *p, u32 classid)
{ … }
static struct Qdisc_ops *qdisc_lookup_ops(struct nlattr *kind)
{ … }
static __u8 __detect_linklayer(struct tc_ratespec *r, __u32 *rtab)
{ … }
static struct qdisc_rate_table *qdisc_rtab_list;
struct qdisc_rate_table *qdisc_get_rtab(struct tc_ratespec *r,
struct nlattr *tab,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL(…);
void qdisc_put_rtab(struct qdisc_rate_table *tab)
{ … }
EXPORT_SYMBOL(…);
static LIST_HEAD(qdisc_stab_list);
static const struct nla_policy stab_policy[TCA_STAB_MAX + 1] = …;
static struct qdisc_size_table *qdisc_get_stab(struct nlattr *opt,
struct netlink_ext_ack *extack)
{ … }
void qdisc_put_stab(struct qdisc_size_table *tab)
{ … }
EXPORT_SYMBOL(…);
static int qdisc_dump_stab(struct sk_buff *skb, struct qdisc_size_table *stab)
{ … }
void __qdisc_calculate_pkt_len(struct sk_buff *skb,
const struct qdisc_size_table *stab)
{ … }
EXPORT_SYMBOL(…);
void qdisc_warn_nonwc(const char *txt, struct Qdisc *qdisc)
{ … }
EXPORT_SYMBOL(…);
static enum hrtimer_restart qdisc_watchdog(struct hrtimer *timer)
{ … }
void qdisc_watchdog_init_clockid(struct qdisc_watchdog *wd, struct Qdisc *qdisc,
clockid_t clockid)
{ … }
EXPORT_SYMBOL(…);
void qdisc_watchdog_init(struct qdisc_watchdog *wd, struct Qdisc *qdisc)
{ … }
EXPORT_SYMBOL(…);
void qdisc_watchdog_schedule_range_ns(struct qdisc_watchdog *wd, u64 expires,
u64 delta_ns)
{ … }
EXPORT_SYMBOL(…);
void qdisc_watchdog_cancel(struct qdisc_watchdog *wd)
{ … }
EXPORT_SYMBOL(…);
static struct hlist_head *qdisc_class_hash_alloc(unsigned int n)
{ … }
void qdisc_class_hash_grow(struct Qdisc *sch, struct Qdisc_class_hash *clhash)
{ … }
EXPORT_SYMBOL(…);
int qdisc_class_hash_init(struct Qdisc_class_hash *clhash)
{ … }
EXPORT_SYMBOL(…);
void qdisc_class_hash_destroy(struct Qdisc_class_hash *clhash)
{ … }
EXPORT_SYMBOL(…);
void qdisc_class_hash_insert(struct Qdisc_class_hash *clhash,
struct Qdisc_class_common *cl)
{ … }
EXPORT_SYMBOL(…);
void qdisc_class_hash_remove(struct Qdisc_class_hash *clhash,
struct Qdisc_class_common *cl)
{ … }
EXPORT_SYMBOL(…);
static u32 qdisc_alloc_handle(struct net_device *dev)
{ … }
void qdisc_tree_reduce_backlog(struct Qdisc *sch, int n, int len)
{ … }
EXPORT_SYMBOL(…);
int qdisc_offload_dump_helper(struct Qdisc *sch, enum tc_setup_type type,
void *type_data)
{ … }
EXPORT_SYMBOL(…);
void qdisc_offload_graft_helper(struct net_device *dev, struct Qdisc *sch,
struct Qdisc *new, struct Qdisc *old,
enum tc_setup_type type, void *type_data,
struct netlink_ext_ack *extack)
{ … }
EXPORT_SYMBOL(…);
void qdisc_offload_query_caps(struct net_device *dev,
enum tc_setup_type type,
void *caps, size_t caps_len)
{ … }
EXPORT_SYMBOL(…);
static void qdisc_offload_graft_root(struct net_device *dev,
struct Qdisc *new, struct Qdisc *old,
struct netlink_ext_ack *extack)
{ … }
static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
u32 portid, u32 seq, u16 flags, int event,
struct netlink_ext_ack *extack)
{ … }
static bool tc_qdisc_dump_ignore(struct Qdisc *q, bool dump_invisible)
{ … }
static int qdisc_get_notify(struct net *net, struct sk_buff *oskb,
struct nlmsghdr *n, u32 clid, struct Qdisc *q,
struct netlink_ext_ack *extack)
{ … }
static int qdisc_notify(struct net *net, struct sk_buff *oskb,
struct nlmsghdr *n, u32 clid,
struct Qdisc *old, struct Qdisc *new,
struct netlink_ext_ack *extack)
{ … }
static void notify_and_destroy(struct net *net, struct sk_buff *skb,
struct nlmsghdr *n, u32 clid,
struct Qdisc *old, struct Qdisc *new,
struct netlink_ext_ack *extack)
{ … }
static void qdisc_clear_nolock(struct Qdisc *sch)
{ … }
static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
struct sk_buff *skb, struct nlmsghdr *n, u32 classid,
struct Qdisc *new, struct Qdisc *old,
struct netlink_ext_ack *extack)
{ … }
static int qdisc_block_indexes_set(struct Qdisc *sch, struct nlattr **tca,
struct netlink_ext_ack *extack)
{ … }
static struct Qdisc *qdisc_create(struct net_device *dev,
struct netdev_queue *dev_queue,
u32 parent, u32 handle,
struct nlattr **tca, int *errp,
struct netlink_ext_ack *extack)
{ … }
static int qdisc_change(struct Qdisc *sch, struct nlattr **tca,
struct netlink_ext_ack *extack)
{ … }
struct check_loop_arg { … };
static int check_loop_fn(struct Qdisc *q, unsigned long cl,
struct qdisc_walker *w);
static int check_loop(struct Qdisc *q, struct Qdisc *p, int depth)
{ … }
static int
check_loop_fn(struct Qdisc *q, unsigned long cl, struct qdisc_walker *w)
{ … }
const struct nla_policy rtm_tca_policy[TCA_MAX + 1] = …;
static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{ … }
static bool req_create_or_replace(struct nlmsghdr *n)
{ … }
static bool req_create_exclusive(struct nlmsghdr *n)
{ … }
static bool req_change(struct nlmsghdr *n)
{ … }
static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{ … }
static int tc_dump_qdisc_root(struct Qdisc *root, struct sk_buff *skb,
struct netlink_callback *cb,
int *q_idx_p, int s_q_idx, bool recur,
bool dump_invisible)
{ … }
static int tc_dump_qdisc(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
unsigned long cl, u32 portid, u32 seq, u16 flags,
int event, struct netlink_ext_ack *extack)
{ … }
static int tclass_notify(struct net *net, struct sk_buff *oskb,
struct nlmsghdr *n, struct Qdisc *q,
unsigned long cl, int event, struct netlink_ext_ack *extack)
{ … }
static int tclass_get_notify(struct net *net, struct sk_buff *oskb,
struct nlmsghdr *n, struct Qdisc *q,
unsigned long cl, struct netlink_ext_ack *extack)
{ … }
static int tclass_del_notify(struct net *net,
const struct Qdisc_class_ops *cops,
struct sk_buff *oskb, struct nlmsghdr *n,
struct Qdisc *q, unsigned long cl,
struct netlink_ext_ack *extack)
{ … }
#ifdef CONFIG_NET_CLS
struct tcf_bind_args { … };
static int tcf_node_bind(struct tcf_proto *tp, void *n, struct tcf_walker *arg)
{ … }
struct tc_bind_class_args { … };
static int tc_bind_class_walker(struct Qdisc *q, unsigned long cl,
struct qdisc_walker *w)
{ … }
static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
unsigned long new_cl)
{ … }
#else
static void tc_bind_tclass(struct Qdisc *q, u32 portid, u32 clid,
unsigned long new_cl)
{
}
#endif
static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n,
struct netlink_ext_ack *extack)
{ … }
struct qdisc_dump_args { … };
static int qdisc_class_dump(struct Qdisc *q, unsigned long cl,
struct qdisc_walker *arg)
{ … }
static int tc_dump_tclass_qdisc(struct Qdisc *q, struct sk_buff *skb,
struct tcmsg *tcm, struct netlink_callback *cb,
int *t_p, int s_t)
{ … }
static int tc_dump_tclass_root(struct Qdisc *root, struct sk_buff *skb,
struct tcmsg *tcm, struct netlink_callback *cb,
int *t_p, int s_t, bool recur)
{ … }
static int tc_dump_tclass(struct sk_buff *skb, struct netlink_callback *cb)
{ … }
#ifdef CONFIG_PROC_FS
static int psched_show(struct seq_file *seq, void *v)
{ … }
static int __net_init psched_net_init(struct net *net)
{ … }
static void __net_exit psched_net_exit(struct net *net)
{ … }
#else
static int __net_init psched_net_init(struct net *net)
{
return 0;
}
static void __net_exit psched_net_exit(struct net *net)
{
}
#endif
static struct pernet_operations psched_net_ops = …;
#if IS_ENABLED(CONFIG_MITIGATION_RETPOLINE)
DEFINE_STATIC_KEY_FALSE(tc_skip_wrapper);
#endif
static int __init pktsched_init(void)
{ … }
subsys_initcall(pktsched_init);