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
2431 * Return2431 * Return
2432 * A **struct bpf_sock** pointer on success, or **NULL** in2432 * A **struct bpf_sock** pointer on success, or **NULL** in
2433 * case of failure.2433 * 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.
2434 */2451 */
2435#define __BPF_FUNC_MAPPER(FN) \2452#define __BPF_FUNC_MAPPER(FN) \
2436 FN(unspec), \2453 FN(unspec), \
@@ -2531,7 +2548,8 @@ union bpf_attr { · 94 unmodified lines
2531 FN(sk_fullsock), \2548 FN(sk_fullsock), \
2532 FN(tcp_sock), \2549 FN(tcp_sock), \
2533 FN(skb_ecn_set_ce), \2550 FN(skb_ecn_set_ce), \
2534 FN(get_listener_sock),2551 FN(get_listener_sock), \
2552 FN(skc_lookup_tcp),
2535 2553
2536/* integer value in 'imm' field of BPF_CALL instruction selects which helper2554/* integer value in 'imm' field of BPF_CALL instruction selects which helper
2537 * function eBPF program intends to call2555 * 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
369static bool is_acquire_function(enum bpf_func_id func_id)369static bool is_acquire_function(enum bpf_func_id func_id)
370{370{
371 return func_id == BPF_FUNC_sk_lookup_tcp ||371 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;
373}374}
374 375
375static bool is_ptr_cast_function(enum bpf_func_id func_id)376static 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
5156 return sk;5156 return sk;
5157}5157}
5158 5158
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,
5160 * taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.5160 * taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
5161 * Returns the socket as an 'unsigned long' to simplify the casting in the5161 * Returns the socket as an 'unsigned long' to simplify the casting in the
5162 * callers to satisfy BPF_CALL declarations.5162 * callers to satisfy BPF_CALL declarations.
5163 */5163 */
5164static unsigned long5164static struct sock *
5165__bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,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,5166 struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
5167 u64 flags)5167 u64 flags)
5168{5168{
5169 struct sock *sk = NULL;5169 struct sock *sk = NULL;
5170 u8 family = AF_UNSPEC;5170 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
5192 put_net(net);5192 put_net(net);
5193 }5193 }
5194 5194
5195out:
5196 return sk;
5197}
5198
5199static 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
5195 if (sk)5207 if (sk)
5196 sk = sk_to_full_sk(sk);5208 sk = sk_to_full_sk(sk);
5197out:5209
5198 return (unsigned long) sk;5210 return sk;
5199}5211}
5200 5212
5201static unsigned long5213static struct sock *
5202bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,5214bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
5203 u8 proto, u64 netns_id, u64 flags)5215 u8 proto, u64 netns_id, u64 flags)
5204{5216{
5205 struct net *caller_net;5217 struct net *caller_net;
5206 int ifindex;5218 int ifindex;
@@ -5213,14 +5225,47 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len, · 6 unmodified lines
5213 ifindex = 0;5225 ifindex = 0;
5214 }5226 }
5215 5227
5216 return __bpf_sk_lookup(skb, tuple, len, caller_net, ifindex,5228 return __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto,
5217 proto, netns_id, flags);5229 netns_id, flags);
5218}5230}
5219 5231
5232static struct sock *
5233bpf_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
5245BPF_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
5252static 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
5220BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,5264BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
5221 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)5265 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
5222{5266{
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);
5224}5269}
5225 5270
5226static const struct bpf_func_proto bpf_sk_lookup_tcp_proto = {5271static 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
5238BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,5283BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
5239 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)5284 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
5240{5285{
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);
5242}5288}
5243 5289
5244static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {5290static 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
5273 struct net *caller_net = dev_net(ctx->rxq->dev);5319 struct net *caller_net = dev_net(ctx->rxq->dev);
5274 int ifindex = ctx->rxq->dev->ifindex;5320 int ifindex = ctx->rxq->dev->ifindex;
5275 5321
5276 return __bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex,5322 return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
5277 IPPROTO_UDP, netns_id, flags);5323 ifindex, IPPROTO_UDP, netns_id,
5324 flags);
5278}5325}
5279 5326
5280static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = {5327static 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
5289 .arg5_type = ARG_ANYTHING,5336 .arg5_type = ARG_ANYTHING,
5290};5337};
5291 5338
5339BPF_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
5350static 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
5292BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx,5362BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx,
5293 struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)5363 struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
5294{5364{
5295 struct net *caller_net = dev_net(ctx->rxq->dev);5365 struct net *caller_net = dev_net(ctx->rxq->dev);
5296 int ifindex = ctx->rxq->dev->ifindex;5366 int ifindex = ctx->rxq->dev->ifindex;
5297 5367
5298 return __bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex,5368 return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
5299 IPPROTO_TCP, netns_id, flags);5369 ifindex, IPPROTO_TCP, netns_id,
5370 flags);
5300}5371}
5301 5372
5302static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = {5373static 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
5311 .arg5_type = ARG_ANYTHING,5382 .arg5_type = ARG_ANYTHING,
5312};5383};
5313 5384
5385BPF_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
5393static 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
5314BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx,5404BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
5315 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)5405 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
5316{5406{
5317 return __bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0,5407 return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
5318 IPPROTO_TCP, netns_id, flags);5408 sock_net(ctx->sk), 0, IPPROTO_TCP,
5409 netns_id, flags);
5319}5410}
5320 5411
5321static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = {5412static 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
5332BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx,5423BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx,
5333 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)5424 struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
5334{5425{
5335 return __bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0,5426 return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
5336 IPPROTO_UDP, netns_id, flags);5427 sock_net(ctx->sk), 0, IPPROTO_UDP,
5428 netns_id, flags);
5337}5429}
5338 5430
5339static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {5431static 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
5586 return &bpf_sock_addr_sk_lookup_udp_proto;5678 return &bpf_sock_addr_sk_lookup_udp_proto;
5587 case BPF_FUNC_sk_release:5679 case BPF_FUNC_sk_release:
5588 return &bpf_sk_release_proto;5680 return &bpf_sk_release_proto;
5681 case BPF_FUNC_skc_lookup_tcp:
5682 return &bpf_sock_addr_skc_lookup_tcp_proto;
5589#endif /* CONFIG_INET */5683#endif /* CONFIG_INET */
5590 default:5684 default:
5591 return bpf_base_func_proto(func_id);5685 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
5719 return &bpf_tcp_sock_proto;5813 return &bpf_tcp_sock_proto;
5720 case BPF_FUNC_get_listener_sock:5814 case BPF_FUNC_get_listener_sock:
5721 return &bpf_get_listener_sock_proto;5815 return &bpf_get_listener_sock_proto;
5816 case BPF_FUNC_skc_lookup_tcp:
5817 return &bpf_skc_lookup_tcp_proto;
5722#endif5818#endif
5723 default:5819 default:
5724 return bpf_base_func_proto(func_id);5820 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
5754 return &bpf_xdp_sk_lookup_tcp_proto;5850 return &bpf_xdp_sk_lookup_tcp_proto;
5755 case BPF_FUNC_sk_release:5851 case BPF_FUNC_sk_release:
5756 return &bpf_sk_release_proto;5852 return &bpf_sk_release_proto;
5853 case BPF_FUNC_skc_lookup_tcp:
5854 return &bpf_xdp_skc_lookup_tcp_proto;
5757#endif5855#endif
5758 default:5856 default:
5759 return bpf_base_func_proto(func_id);5857 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
5846 return &bpf_sk_lookup_udp_proto;5944 return &bpf_sk_lookup_udp_proto;
5847 case BPF_FUNC_sk_release:5945 case BPF_FUNC_sk_release:
5848 return &bpf_sk_release_proto;5946 return &bpf_sk_release_proto;
5947 case BPF_FUNC_skc_lookup_tcp:
5948 return &bpf_skc_lookup_tcp_proto;
5849#endif5949#endif
5850 default:5950 default:
5851 return bpf_base_func_proto(func_id);5951 return bpf_base_func_proto(func_id);