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