summaryrefslogtreecommitdiff
path: root/include/net/cls_cgroup.h
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2015-07-15 15:21:41 +0300
committerDavid S. Miller <davem@davemloft.net>2015-07-20 22:41:30 +0300
commitb87a173e25d6bf5c26f13d329cdddf57dbd4061a (patch)
treeed2f43c4b6058bf7ca91676afc320757fe277a15 /include/net/cls_cgroup.h
parentd9382bda4ef97d73c77ecaed7a8d5df20da8b8dd (diff)
downloadlinux-b87a173e25d6bf5c26f13d329cdddf57dbd4061a.tar.xz
cls_cgroup: factor out classid retrieval
Split out retrieving the cgroups net_cls classid retrieval into its own function, so that it can be reused later on from other parts of the traffic control subsystem. If there's no skb->sk, then the small helper returns 0 as well, which in cls_cgroup terms means 'could not classify'. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Cc: Thomas Graf <tgraf@suug.ch> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/net/cls_cgroup.h')
-rw-r--r--include/net/cls_cgroup.h29
1 files changed, 29 insertions, 0 deletions
diff --git a/include/net/cls_cgroup.h b/include/net/cls_cgroup.h
index c15d39456e14..ccd6d8bffa4d 100644
--- a/include/net/cls_cgroup.h
+++ b/include/net/cls_cgroup.h
@@ -49,9 +49,38 @@ static inline void sock_update_classid(struct sock *sk)
if (classid != sk->sk_classid)
sk->sk_classid = classid;
}
+
+static inline u32 task_get_classid(const struct sk_buff *skb)
+{
+ u32 classid = task_cls_state(current)->classid;
+
+ /* Due to the nature of the classifier it is required to ignore all
+ * packets originating from softirq context as accessing `current'
+ * would lead to false results.
+ *
+ * This test assumes that all callers of dev_queue_xmit() explicitly
+ * disable bh. Knowing this, it is possible to detect softirq based
+ * calls by looking at the number of nested bh disable calls because
+ * softirqs always disables bh.
+ */
+ if (in_serving_softirq()) {
+ /* If there is an sk_classid we'll use that. */
+ if (!skb->sk)
+ return 0;
+
+ classid = skb->sk->sk_classid;
+ }
+
+ return classid;
+}
#else /* !CONFIG_CGROUP_NET_CLASSID */
static inline void sock_update_classid(struct sock *sk)
{
}
+
+static inline u32 task_get_classid(const struct sk_buff *skb)
+{
+ return 0;
+}
#endif /* CONFIG_CGROUP_NET_CLASSID */
#endif /* _NET_CLS_CGROUP_H */