Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0-or-later */
0002 /*
0003  * cls_cgroup.h         Control Group Classifier
0004  *
0005  * Authors: Thomas Graf <tgraf@suug.ch>
0006  */
0007 
0008 #ifndef _NET_CLS_CGROUP_H
0009 #define _NET_CLS_CGROUP_H
0010 
0011 #include <linux/cgroup.h>
0012 #include <linux/hardirq.h>
0013 #include <linux/rcupdate.h>
0014 #include <net/sock.h>
0015 #include <net/inet_sock.h>
0016 
0017 #ifdef CONFIG_CGROUP_NET_CLASSID
0018 struct cgroup_cls_state {
0019     struct cgroup_subsys_state css;
0020     u32 classid;
0021 };
0022 
0023 struct cgroup_cls_state *task_cls_state(struct task_struct *p);
0024 
0025 static inline u32 task_cls_classid(struct task_struct *p)
0026 {
0027     u32 classid;
0028 
0029     if (in_interrupt())
0030         return 0;
0031 
0032     rcu_read_lock();
0033     classid = container_of(task_css(p, net_cls_cgrp_id),
0034                    struct cgroup_cls_state, css)->classid;
0035     rcu_read_unlock();
0036 
0037     return classid;
0038 }
0039 
0040 static inline void sock_update_classid(struct sock_cgroup_data *skcd)
0041 {
0042     u32 classid;
0043 
0044     classid = task_cls_classid(current);
0045     sock_cgroup_set_classid(skcd, classid);
0046 }
0047 
0048 static inline u32 __task_get_classid(struct task_struct *task)
0049 {
0050     return task_cls_state(task)->classid;
0051 }
0052 
0053 static inline u32 task_get_classid(const struct sk_buff *skb)
0054 {
0055     u32 classid = __task_get_classid(current);
0056 
0057     /* Due to the nature of the classifier it is required to ignore all
0058      * packets originating from softirq context as accessing `current'
0059      * would lead to false results.
0060      *
0061      * This test assumes that all callers of dev_queue_xmit() explicitly
0062      * disable bh. Knowing this, it is possible to detect softirq based
0063      * calls by looking at the number of nested bh disable calls because
0064      * softirqs always disables bh.
0065      */
0066     if (in_serving_softirq()) {
0067         struct sock *sk = skb_to_full_sk(skb);
0068 
0069         /* If there is an sock_cgroup_classid we'll use that. */
0070         if (!sk || !sk_fullsock(sk))
0071             return 0;
0072 
0073         classid = sock_cgroup_classid(&sk->sk_cgrp_data);
0074     }
0075 
0076     return classid;
0077 }
0078 #else /* !CONFIG_CGROUP_NET_CLASSID */
0079 static inline void sock_update_classid(struct sock_cgroup_data *skcd)
0080 {
0081 }
0082 
0083 static inline u32 task_get_classid(const struct sk_buff *skb)
0084 {
0085     return 0;
0086 }
0087 #endif /* CONFIG_CGROUP_NET_CLASSID */
0088 #endif  /* _NET_CLS_CGROUP_H */