Skip to content

Commit edbf8c0

Browse files
lmbAlexei Starovoitov
authored and
Alexei Starovoitov
committed
bpf: add skc_lookup_tcp helper
Allow looking up a sock_common. This gives eBPF programs access to timewait and request sockets. Signed-off-by: Lorenz Bauer <[email protected]> Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 85a51f8 commit edbf8c0

File tree

3 files changed

+143
-24
lines changed

3 files changed

+143
-24
lines changed

include/uapi/linux/bpf.h

+19-1
Original file line numberDiff line numberDiff line change
@@ -2431,6 +2431,23 @@ union bpf_attr {
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 {
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
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,8 @@ static bool is_release_function(enum bpf_func_id func_id)
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
Original file line numberDiff line numberDiff line change
@@ -5156,15 +5156,15 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
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,
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,
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 = {
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,
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 = {
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 = {
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 = {
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)
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)
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)
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)
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);

0 commit comments

Comments
 (0)