--- zzzz-none-000/linux-3.10.107/include/net/cls_cgroup.h 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/include/net/cls_cgroup.h 2021-02-04 17:41:59.000000000 +0000 @@ -16,17 +16,16 @@ #include #include #include +#include -#if IS_ENABLED(CONFIG_NET_CLS_CGROUP) -struct cgroup_cls_state -{ +#ifdef CONFIG_CGROUP_NET_CLASSID +struct cgroup_cls_state { struct cgroup_subsys_state css; u32 classid; }; -extern void sock_update_classid(struct sock *sk); +struct cgroup_cls_state *task_cls_state(struct task_struct *p); -#if IS_BUILTIN(CONFIG_NET_CLS_CGROUP) static inline u32 task_cls_classid(struct task_struct *p) { u32 classid; @@ -35,39 +34,53 @@ return 0; rcu_read_lock(); - classid = container_of(task_subsys_state(p, net_cls_subsys_id), + classid = container_of(task_css(p, net_cls_cgrp_id), struct cgroup_cls_state, css)->classid; rcu_read_unlock(); return classid; } -#elif IS_MODULE(CONFIG_NET_CLS_CGROUP) -static inline u32 task_cls_classid(struct task_struct *p) + +static inline void sock_update_classid(struct sock *sk) { - struct cgroup_subsys_state *css; - u32 classid = 0; + u32 classid; - if (in_interrupt()) - return 0; + classid = task_cls_classid(current); + if (classid != sk->sk_classid) + sk->sk_classid = classid; +} - rcu_read_lock(); - css = task_subsys_state(p, net_cls_subsys_id); - if (css) - classid = container_of(css, - struct cgroup_cls_state, css)->classid; - rcu_read_unlock(); +static inline u32 task_get_classid(const struct sk_buff *skb) +{ + u32 classid = task_cls_state(current)->classid; + + /* Due to the nature of the classifier it is required to ignore all + * packets originating from softirq context as accessing `current' + * would lead to false results. + * + * This test assumes that all callers of dev_queue_xmit() explicitly + * disable bh. Knowing this, it is possible to detect softirq based + * calls by looking at the number of nested bh disable calls because + * softirqs always disables bh. + */ + if (in_serving_softirq()) { + /* If there is an sk_classid we'll use that. */ + if (!skb->sk) + return 0; + + classid = skb->sk->sk_classid; + } return classid; } -#endif -#else /* !CGROUP_NET_CLS_CGROUP */ +#else /* !CONFIG_CGROUP_NET_CLASSID */ static inline void sock_update_classid(struct sock *sk) { } -static inline u32 task_cls_classid(struct task_struct *p) +static inline u32 task_get_classid(const struct sk_buff *skb) { return 0; } -#endif /* CGROUP_NET_CLS_CGROUP */ +#endif /* CONFIG_CGROUP_NET_CLASSID */ #endif /* _NET_CLS_CGROUP_H */