aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorMartin KaFai Lau <kafai@fb.com>2016-06-30 13:28:44 -0400
committerDavid S. Miller <davem@davemloft.net>2016-07-01 16:32:13 -0400
commit4a482f34afcc162d8456f449b137ec2a95be60d8 (patch)
tree0eb3ace759a7df82f868dc4d999fb65f120cabb2 /net/core
parent4ed8ec521ed57c4e207ad464ca0388776de74d4b (diff)
cgroup: bpf: Add bpf_skb_in_cgroup_proto
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> Acked-by: Alexei Starovoitov <ast@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/filter.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/net/core/filter.c b/net/core/filter.c
index 76fee35da244..54071cf70fb5 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -2239,6 +2239,40 @@ bpf_get_skb_set_tunnel_proto(enum bpf_func_id which)
2239 } 2239 }
2240} 2240}
2241 2241
2242#ifdef CONFIG_SOCK_CGROUP_DATA
2243static u64 bpf_skb_in_cgroup(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
2244{
2245 struct sk_buff *skb = (struct sk_buff *)(long)r1;
2246 struct bpf_map *map = (struct bpf_map *)(long)r2;
2247 struct bpf_array *array = container_of(map, struct bpf_array, map);
2248 struct cgroup *cgrp;
2249 struct sock *sk;
2250 u32 i = (u32)r3;
2251
2252 sk = skb->sk;
2253 if (!sk || !sk_fullsock(sk))
2254 return -ENOENT;
2255
2256 if (unlikely(i >= array->map.max_entries))
2257 return -E2BIG;
2258
2259 cgrp = READ_ONCE(array->ptrs[i]);
2260 if (unlikely(!cgrp))
2261 return -EAGAIN;
2262
2263 return cgroup_is_descendant(sock_cgroup_ptr(&sk->sk_cgrp_data), cgrp);
2264}
2265
2266static const struct bpf_func_proto bpf_skb_in_cgroup_proto = {
2267 .func = bpf_skb_in_cgroup,
2268 .gpl_only = false,
2269 .ret_type = RET_INTEGER,
2270 .arg1_type = ARG_PTR_TO_CTX,
2271 .arg2_type = ARG_CONST_MAP_PTR,
2272 .arg3_type = ARG_ANYTHING,
2273};
2274#endif
2275
2242static const struct bpf_func_proto * 2276static const struct bpf_func_proto *
2243sk_filter_func_proto(enum bpf_func_id func_id) 2277sk_filter_func_proto(enum bpf_func_id func_id)
2244{ 2278{
@@ -2307,6 +2341,10 @@ tc_cls_act_func_proto(enum bpf_func_id func_id)
2307 return bpf_get_event_output_proto(); 2341 return bpf_get_event_output_proto();
2308 case BPF_FUNC_get_smp_processor_id: 2342 case BPF_FUNC_get_smp_processor_id:
2309 return &bpf_get_smp_processor_id_proto; 2343 return &bpf_get_smp_processor_id_proto;
2344#ifdef CONFIG_SOCK_CGROUP_DATA
2345 case BPF_FUNC_skb_in_cgroup:
2346 return &bpf_skb_in_cgroup_proto;
2347#endif
2310 default: 2348 default:
2311 return sk_filter_func_proto(func_id); 2349 return sk_filter_func_proto(func_id);
2312 } 2350 }