Message ID | 1466555002-1316296-4-git-send-email-kafai@fb.com |
---|---|
State | Superseded, archived |
Delegated to: | David Miller |
Headers | show |
On Tue, Jun 21, 2016 at 05:23:21PM -0700, Martin KaFai Lau wrote: > Adds a bpf helper, bpf_skb_in_cgroup, to decide if a skb->sk > belongs to a descendant of a cgroup2. It is similar to the > feature added in netfilter: > commit c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match") > > The user is expected to populate a BPF_MAP_TYPE_CGROUP_ARRAY > which will be used by the bpf_skb_in_cgroup. > > Modifications to the bpf verifier is to ensure BPF_MAP_TYPE_CGROUP_ARRAY > and bpf_skb_in_cgroup() are always used together. > > Signed-off-by: Martin KaFai Lau <kafai@fb.com> > Cc: Alexei Starovoitov <ast@fb.com> > Cc: Daniel Borkmann <daniel@iogearbox.net> > Cc: Tejun Heo <tj@kernel.org> > --- > include/uapi/linux/bpf.h | 1 + > kernel/bpf/verifier.c | 8 ++++++++ > net/core/filter.c | 36 ++++++++++++++++++++++++++++++++++++ > 3 files changed, 45 insertions(+) > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > index ef4e386..a91714bd 100644 > --- a/include/uapi/linux/bpf.h > +++ b/include/uapi/linux/bpf.h > @@ -314,6 +314,7 @@ enum bpf_func_id { > */ > BPF_FUNC_skb_get_tunnel_opt, > BPF_FUNC_skb_set_tunnel_opt, > + BPF_FUNC_skb_in_cgroup, ... > +static u64 bpf_skb_in_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) > +{ ... > + if (unlikely(!cgrp)) > + return -ENOENT; > + > + return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); if you'd need to respin the patch for other reasons please add kdoc to bpf.h for this new helper similar to other helpers. To say that 0 or 1 return values is indication of cg2 descendant relation and < 0 in case of error. Acked-by: Alexei Starovoitov <ast@kernel.org>
Hi, [auto build test ERROR on next-20160621] url: https://github.com/0day-ci/linux/commits/Martin-KaFai-Lau/cgroup-bpf-cgroup2-membership-test-on-skb/20160622-082800 config: i386-randconfig-s1-201625 (attached as .config) compiler: gcc-6 (Debian 6.1.1-1) 6.1.1 20160430 reproduce: # save the attached .config to linux build tree make ARCH=i386 All error/warnings (new ones prefixed by >>): net/core/filter.c: In function 'bpf_skb_in_cgroup': >> net/core/filter.c:2049:30: error: implicit declaration of function 'sock_cgroup_ptr' [-Werror=implicit-function-declaration] return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); ^~~~~~~~~~~~~~~ >> net/core/filter.c:2049:30: warning: passing argument 1 of 'cgroup_is_descendant' makes pointer from integer without a cast [-Wint-conversion] In file included from include/net/netprio_cgroup.h:17:0, from include/linux/netdevice.h:48, from net/core/filter.c:31: include/linux/cgroup.h:492:20: note: expected 'struct cgroup *' but argument is of type 'int' static inline bool cgroup_is_descendant(struct cgroup *cgrp, ^~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors vim +/sock_cgroup_ptr +2049 net/core/filter.c 2043 return -E2BIG; 2044 2045 cgrp = READ_ONCE(array->ptrs[i]); 2046 if (unlikely(!cgrp)) 2047 return -ENOENT; 2048 > 2049 return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); 2050 } 2051 2052 static const struct bpf_func_proto bpf_skb_in_cgroup_proto = { --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
Hi, [auto build test ERROR on next-20160621] url: https://github.com/0day-ci/linux/commits/Martin-KaFai-Lau/cgroup-bpf-cgroup2-membership-test-on-skb/20160622-082800 config: sh-titan_defconfig (attached as .config) compiler: sh4-linux-gnu-gcc (Debian 5.3.1-8) 5.3.1 20160205 reproduce: wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # save the attached .config to linux build tree make.cross ARCH=sh All errors (new ones prefixed by >>): net/core/filter.c: In function 'bpf_skb_in_cgroup': >> net/core/filter.c:2049:9: error: implicit declaration of function 'cgroup_is_descendant' [-Werror=implicit-function-declaration] return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); ^ net/core/filter.c:2049:30: error: implicit declaration of function 'sock_cgroup_ptr' [-Werror=implicit-function-declaration] return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); ^ cc1: some warnings being treated as errors vim +/cgroup_is_descendant +2049 net/core/filter.c 2043 return -E2BIG; 2044 2045 cgrp = READ_ONCE(array->ptrs[i]); 2046 if (unlikely(!cgrp)) 2047 return -ENOENT; 2048 > 2049 return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); 2050 } 2051 2052 static const struct bpf_func_proto bpf_skb_in_cgroup_proto = { --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
On Tue, Jun 21, 2016 at 06:15:13PM -0700, Alexei Starovoitov wrote: > On Tue, Jun 21, 2016 at 05:23:21PM -0700, Martin KaFai Lau wrote: > > Adds a bpf helper, bpf_skb_in_cgroup, to decide if a skb->sk > > belongs to a descendant of a cgroup2. It is similar to the > > feature added in netfilter: > > commit c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match") > > > > The user is expected to populate a BPF_MAP_TYPE_CGROUP_ARRAY > > which will be used by the bpf_skb_in_cgroup. > > > > Modifications to the bpf verifier is to ensure BPF_MAP_TYPE_CGROUP_ARRAY > > and bpf_skb_in_cgroup() are always used together. > > > > Signed-off-by: Martin KaFai Lau <kafai@fb.com> > > Cc: Alexei Starovoitov <ast@fb.com> > > Cc: Daniel Borkmann <daniel@iogearbox.net> > > Cc: Tejun Heo <tj@kernel.org> > > --- > > include/uapi/linux/bpf.h | 1 + > > kernel/bpf/verifier.c | 8 ++++++++ > > net/core/filter.c | 36 ++++++++++++++++++++++++++++++++++++ > > 3 files changed, 45 insertions(+) > > > > diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h > > index ef4e386..a91714bd 100644 > > --- a/include/uapi/linux/bpf.h > > +++ b/include/uapi/linux/bpf.h > > @@ -314,6 +314,7 @@ enum bpf_func_id { > > */ > > BPF_FUNC_skb_get_tunnel_opt, > > BPF_FUNC_skb_set_tunnel_opt, > > + BPF_FUNC_skb_in_cgroup, > ... > > +static u64 bpf_skb_in_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) > > +{ > ... > > + if (unlikely(!cgrp)) > > + return -ENOENT; > > + > > + return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); > > if you'd need to respin the patch for other reasons please add kdoc > to bpf.h for this new helper similar to other helpers. > To say that 0 or 1 return values is indication of cg2 descendant relation > and < 0 in case of error. Will do. I will also address the '#ifndef CONFIG_CGROUPS' case in v2, as reported by the kbuild test.
diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h index ef4e386..a91714bd 100644 --- a/include/uapi/linux/bpf.h +++ b/include/uapi/linux/bpf.h @@ -314,6 +314,7 @@ enum bpf_func_id { */ BPF_FUNC_skb_get_tunnel_opt, BPF_FUNC_skb_set_tunnel_opt, + BPF_FUNC_skb_in_cgroup, __BPF_FUNC_MAX_ID, }; diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c index 668e079..68753e0 100644 --- a/kernel/bpf/verifier.c +++ b/kernel/bpf/verifier.c @@ -1062,6 +1062,10 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id) if (func_id != BPF_FUNC_get_stackid) goto error; break; + case BPF_MAP_TYPE_CGROUP_ARRAY: + if (func_id != BPF_FUNC_skb_in_cgroup) + goto error; + break; default: break; } @@ -1081,6 +1085,10 @@ static int check_map_func_compatibility(struct bpf_map *map, int func_id) if (map->map_type != BPF_MAP_TYPE_STACK_TRACE) goto error; break; + case BPF_FUNC_skb_in_cgroup: + if (map->map_type != BPF_MAP_TYPE_CGROUP_ARRAY) + goto error; + break; default: break; } diff --git a/net/core/filter.c b/net/core/filter.c index df6860c..410da89 100644 --- a/net/core/filter.c +++ b/net/core/filter.c @@ -2024,6 +2024,40 @@ bpf_get_skb_set_tunnel_proto(enum bpf_func_id which) } } +static u64 bpf_skb_in_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) +{ + struct sk_buff *skb = (struct sk_buff *)(long)r1; + struct bpf_map *map = (struct bpf_map *)(long)r2; + struct bpf_array *array = container_of(map, struct bpf_array, map); + u32 i = (u32)r3; + struct cgroup *cgrp; + struct sock *sk; + + WARN_ON_ONCE(!rcu_read_lock_held()); + + sk = skb->sk; + if (!sk || !sk_fullsock(sk)) + return -ENOENT; + + if (unlikely(i >= array->map.max_entries)) + return -E2BIG; + + cgrp = READ_ONCE(array->ptrs[i]); + if (unlikely(!cgrp)) + return -ENOENT; + + return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp); +} + +static const struct bpf_func_proto bpf_skb_in_cgroup_proto = { + .func = bpf_skb_in_cgroup, + .gpl_only = false, + .ret_type = RET_INTEGER, + .arg1_type = ARG_PTR_TO_CTX, + .arg2_type = ARG_CONST_MAP_PTR, + .arg3_type = ARG_ANYTHING, +}; + static const struct bpf_func_proto * sk_filter_func_proto(enum bpf_func_id func_id) { @@ -2086,6 +2120,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id) return &bpf_get_route_realm_proto; case BPF_FUNC_perf_event_output: return bpf_get_event_output_proto(); + case BPF_FUNC_skb_in_cgroup: + return &bpf_skb_in_cgroup_proto; default: return sk_filter_func_proto(func_id); }
Adds a bpf helper, bpf_skb_in_cgroup, to decide if a skb->sk belongs to a descendant of a cgroup2. It is similar to the feature added in netfilter: commit c38c4597e4bf ("netfilter: implement xt_cgroup cgroup2 path match") The user is expected to populate a BPF_MAP_TYPE_CGROUP_ARRAY which will be used by the bpf_skb_in_cgroup. Modifications to the bpf verifier is to ensure BPF_MAP_TYPE_CGROUP_ARRAY and bpf_skb_in_cgroup() are always used together. Signed-off-by: Martin KaFai Lau <kafai@fb.com> Cc: Alexei Starovoitov <ast@fb.com> Cc: Daniel Borkmann <daniel@iogearbox.net> Cc: Tejun Heo <tj@kernel.org> --- include/uapi/linux/bpf.h | 1 + kernel/bpf/verifier.c | 8 ++++++++ net/core/filter.c | 36 ++++++++++++++++++++++++++++++++++++ 3 files changed, 45 insertions(+)