12874c5fdSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-or-later */ 2f8451725SHerbert Xu /* 3f8451725SHerbert Xu * cls_cgroup.h Control Group Classifier 4f8451725SHerbert Xu * 5f8451725SHerbert Xu * Authors: Thomas Graf <tgraf@suug.ch> 6f8451725SHerbert Xu */ 7f8451725SHerbert Xu 8f8451725SHerbert Xu #ifndef _NET_CLS_CGROUP_H 9f8451725SHerbert Xu #define _NET_CLS_CGROUP_H 10f8451725SHerbert Xu 11f8451725SHerbert Xu #include <linux/cgroup.h> 12f8451725SHerbert Xu #include <linux/hardirq.h> 13f8451725SHerbert Xu #include <linux/rcupdate.h> 14fe1217c4SDaniel Borkmann #include <net/sock.h> 152309236cSKonstantin Khlebnikov #include <net/inet_sock.h> 16f8451725SHerbert Xu 17fe1217c4SDaniel Borkmann #ifdef CONFIG_CGROUP_NET_CLASSID 18fe1217c4SDaniel Borkmann struct cgroup_cls_state { 19f8451725SHerbert Xu struct cgroup_subsys_state css; 20f8451725SHerbert Xu u32 classid; 21f8451725SHerbert Xu }; 22f8451725SHerbert Xu 23fe1217c4SDaniel Borkmann struct cgroup_cls_state *task_cls_state(struct task_struct *p); 24f3419807SDaniel Wagner task_cls_classid(struct task_struct * p)25f8451725SHerbert Xustatic inline u32 task_cls_classid(struct task_struct *p) 26f8451725SHerbert Xu { 27920750ceSDaniel Wagner u32 classid; 283fb5a991SLi Zefan 29f8451725SHerbert Xu if (in_interrupt()) 30f8451725SHerbert Xu return 0; 31f8451725SHerbert Xu 323fb5a991SLi Zefan rcu_read_lock(); 33073219e9STejun Heo classid = container_of(task_css(p, net_cls_cgrp_id), 34937eada4SHerbert Xu struct cgroup_cls_state, css)->classid; 353fb5a991SLi Zefan rcu_read_unlock(); 363fb5a991SLi Zefan 373fb5a991SLi Zefan return classid; 38f8451725SHerbert Xu } 39fe1217c4SDaniel Borkmann sock_update_classid(struct sock_cgroup_data * skcd)402a56a1feSTejun Heostatic inline void sock_update_classid(struct sock_cgroup_data *skcd) 41f8451725SHerbert Xu { 42fe1217c4SDaniel Borkmann u32 classid; 43f8451725SHerbert Xu 44fe1217c4SDaniel Borkmann classid = task_cls_classid(current); 452a56a1feSTejun Heo sock_cgroup_set_classid(skcd, classid); 46f8451725SHerbert Xu } 47b87a173eSDaniel Borkmann __task_get_classid(struct task_struct * task)48*5a52ae4eSDaniel Borkmannstatic inline u32 __task_get_classid(struct task_struct *task) 49*5a52ae4eSDaniel Borkmann { 50*5a52ae4eSDaniel Borkmann return task_cls_state(task)->classid; 51*5a52ae4eSDaniel Borkmann } 52*5a52ae4eSDaniel Borkmann task_get_classid(const struct sk_buff * skb)53b87a173eSDaniel Borkmannstatic inline u32 task_get_classid(const struct sk_buff *skb) 54b87a173eSDaniel Borkmann { 55*5a52ae4eSDaniel Borkmann u32 classid = __task_get_classid(current); 56b87a173eSDaniel Borkmann 57b87a173eSDaniel Borkmann /* Due to the nature of the classifier it is required to ignore all 58b87a173eSDaniel Borkmann * packets originating from softirq context as accessing `current' 59b87a173eSDaniel Borkmann * would lead to false results. 60b87a173eSDaniel Borkmann * 61b87a173eSDaniel Borkmann * This test assumes that all callers of dev_queue_xmit() explicitly 62b87a173eSDaniel Borkmann * disable bh. Knowing this, it is possible to detect softirq based 63b87a173eSDaniel Borkmann * calls by looking at the number of nested bh disable calls because 64b87a173eSDaniel Borkmann * softirqs always disables bh. 65b87a173eSDaniel Borkmann */ 66b87a173eSDaniel Borkmann if (in_serving_softirq()) { 672309236cSKonstantin Khlebnikov struct sock *sk = skb_to_full_sk(skb); 682309236cSKonstantin Khlebnikov 692a56a1feSTejun Heo /* If there is an sock_cgroup_classid we'll use that. */ 702309236cSKonstantin Khlebnikov if (!sk || !sk_fullsock(sk)) 71b87a173eSDaniel Borkmann return 0; 72b87a173eSDaniel Borkmann 732309236cSKonstantin Khlebnikov classid = sock_cgroup_classid(&sk->sk_cgrp_data); 74b87a173eSDaniel Borkmann } 75b87a173eSDaniel Borkmann 76b87a173eSDaniel Borkmann return classid; 77b87a173eSDaniel Borkmann } 78fe1217c4SDaniel Borkmann #else /* !CONFIG_CGROUP_NET_CLASSID */ sock_update_classid(struct sock_cgroup_data * skcd)792a56a1feSTejun Heostatic inline void sock_update_classid(struct sock_cgroup_data *skcd) 80f3419807SDaniel Wagner { 81f3419807SDaniel Wagner } 82b87a173eSDaniel Borkmann task_get_classid(const struct sk_buff * skb)83b87a173eSDaniel Borkmannstatic inline u32 task_get_classid(const struct sk_buff *skb) 84b87a173eSDaniel Borkmann { 85b87a173eSDaniel Borkmann return 0; 86b87a173eSDaniel Borkmann } 87fe1217c4SDaniel Borkmann #endif /* CONFIG_CGROUP_NET_CLASSID */ 88f8451725SHerbert Xu #endif /* _NET_CLS_CGROUP_H */ 89