18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-or-later */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * cls_cgroup.h Control Group Classifier 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Authors: Thomas Graf <tgraf@suug.ch> 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#ifndef _NET_CLS_CGROUP_H 98c2ecf20Sopenharmony_ci#define _NET_CLS_CGROUP_H 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#include <linux/cgroup.h> 128c2ecf20Sopenharmony_ci#include <linux/hardirq.h> 138c2ecf20Sopenharmony_ci#include <linux/rcupdate.h> 148c2ecf20Sopenharmony_ci#include <net/sock.h> 158c2ecf20Sopenharmony_ci#include <net/inet_sock.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#ifdef CONFIG_CGROUP_NET_CLASSID 188c2ecf20Sopenharmony_cistruct cgroup_cls_state { 198c2ecf20Sopenharmony_ci struct cgroup_subsys_state css; 208c2ecf20Sopenharmony_ci u32 classid; 218c2ecf20Sopenharmony_ci}; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct cgroup_cls_state *task_cls_state(struct task_struct *p); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_cistatic inline u32 task_cls_classid(struct task_struct *p) 268c2ecf20Sopenharmony_ci{ 278c2ecf20Sopenharmony_ci u32 classid; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci if (in_interrupt()) 308c2ecf20Sopenharmony_ci return 0; 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci rcu_read_lock(); 338c2ecf20Sopenharmony_ci classid = container_of(task_css(p, net_cls_cgrp_id), 348c2ecf20Sopenharmony_ci struct cgroup_cls_state, css)->classid; 358c2ecf20Sopenharmony_ci rcu_read_unlock(); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci return classid; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_cistatic inline void sock_update_classid(struct sock_cgroup_data *skcd) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci u32 classid; 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci classid = task_cls_classid(current); 458c2ecf20Sopenharmony_ci sock_cgroup_set_classid(skcd, classid); 468c2ecf20Sopenharmony_ci} 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_cistatic inline u32 __task_get_classid(struct task_struct *task) 498c2ecf20Sopenharmony_ci{ 508c2ecf20Sopenharmony_ci return task_cls_state(task)->classid; 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic inline u32 task_get_classid(const struct sk_buff *skb) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci u32 classid = __task_get_classid(current); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci /* Due to the nature of the classifier it is required to ignore all 588c2ecf20Sopenharmony_ci * packets originating from softirq context as accessing `current' 598c2ecf20Sopenharmony_ci * would lead to false results. 608c2ecf20Sopenharmony_ci * 618c2ecf20Sopenharmony_ci * This test assumes that all callers of dev_queue_xmit() explicitly 628c2ecf20Sopenharmony_ci * disable bh. Knowing this, it is possible to detect softirq based 638c2ecf20Sopenharmony_ci * calls by looking at the number of nested bh disable calls because 648c2ecf20Sopenharmony_ci * softirqs always disables bh. 658c2ecf20Sopenharmony_ci */ 668c2ecf20Sopenharmony_ci if (in_serving_softirq()) { 678c2ecf20Sopenharmony_ci struct sock *sk = skb_to_full_sk(skb); 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci /* If there is an sock_cgroup_classid we'll use that. */ 708c2ecf20Sopenharmony_ci if (!sk || !sk_fullsock(sk)) 718c2ecf20Sopenharmony_ci return 0; 728c2ecf20Sopenharmony_ci 738c2ecf20Sopenharmony_ci classid = sock_cgroup_classid(&sk->sk_cgrp_data); 748c2ecf20Sopenharmony_ci } 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci return classid; 778c2ecf20Sopenharmony_ci} 788c2ecf20Sopenharmony_ci#else /* !CONFIG_CGROUP_NET_CLASSID */ 798c2ecf20Sopenharmony_cistatic inline void sock_update_classid(struct sock_cgroup_data *skcd) 808c2ecf20Sopenharmony_ci{ 818c2ecf20Sopenharmony_ci} 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_cistatic inline u32 task_get_classid(const struct sk_buff *skb) 848c2ecf20Sopenharmony_ci{ 858c2ecf20Sopenharmony_ci return 0; 868c2ecf20Sopenharmony_ci} 878c2ecf20Sopenharmony_ci#endif /* CONFIG_CGROUP_NET_CLASSID */ 888c2ecf20Sopenharmony_ci#endif /* _NET_CLS_CGROUP_H */ 89