History

bpf: add skc_lookup_tcp helper

Allow looking up a sock_common. This gives eBPF programs access to timewait and request sockets.

Lorenz Bauer committed 7 years ago

Commit edbf8c01 parent 85a51f83 files · +143 −24Browse files

Unified · Split

3 files
  1. include/uapi/linux/bpf.h +19 −1
  2. kernel/bpf/verifier.c +2 −1
  3. net/core/filter.c +122 −22
include/uapi/linux/bpf.h+19−1
@@ -2431,6 +2431,23 @@ union bpf_attr { · 2430 unmodified lines
24312431 * Return
24322432 * A **struct bpf_sock** pointer on success, or **NULL** in
24332433 * case of failure.
2434+ *
2435+ * struct bpf_sock *bpf_skc_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
2436+ * Description
2437+ * Look for TCP socket matching *tuple*, optionally in a child
2438+ * network namespace *netns*. The return value must be checked,
2439+ * and if non-**NULL**, released via **bpf_sk_release**\ ().
2440+ *
2441+ * This function is identical to bpf_sk_lookup_tcp, except that it
2442+ * also returns timewait or request sockets. Use bpf_sk_fullsock
2443+ * or bpf_tcp_socket to access the full structure.
2444+ *
2445+ * This helper is available only if the kernel was compiled with
2446+ * **CONFIG_NET** configuration option.
2447+ * Return
2448+ * Pointer to **struct bpf_sock**, or **NULL** in case of failure.
2449+ * For sockets with reuseport option, the **struct bpf_sock**
2450+ * result is from **reuse->socks**\ [] using the hash of the tuple.
24342451 */
24352452 #define __BPF_FUNC_MAPPER(FN) \
24362453 FN(unspec), \
@@ -2531,7 +2548,8 @@ union bpf_attr { · 94 unmodified lines
25312548 FN(sk_fullsock), \
25322549 FN(tcp_sock), \
25332550 FN(skb_ecn_set_ce), \
2534− FN(get_listener_sock),
2551+ FN(get_listener_sock), \
2552+ FN(skc_lookup_tcp),
25352553
25362554 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
25372555 * function eBPF program intends to call
kernel/bpf/verifier.c+2−1
@@ -369,7 +369,8 @@ static bool is_release_function(enum bpf_func_id func_id) · 368 unmodified lines
369369 static bool is_acquire_function(enum bpf_func_id func_id)
370370 {
371371 return func_id == BPF_FUNC_sk_lookup_tcp ||
372− func_id == BPF_FUNC_sk_lookup_udp;
372+ func_id == BPF_FUNC_sk_lookup_udp ||
373+ func_id == BPF_FUNC_skc_lookup_tcp;
373374 }
374375
375376 static bool is_ptr_cast_function(enum bpf_func_id func_id)
net/core/filter.c+122−22
@@ -5156,15 +5156,15 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple, · 5155 unmodified lines
51565156 return sk;
51575157 }
51585158
5159−/* bpf_sk_lookup performs the core lookup for different types of sockets,
5159+/* bpf_skc_lookup performs the core lookup for different types of sockets,
51605160 * taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
51615161 * Returns the socket as an 'unsigned long' to simplify the casting in the
51625162 * callers to satisfy BPF_CALL declarations.
51635163 */
5164−static unsigned long
5165−__bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5166− struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
5167− u64 flags)
5164+static struct sock *
5165+__bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5166+ struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
5167+ u64 flags)
51685168 {
51695169 struct sock *sk = NULL;
51705170 u8 family = AF_UNSPEC;
@@ -5192,15 +5192,27 @@ __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, · 21 unmodified lines
51925192 put_net(net);
51935193 }
51945194
5195+out:
5196+ return sk;
5197+}
5198+
5199+static struct sock *
5200+__bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5201+ struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
5202+ u64 flags)
5203+{
5204+ struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net,
5205+ ifindex, proto, netns_id, flags);
5206+
51955207 if (sk)
51965208 sk = sk_to_full_sk(sk);
5197−out:
5198− return (unsigned long) sk;
5209+
5210+ return sk;
51995211 }
52005212
5201−static unsigned long
5202−bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5203− u8 proto, u64 netns_id, u64 flags)
5213+static struct sock *
5214+bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5215+ u8 proto, u64 netns_id, u64 flags)
52045216 {
52055217 struct net *caller_net;
52065218 int ifindex;
@@ -5213,14 +5225,47 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, · 6 unmodified lines
52135225 ifindex = 0;
52145226 }
52155227
5216− return __bpf_sk_lookup(skb, tuple, len, caller_net, ifindex,
5217− proto, netns_id, flags);
5228+ return __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto,
5229+ netns_id, flags);
52185230 }
52195231
5232+static struct sock *
5233+bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5234+ u8 proto, u64 netns_id, u64 flags)
5235+{
5236+ struct sock *sk = bpf_skc_lookup(skb, tuple, len, proto, netns_id,
5237+ flags);
5238+
5239+ if (sk)
5240+ sk = sk_to_full_sk(sk);
5241+
5242+ return sk;
5243+}
5244+
5245+BPF_CALL_5(bpf_skc_lookup_tcp, struct sk_buff *, skb,
5246+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
5247+{
5248+ return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP,
5249+ netns_id, flags);
5250+}
5251+
5252+static const struct bpf_func_proto bpf_skc_lookup_tcp_proto = {
5253+ .func = bpf_skc_lookup_tcp,
5254+ .gpl_only = false,
5255+ .pkt_access = true,
5256+ .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
5257+ .arg1_type = ARG_PTR_TO_CTX,
5258+ .arg2_type = ARG_PTR_TO_MEM,
5259+ .arg3_type = ARG_CONST_SIZE,
5260+ .arg4_type = ARG_ANYTHING,
5261+ .arg5_type = ARG_ANYTHING,
5262+};
5263+
52205264 BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
52215265 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
52225266 {
5223− return bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, netns_id, flags);
5267+ return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP,
5268+ netns_id, flags);
52245269 }
52255270
52265271 static const struct bpf_func_proto bpf_sk_lookup_tcp_proto = {
@@ -5238,7 +5283,8 @@ static const struct bpf_func_proto bpf_sk_lookup_tcp_proto = { · 11 unmodified lines
52385283 BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
52395284 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
52405285 {
5241− return bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, netns_id, flags);
5286+ return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP,
5287+ netns_id, flags);
52425288 }
52435289
52445290 static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
@@ -5273,8 +5319,9 @@ BPF_CALL_5(bpf_xdp_sk_lookup_udp, struct xdp_buff *, ctx, · 28 unmodified lines
52735319 struct net *caller_net = dev_net(ctx->rxq->dev);
52745320 int ifindex = ctx->rxq->dev->ifindex;
52755321
5276− return __bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex,
5277− IPPROTO_UDP, netns_id, flags);
5322+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
5323+ ifindex, IPPROTO_UDP, netns_id,
5324+ flags);
52785325 }
52795326
52805327 static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = {
@@ -5289,14 +5336,38 @@ static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = { · 8 unmodified lines
52895336 .arg5_type = ARG_ANYTHING,
52905337 };
52915338
5339+BPF_CALL_5(bpf_xdp_skc_lookup_tcp, struct xdp_buff *, ctx,
5340+ struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
5341+{
5342+ struct net *caller_net = dev_net(ctx->rxq->dev);
5343+ int ifindex = ctx->rxq->dev->ifindex;
5344+
5345+ return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, caller_net,
5346+ ifindex, IPPROTO_TCP, netns_id,
5347+ flags);
5348+}
5349+
5350+static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = {
5351+ .func = bpf_xdp_skc_lookup_tcp,
5352+ .gpl_only = false,
5353+ .pkt_access = true,
5354+ .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
5355+ .arg1_type = ARG_PTR_TO_CTX,
5356+ .arg2_type = ARG_PTR_TO_MEM,
5357+ .arg3_type = ARG_CONST_SIZE,
5358+ .arg4_type = ARG_ANYTHING,
5359+ .arg5_type = ARG_ANYTHING,
5360+};
5361+
52925362 BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx,
52935363 struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
52945364 {
52955365 struct net *caller_net = dev_net(ctx->rxq->dev);
52965366 int ifindex = ctx->rxq->dev->ifindex;
52975367
5298− return __bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex,
5299− IPPROTO_TCP, netns_id, flags);
5368+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
5369+ ifindex, IPPROTO_TCP, netns_id,
5370+ flags);
53005371 }
53015372
53025373 static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = {
@@ -5311,11 +5382,31 @@ static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = { · 8 unmodified lines
53115382 .arg5_type = ARG_ANYTHING,
53125383 };
53135384
5385+BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
5386+ struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
5387+{
5388+ return (unsigned long)__bpf_skc_lookup(NULL, tuple, len,
5389+ sock_net(ctx->sk), 0,
5390+ IPPROTO_TCP, netns_id, flags);
5391+}
5392+
5393+static const struct bpf_func_proto bpf_sock_addr_skc_lookup_tcp_proto = {
5394+ .func = bpf_sock_addr_skc_lookup_tcp,
5395+ .gpl_only = false,
5396+ .ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
5397+ .arg1_type = ARG_PTR_TO_CTX,
5398+ .arg2_type = ARG_PTR_TO_MEM,
5399+ .arg3_type = ARG_CONST_SIZE,
5400+ .arg4_type = ARG_ANYTHING,
5401+ .arg5_type = ARG_ANYTHING,
5402+};
5403+
53145404 BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
53155405 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
53165406 {
5317− return __bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0,
5318− IPPROTO_TCP, netns_id, flags);
5407+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
5408+ sock_net(ctx->sk), 0, IPPROTO_TCP,
5409+ netns_id, flags);
53195410 }
53205411
53215412 static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = {
@@ -5332,8 +5423,9 @@ static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = { · 10 unmodified lines
53325423 BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx,
53335424 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
53345425 {
5335− return __bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0,
5336− IPPROTO_UDP, netns_id, flags);
5426+ return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
5427+ sock_net(ctx->sk), 0, IPPROTO_UDP,
5428+ netns_id, flags);
53375429 }
53385430
53395431 static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {
@@ -5586,6 +5678,8 @@ sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 246 unmodified lines
55865678 return &bpf_sock_addr_sk_lookup_udp_proto;
55875679 case BPF_FUNC_sk_release:
55885680 return &bpf_sk_release_proto;
5681+ case BPF_FUNC_skc_lookup_tcp:
5682+ return &bpf_sock_addr_skc_lookup_tcp_proto;
55895683 #endif /* CONFIG_INET */
55905684 default:
55915685 return bpf_base_func_proto(func_id);
@@ -5719,6 +5813,8 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 127 unmodified lines
57195813 return &bpf_tcp_sock_proto;
57205814 case BPF_FUNC_get_listener_sock:
57215815 return &bpf_get_listener_sock_proto;
5816+ case BPF_FUNC_skc_lookup_tcp:
5817+ return &bpf_skc_lookup_tcp_proto;
57225818 #endif
57235819 default:
57245820 return bpf_base_func_proto(func_id);
@@ -5754,6 +5850,8 @@ xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 29 unmodified lines
57545850 return &bpf_xdp_sk_lookup_tcp_proto;
57555851 case BPF_FUNC_sk_release:
57565852 return &bpf_sk_release_proto;
5853+ case BPF_FUNC_skc_lookup_tcp:
5854+ return &bpf_xdp_skc_lookup_tcp_proto;
57575855 #endif
57585856 default:
57595857 return bpf_base_func_proto(func_id);
@@ -5846,6 +5944,8 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog) · 86 unmodified lines
58465944 return &bpf_sk_lookup_udp_proto;
58475945 case BPF_FUNC_sk_release:
58485946 return &bpf_sk_release_proto;
5947+ case BPF_FUNC_skc_lookup_tcp:
5948+ return &bpf_skc_lookup_tcp_proto;
58495949 #endif
58505950 default:
58515951 return bpf_base_func_proto(func_id);