1f8451725SHerbert Xu /* 2f8451725SHerbert Xu * cls_cgroup.h Control Group Classifier 3f8451725SHerbert Xu * 4f8451725SHerbert Xu * Authors: Thomas Graf <tgraf@suug.ch> 5f8451725SHerbert Xu * 6f8451725SHerbert Xu * This program is free software; you can redistribute it and/or modify it 7f8451725SHerbert Xu * under the terms of the GNU General Public License as published by the Free 8f8451725SHerbert Xu * Software Foundation; either version 2 of the License, or (at your option) 9f8451725SHerbert Xu * any later version. 10f8451725SHerbert Xu * 11f8451725SHerbert Xu */ 12f8451725SHerbert Xu 13f8451725SHerbert Xu #ifndef _NET_CLS_CGROUP_H 14f8451725SHerbert Xu #define _NET_CLS_CGROUP_H 15f8451725SHerbert Xu 16f8451725SHerbert Xu #include <linux/cgroup.h> 17f8451725SHerbert Xu #include <linux/hardirq.h> 18f8451725SHerbert Xu #include <linux/rcupdate.h> 19fe1217c4SDaniel Borkmann #include <net/sock.h> 20*2309236cSKonstantin Khlebnikov #include <net/inet_sock.h> 21f8451725SHerbert Xu 22fe1217c4SDaniel Borkmann #ifdef CONFIG_CGROUP_NET_CLASSID 23fe1217c4SDaniel Borkmann struct cgroup_cls_state { 24f8451725SHerbert Xu struct cgroup_subsys_state css; 25f8451725SHerbert Xu u32 classid; 26f8451725SHerbert Xu }; 27f8451725SHerbert Xu 28fe1217c4SDaniel Borkmann struct cgroup_cls_state *task_cls_state(struct task_struct *p); 29f3419807SDaniel Wagner 30f8451725SHerbert Xu static inline u32 task_cls_classid(struct task_struct *p) 31f8451725SHerbert Xu { 32920750ceSDaniel Wagner u32 classid; 333fb5a991SLi Zefan 34f8451725SHerbert Xu if (in_interrupt()) 35f8451725SHerbert Xu return 0; 36f8451725SHerbert Xu 373fb5a991SLi Zefan rcu_read_lock(); 38073219e9STejun Heo classid = container_of(task_css(p, net_cls_cgrp_id), 39937eada4SHerbert Xu struct cgroup_cls_state, css)->classid; 403fb5a991SLi Zefan rcu_read_unlock(); 413fb5a991SLi Zefan 423fb5a991SLi Zefan return classid; 43f8451725SHerbert Xu } 44fe1217c4SDaniel Borkmann 452a56a1feSTejun Heo static inline void sock_update_classid(struct sock_cgroup_data *skcd) 46f8451725SHerbert Xu { 47fe1217c4SDaniel Borkmann u32 classid; 48f8451725SHerbert Xu 49fe1217c4SDaniel Borkmann classid = task_cls_classid(current); 502a56a1feSTejun Heo sock_cgroup_set_classid(skcd, classid); 51f8451725SHerbert Xu } 52b87a173eSDaniel Borkmann 53b87a173eSDaniel Borkmann static inline u32 task_get_classid(const struct sk_buff *skb) 54b87a173eSDaniel Borkmann { 55b87a173eSDaniel Borkmann u32 classid = task_cls_state(current)->classid; 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()) { 67*2309236cSKonstantin Khlebnikov struct sock *sk = skb_to_full_sk(skb); 68*2309236cSKonstantin Khlebnikov 692a56a1feSTejun Heo /* If there is an sock_cgroup_classid we'll use that. */ 70*2309236cSKonstantin Khlebnikov if (!sk || !sk_fullsock(sk)) 71b87a173eSDaniel Borkmann return 0; 72b87a173eSDaniel Borkmann 73*2309236cSKonstantin 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 */ 792a56a1feSTejun Heo static inline void sock_update_classid(struct sock_cgroup_data *skcd) 80f3419807SDaniel Wagner { 81f3419807SDaniel Wagner } 82b87a173eSDaniel Borkmann 83b87a173eSDaniel Borkmann static 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