bpf: Allow to retrieve cgroup v1 classid from v2 hooks
authorDaniel Borkmann <daniel@iogearbox.net>
Fri, 27 Mar 2020 15:58:53 +0000 (16:58 +0100)
committerAlexei Starovoitov <ast@kernel.org>
Sat, 28 Mar 2020 02:40:38 +0000 (19:40 -0700)
Today, Kubernetes is still operating on cgroups v1, however, it is
possible to retrieve the task's classid based on 'current' out of
connect(), sendmsg(), recvmsg() and bind-related hooks for orchestrators
which attach to the root cgroup v2 hook in a mixed env like in case
of Cilium, for example, in order to then correlate certain pod traffic
and use it as part of the key for BPF map lookups.

Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://lore.kernel.org/bpf/555e1c69db7376c0947007b4951c260e1074efc3.1585323121.git.daniel@iogearbox.net
include/net/cls_cgroup.h
net/core/filter.c

index 4295de3..7e78e7d 100644 (file)
@@ -45,9 +45,14 @@ static inline void sock_update_classid(struct sock_cgroup_data *skcd)
        sock_cgroup_set_classid(skcd, classid);
 }
 
+static inline u32 __task_get_classid(struct task_struct *task)
+{
+       return task_cls_state(task)->classid;
+}
+
 static inline u32 task_get_classid(const struct sk_buff *skb)
 {
-       u32 classid = task_cls_state(current)->classid;
+       u32 classid = __task_get_classid(current);
 
        /* Due to the nature of the classifier it is required to ignore all
         * packets originating from softirq context as accessing `current'
index e249a49..3083c77 100644 (file)
@@ -2642,6 +2642,19 @@ static const struct bpf_func_proto bpf_msg_pop_data_proto = {
        .arg4_type      = ARG_ANYTHING,
 };
 
+#ifdef CONFIG_CGROUP_NET_CLASSID
+BPF_CALL_0(bpf_get_cgroup_classid_curr)
+{
+       return __task_get_classid(current);
+}
+
+static const struct bpf_func_proto bpf_get_cgroup_classid_curr_proto = {
+       .func           = bpf_get_cgroup_classid_curr,
+       .gpl_only       = false,
+       .ret_type       = RET_INTEGER,
+};
+#endif
+
 BPF_CALL_1(bpf_get_cgroup_classid, const struct sk_buff *, skb)
 {
        return task_get_classid(skb);
@@ -6005,6 +6018,10 @@ sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_get_netns_cookie_sock_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
+#ifdef CONFIG_CGROUP_NET_CLASSID
+       case BPF_FUNC_get_cgroup_classid:
+               return &bpf_get_cgroup_classid_curr_proto;
+#endif
        default:
                return bpf_base_func_proto(func_id);
        }
@@ -6035,6 +6052,10 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
                return &bpf_get_local_storage_proto;
        case BPF_FUNC_perf_event_output:
                return &bpf_event_output_data_proto;
+#ifdef CONFIG_CGROUP_NET_CLASSID
+       case BPF_FUNC_get_cgroup_classid:
+               return &bpf_get_cgroup_classid_curr_proto;
+#endif
 #ifdef CONFIG_INET
        case BPF_FUNC_sk_lookup_tcp:
                return &bpf_sock_addr_sk_lookup_tcp_proto;