1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 /* 3 * cls_cgroup.h Control Group Classifier 4 * 5 * Authors: Thomas Graf <tgraf@suug.ch> 6 */ 7 8 #ifndef _NET_CLS_CGROUP_H 9 #define _NET_CLS_CGROUP_H 10 11 #include <linux/cgroup.h> 12 #include <linux/hardirq.h> 13 #include <linux/rcupdate.h> 14 #include <net/sock.h> 15 #include <net/inet_sock.h> 16 17 #ifdef CONFIG_CGROUP_NET_CLASSID 18 struct cgroup_cls_state { 19 struct cgroup_subsys_state css; 20 u32 classid; 21 }; 22 23 void _trace_android_vh_task_get_classid(const struct sk_buff *skb, u32 *classid); 24 25 struct cgroup_cls_state *task_cls_state(struct task_struct *p); 26 task_cls_classid(struct task_struct * p)27static inline u32 task_cls_classid(struct task_struct *p) 28 { 29 u32 classid; 30 31 if (in_interrupt()) 32 return 0; 33 34 rcu_read_lock(); 35 classid = container_of(task_css(p, net_cls_cgrp_id), 36 struct cgroup_cls_state, css)->classid; 37 rcu_read_unlock(); 38 39 return classid; 40 } 41 sock_update_classid(struct sock_cgroup_data * skcd)42static inline void sock_update_classid(struct sock_cgroup_data *skcd) 43 { 44 u32 classid; 45 46 classid = task_cls_classid(current); 47 sock_cgroup_set_classid(skcd, classid); 48 } 49 __task_get_classid(struct task_struct * task)50static inline u32 __task_get_classid(struct task_struct *task) 51 { 52 return task_cls_state(task)->classid; 53 } 54 task_get_classid(const struct sk_buff * skb)55static inline u32 task_get_classid(const struct sk_buff *skb) 56 { 57 u32 classid = __task_get_classid(current); 58 59 /* Due to the nature of the classifier it is required to ignore all 60 * packets originating from softirq context as accessing `current' 61 * would lead to false results. 62 * 63 * This test assumes that all callers of dev_queue_xmit() explicitly 64 * disable bh. Knowing this, it is possible to detect softirq based 65 * calls by looking at the number of nested bh disable calls because 66 * softirqs always disables bh. 67 */ 68 if (in_serving_softirq()) { 69 struct sock *sk = skb_to_full_sk(skb); 70 71 /* If there is an sock_cgroup_classid we'll use that. */ 72 if (!sk || !sk_fullsock(sk)) 73 return 0; 74 75 classid = sock_cgroup_classid(&sk->sk_cgrp_data); 76 } 77 78 _trace_android_vh_task_get_classid(skb, &classid); 79 80 return classid; 81 } 82 #else /* !CONFIG_CGROUP_NET_CLASSID */ sock_update_classid(struct sock_cgroup_data * skcd)83static inline void sock_update_classid(struct sock_cgroup_data *skcd) 84 { 85 } 86 task_get_classid(const struct sk_buff * skb)87static inline u32 task_get_classid(const struct sk_buff *skb) 88 { 89 return 0; 90 } 91 #endif /* CONFIG_CGROUP_NET_CLASSID */ 92 #endif /* _NET_CLS_CGROUP_H */ 93