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 <lmb@cloudflare.com> Signed-off-by: Alexei Starovoitov <ast@kernel.org>
This commit is contained in:
parent
85a51f8c28
commit
edbf8c01de
|
@ -2431,6 +2431,23 @@ union bpf_attr {
|
||||||
* Return
|
* Return
|
||||||
* A **struct bpf_sock** pointer on success, or **NULL** in
|
* A **struct bpf_sock** pointer on success, or **NULL** in
|
||||||
* case of failure.
|
* case of failure.
|
||||||
|
*
|
||||||
|
* struct bpf_sock *bpf_skc_lookup_tcp(void *ctx, struct bpf_sock_tuple *tuple, u32 tuple_size, u64 netns, u64 flags)
|
||||||
|
* Description
|
||||||
|
* Look for TCP socket matching *tuple*, optionally in a child
|
||||||
|
* network namespace *netns*. The return value must be checked,
|
||||||
|
* and if non-**NULL**, released via **bpf_sk_release**\ ().
|
||||||
|
*
|
||||||
|
* This function is identical to bpf_sk_lookup_tcp, except that it
|
||||||
|
* also returns timewait or request sockets. Use bpf_sk_fullsock
|
||||||
|
* or bpf_tcp_socket to access the full structure.
|
||||||
|
*
|
||||||
|
* This helper is available only if the kernel was compiled with
|
||||||
|
* **CONFIG_NET** configuration option.
|
||||||
|
* Return
|
||||||
|
* Pointer to **struct bpf_sock**, or **NULL** in case of failure.
|
||||||
|
* For sockets with reuseport option, the **struct bpf_sock**
|
||||||
|
* result is from **reuse->socks**\ [] using the hash of the tuple.
|
||||||
*/
|
*/
|
||||||
#define __BPF_FUNC_MAPPER(FN) \
|
#define __BPF_FUNC_MAPPER(FN) \
|
||||||
FN(unspec), \
|
FN(unspec), \
|
||||||
|
@ -2531,7 +2548,8 @@ union bpf_attr {
|
||||||
FN(sk_fullsock), \
|
FN(sk_fullsock), \
|
||||||
FN(tcp_sock), \
|
FN(tcp_sock), \
|
||||||
FN(skb_ecn_set_ce), \
|
FN(skb_ecn_set_ce), \
|
||||||
FN(get_listener_sock),
|
FN(get_listener_sock), \
|
||||||
|
FN(skc_lookup_tcp),
|
||||||
|
|
||||||
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
|
/* integer value in 'imm' field of BPF_CALL instruction selects which helper
|
||||||
* function eBPF program intends to call
|
* function eBPF program intends to call
|
||||||
|
|
|
@ -369,7 +369,8 @@ static bool is_release_function(enum bpf_func_id func_id)
|
||||||
static bool is_acquire_function(enum bpf_func_id func_id)
|
static bool is_acquire_function(enum bpf_func_id func_id)
|
||||||
{
|
{
|
||||||
return func_id == BPF_FUNC_sk_lookup_tcp ||
|
return func_id == BPF_FUNC_sk_lookup_tcp ||
|
||||||
func_id == BPF_FUNC_sk_lookup_udp;
|
func_id == BPF_FUNC_sk_lookup_udp ||
|
||||||
|
func_id == BPF_FUNC_skc_lookup_tcp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool is_ptr_cast_function(enum bpf_func_id func_id)
|
static bool is_ptr_cast_function(enum bpf_func_id func_id)
|
||||||
|
|
|
@ -5156,15 +5156,15 @@ static struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
|
||||||
return sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* bpf_sk_lookup performs the core lookup for different types of sockets,
|
/* bpf_skc_lookup performs the core lookup for different types of sockets,
|
||||||
* taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
|
* taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
|
||||||
* Returns the socket as an 'unsigned long' to simplify the casting in the
|
* Returns the socket as an 'unsigned long' to simplify the casting in the
|
||||||
* callers to satisfy BPF_CALL declarations.
|
* callers to satisfy BPF_CALL declarations.
|
||||||
*/
|
*/
|
||||||
static unsigned long
|
static struct sock *
|
||||||
__bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
__bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
|
struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
|
||||||
u64 flags)
|
u64 flags)
|
||||||
{
|
{
|
||||||
struct sock *sk = NULL;
|
struct sock *sk = NULL;
|
||||||
u8 family = AF_UNSPEC;
|
u8 family = AF_UNSPEC;
|
||||||
|
@ -5192,15 +5192,27 @@ __bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
put_net(net);
|
put_net(net);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sk)
|
|
||||||
sk = sk_to_full_sk(sk);
|
|
||||||
out:
|
out:
|
||||||
return (unsigned long) sk;
|
return sk;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long
|
static struct sock *
|
||||||
bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
__bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
u8 proto, u64 netns_id, u64 flags)
|
struct net *caller_net, u32 ifindex, u8 proto, u64 netns_id,
|
||||||
|
u64 flags)
|
||||||
|
{
|
||||||
|
struct sock *sk = __bpf_skc_lookup(skb, tuple, len, caller_net,
|
||||||
|
ifindex, proto, netns_id, flags);
|
||||||
|
|
||||||
|
if (sk)
|
||||||
|
sk = sk_to_full_sk(sk);
|
||||||
|
|
||||||
|
return sk;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct sock *
|
||||||
|
bpf_skc_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
|
u8 proto, u64 netns_id, u64 flags)
|
||||||
{
|
{
|
||||||
struct net *caller_net;
|
struct net *caller_net;
|
||||||
int ifindex;
|
int ifindex;
|
||||||
|
@ -5213,14 +5225,47 @@ bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
ifindex = 0;
|
ifindex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return __bpf_sk_lookup(skb, tuple, len, caller_net, ifindex,
|
return __bpf_skc_lookup(skb, tuple, len, caller_net, ifindex, proto,
|
||||||
proto, netns_id, flags);
|
netns_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct sock *
|
||||||
|
bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
|
||||||
|
u8 proto, u64 netns_id, u64 flags)
|
||||||
|
{
|
||||||
|
struct sock *sk = bpf_skc_lookup(skb, tuple, len, proto, netns_id,
|
||||||
|
flags);
|
||||||
|
|
||||||
|
if (sk)
|
||||||
|
sk = sk_to_full_sk(sk);
|
||||||
|
|
||||||
|
return sk;
|
||||||
|
}
|
||||||
|
|
||||||
|
BPF_CALL_5(bpf_skc_lookup_tcp, struct sk_buff *, skb,
|
||||||
|
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
||||||
|
{
|
||||||
|
return (unsigned long)bpf_skc_lookup(skb, tuple, len, IPPROTO_TCP,
|
||||||
|
netns_id, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bpf_func_proto bpf_skc_lookup_tcp_proto = {
|
||||||
|
.func = bpf_skc_lookup_tcp,
|
||||||
|
.gpl_only = false,
|
||||||
|
.pkt_access = true,
|
||||||
|
.ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
|
||||||
|
.arg1_type = ARG_PTR_TO_CTX,
|
||||||
|
.arg2_type = ARG_PTR_TO_MEM,
|
||||||
|
.arg3_type = ARG_CONST_SIZE,
|
||||||
|
.arg4_type = ARG_ANYTHING,
|
||||||
|
.arg5_type = ARG_ANYTHING,
|
||||||
|
};
|
||||||
|
|
||||||
BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
|
BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
|
||||||
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
||||||
{
|
{
|
||||||
return bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, netns_id, flags);
|
return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP,
|
||||||
|
netns_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_sk_lookup_tcp_proto = {
|
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 = {
|
||||||
BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
|
BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
|
||||||
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
||||||
{
|
{
|
||||||
return bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, netns_id, flags);
|
return (unsigned long)bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP,
|
||||||
|
netns_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
|
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,
|
||||||
struct net *caller_net = dev_net(ctx->rxq->dev);
|
struct net *caller_net = dev_net(ctx->rxq->dev);
|
||||||
int ifindex = ctx->rxq->dev->ifindex;
|
int ifindex = ctx->rxq->dev->ifindex;
|
||||||
|
|
||||||
return __bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex,
|
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
|
||||||
IPPROTO_UDP, netns_id, flags);
|
ifindex, IPPROTO_UDP, netns_id,
|
||||||
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_xdp_sk_lookup_udp_proto = {
|
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 = {
|
||||||
.arg5_type = ARG_ANYTHING,
|
.arg5_type = ARG_ANYTHING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BPF_CALL_5(bpf_xdp_skc_lookup_tcp, struct xdp_buff *, ctx,
|
||||||
|
struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
|
||||||
|
{
|
||||||
|
struct net *caller_net = dev_net(ctx->rxq->dev);
|
||||||
|
int ifindex = ctx->rxq->dev->ifindex;
|
||||||
|
|
||||||
|
return (unsigned long)__bpf_skc_lookup(NULL, tuple, len, caller_net,
|
||||||
|
ifindex, IPPROTO_TCP, netns_id,
|
||||||
|
flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bpf_func_proto bpf_xdp_skc_lookup_tcp_proto = {
|
||||||
|
.func = bpf_xdp_skc_lookup_tcp,
|
||||||
|
.gpl_only = false,
|
||||||
|
.pkt_access = true,
|
||||||
|
.ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
|
||||||
|
.arg1_type = ARG_PTR_TO_CTX,
|
||||||
|
.arg2_type = ARG_PTR_TO_MEM,
|
||||||
|
.arg3_type = ARG_CONST_SIZE,
|
||||||
|
.arg4_type = ARG_ANYTHING,
|
||||||
|
.arg5_type = ARG_ANYTHING,
|
||||||
|
};
|
||||||
|
|
||||||
BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx,
|
BPF_CALL_5(bpf_xdp_sk_lookup_tcp, struct xdp_buff *, ctx,
|
||||||
struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
|
struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
|
||||||
{
|
{
|
||||||
struct net *caller_net = dev_net(ctx->rxq->dev);
|
struct net *caller_net = dev_net(ctx->rxq->dev);
|
||||||
int ifindex = ctx->rxq->dev->ifindex;
|
int ifindex = ctx->rxq->dev->ifindex;
|
||||||
|
|
||||||
return __bpf_sk_lookup(NULL, tuple, len, caller_net, ifindex,
|
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len, caller_net,
|
||||||
IPPROTO_TCP, netns_id, flags);
|
ifindex, IPPROTO_TCP, netns_id,
|
||||||
|
flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_xdp_sk_lookup_tcp_proto = {
|
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 = {
|
||||||
.arg5_type = ARG_ANYTHING,
|
.arg5_type = ARG_ANYTHING,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
BPF_CALL_5(bpf_sock_addr_skc_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
|
||||||
|
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
||||||
|
{
|
||||||
|
return (unsigned long)__bpf_skc_lookup(NULL, tuple, len,
|
||||||
|
sock_net(ctx->sk), 0,
|
||||||
|
IPPROTO_TCP, netns_id, flags);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct bpf_func_proto bpf_sock_addr_skc_lookup_tcp_proto = {
|
||||||
|
.func = bpf_sock_addr_skc_lookup_tcp,
|
||||||
|
.gpl_only = false,
|
||||||
|
.ret_type = RET_PTR_TO_SOCK_COMMON_OR_NULL,
|
||||||
|
.arg1_type = ARG_PTR_TO_CTX,
|
||||||
|
.arg2_type = ARG_PTR_TO_MEM,
|
||||||
|
.arg3_type = ARG_CONST_SIZE,
|
||||||
|
.arg4_type = ARG_ANYTHING,
|
||||||
|
.arg5_type = ARG_ANYTHING,
|
||||||
|
};
|
||||||
|
|
||||||
BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
|
BPF_CALL_5(bpf_sock_addr_sk_lookup_tcp, struct bpf_sock_addr_kern *, ctx,
|
||||||
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
||||||
{
|
{
|
||||||
return __bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0,
|
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
|
||||||
IPPROTO_TCP, netns_id, flags);
|
sock_net(ctx->sk), 0, IPPROTO_TCP,
|
||||||
|
netns_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_sock_addr_sk_lookup_tcp_proto = {
|
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 = {
|
||||||
BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx,
|
BPF_CALL_5(bpf_sock_addr_sk_lookup_udp, struct bpf_sock_addr_kern *, ctx,
|
||||||
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
struct bpf_sock_tuple *, tuple, u32, len, u64, netns_id, u64, flags)
|
||||||
{
|
{
|
||||||
return __bpf_sk_lookup(NULL, tuple, len, sock_net(ctx->sk), 0,
|
return (unsigned long)__bpf_sk_lookup(NULL, tuple, len,
|
||||||
IPPROTO_UDP, netns_id, flags);
|
sock_net(ctx->sk), 0, IPPROTO_UDP,
|
||||||
|
netns_id, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct bpf_func_proto bpf_sock_addr_sk_lookup_udp_proto = {
|
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)
|
||||||
return &bpf_sock_addr_sk_lookup_udp_proto;
|
return &bpf_sock_addr_sk_lookup_udp_proto;
|
||||||
case BPF_FUNC_sk_release:
|
case BPF_FUNC_sk_release:
|
||||||
return &bpf_sk_release_proto;
|
return &bpf_sk_release_proto;
|
||||||
|
case BPF_FUNC_skc_lookup_tcp:
|
||||||
|
return &bpf_sock_addr_skc_lookup_tcp_proto;
|
||||||
#endif /* CONFIG_INET */
|
#endif /* CONFIG_INET */
|
||||||
default:
|
default:
|
||||||
return bpf_base_func_proto(func_id);
|
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)
|
||||||
return &bpf_tcp_sock_proto;
|
return &bpf_tcp_sock_proto;
|
||||||
case BPF_FUNC_get_listener_sock:
|
case BPF_FUNC_get_listener_sock:
|
||||||
return &bpf_get_listener_sock_proto;
|
return &bpf_get_listener_sock_proto;
|
||||||
|
case BPF_FUNC_skc_lookup_tcp:
|
||||||
|
return &bpf_skc_lookup_tcp_proto;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return bpf_base_func_proto(func_id);
|
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)
|
||||||
return &bpf_xdp_sk_lookup_tcp_proto;
|
return &bpf_xdp_sk_lookup_tcp_proto;
|
||||||
case BPF_FUNC_sk_release:
|
case BPF_FUNC_sk_release:
|
||||||
return &bpf_sk_release_proto;
|
return &bpf_sk_release_proto;
|
||||||
|
case BPF_FUNC_skc_lookup_tcp:
|
||||||
|
return &bpf_xdp_skc_lookup_tcp_proto;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return bpf_base_func_proto(func_id);
|
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)
|
||||||
return &bpf_sk_lookup_udp_proto;
|
return &bpf_sk_lookup_udp_proto;
|
||||||
case BPF_FUNC_sk_release:
|
case BPF_FUNC_sk_release:
|
||||||
return &bpf_sk_release_proto;
|
return &bpf_sk_release_proto;
|
||||||
|
case BPF_FUNC_skc_lookup_tcp:
|
||||||
|
return &bpf_skc_lookup_tcp_proto;
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
return bpf_base_func_proto(func_id);
|
return bpf_base_func_proto(func_id);
|
||||||
|
|
Loading…
Reference in New Issue