netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-12  0:36 [PATCH bpf-next 00/11] Add socket lookup support Joe Stringer
@ 2018-09-12  0:36 ` Joe Stringer
  2018-09-13  0:06   ` Alexei Starovoitov
                     ` (2 more replies)
  0 siblings, 3 replies; 12+ messages in thread
From: Joe Stringer @ 2018-09-12  0:36 UTC (permalink / raw)
  To: daniel
  Cc: netdev, ast, john.fastabend, tgraf, kafai, nitin.hande,
	mauricio.vasquez

This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
socket listening on this host, and returns a socket pointer which the
BPF program can then access to determine, for instance, whether to
forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
socket, so when a BPF program makes use of this function, it must
subsequently pass the returned pointer into the newly added sk_release()
to return the reference.

By way of example, the following pseudocode would filter inbound
connections at XDP if there is no corresponding service listening for
the traffic:

  struct bpf_sock_tuple tuple;
  struct bpf_sock_ops *sk;

  populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
  sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
  if (!sk) {
    // Couldn't find a socket listening for this traffic. Drop.
    return TC_ACT_SHOT;
  }
  bpf_sk_release(sk, 0);
  return TC_ACT_OK;

Signed-off-by: Joe Stringer <joe@wand.net.nz>
---
 include/uapi/linux/bpf.h                  |  54 +++++++-
 kernel/bpf/verifier.c                     |   8 +-
 net/core/filter.c                         | 145 ++++++++++++++++++++++
 tools/include/uapi/linux/bpf.h            |  54 +++++++-
 tools/testing/selftests/bpf/bpf_helpers.h |  12 ++
 5 files changed, 270 insertions(+), 3 deletions(-)

diff --git a/include/uapi/linux/bpf.h b/include/uapi/linux/bpf.h
index 66917a4eba27..8ed6e293113f 100644
--- a/include/uapi/linux/bpf.h
+++ b/include/uapi/linux/bpf.h
@@ -2141,6 +2141,41 @@ union bpf_attr {
  *		request in the skb.
  *	Return
  *		0 on success, or a negative error in case of failure.
+ *
+ * struct bpf_sock_ops *bpf_sk_lookup_tcp(ctx, tuple, tuple_size, netns, flags)
+ * 	Decription
+ * 		Look for TCP socket matching 'tuple'. The return value must
+ * 		be checked, and if non-NULL, released via bpf_sk_release().
+ * 		@ctx: pointer to ctx
+ * 		@tuple: pointer to struct bpf_sock_tuple
+ * 		@tuple_size: size of the tuple
+ * 		@netns: network namespace id
+ * 		@flags: flags value
+ * 	Return
+ * 		pointer to socket ops on success, or
+ * 		NULL in case of failure
+ *
+ * struct bpf_sock_ops *bpf_sk_lookup_udp(ctx, tuple, tuple_size, netns, flags)
+ * 	Decription
+ * 		Look for UDP socket matching 'tuple'. The return value must
+ * 		be checked, and if non-NULL, released via bpf_sk_release().
+ * 		@ctx: pointer to ctx
+ * 		@tuple: pointer to struct bpf_sock_tuple
+ * 		@tuple_size: size of the tuple
+ * 		@netns: network namespace id
+ * 		@flags: flags value
+ * 	Return
+ * 		pointer to socket ops on success, or
+ * 		NULL in case of failure
+ *
+ *  int bpf_sk_release(sock, flags)
+ * 	Description
+ * 		Release the reference held by 'sock'.
+ * 		@sock: Pointer reference to release. Must be found via
+ * 		       bpf_sk_lookup_xxx().
+ * 		@flags: flags value
+ * 	Return
+ * 		0 on success, or a negative error in case of failure.
  */
 #define __BPF_FUNC_MAPPER(FN)		\
 	FN(unspec),			\
@@ -2226,7 +2261,10 @@ union bpf_attr {
 	FN(get_current_cgroup_id),	\
 	FN(get_local_storage),		\
 	FN(sk_select_reuseport),	\
-	FN(skb_ancestor_cgroup_id),
+	FN(skb_ancestor_cgroup_id),	\
+	FN(sk_lookup_tcp),		\
+	FN(sk_lookup_udp),		\
+	FN(sk_release),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
@@ -2395,6 +2433,20 @@ struct bpf_sock {
 				 */
 };
 
+struct bpf_sock_tuple {
+	union {
+		__be32 ipv6[4];
+		__be32 ipv4;
+	} saddr;
+	union {
+		__be32 ipv6[4];
+		__be32 ipv4;
+	} daddr;
+	__be16 sport;
+	__be16 dport;
+	__u8 family;
+};
+
 #define XDP_PACKET_HEADROOM 256
 
 /* User return codes for XDP prog type.
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 67c62ef67d37..37feedaaa1c3 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -153,6 +153,12 @@ static const struct bpf_verifier_ops * const bpf_verifier_ops[] = {
  * PTR_TO_MAP_VALUE, PTR_TO_SOCKET_OR_NULL becomes PTR_TO_SOCKET when the type
  * passes through a NULL-check conditional. For the branch wherein the state is
  * changed to CONST_IMM, the verifier releases the reference.
+ *
+ * For each helper function that allocates a reference, such as
+ * bpf_sk_lookup_tcp(), there is a corresponding release function, such as
+ * bpf_sk_release(). When a reference type passes into the release function,
+ * the verifier also releases the reference. If any unchecked or unreleased
+ * reference remains at the end of the program, the verifier rejects it.
  */
 
 /* verifier_state + insn_idx are pushed to stack when branch is encountered */
@@ -300,7 +306,7 @@ static bool arg_type_is_refcounted(enum bpf_arg_type type)
  */
 static bool is_release_function(enum bpf_func_id func_id)
 {
-	return false;
+	return func_id == BPF_FUNC_sk_release;
 }
 
 /* string representation of 'enum bpf_reg_type' */
diff --git a/net/core/filter.c b/net/core/filter.c
index 23e6e5202138..b092cae8efd5 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -58,13 +58,17 @@
 #include <net/busy_poll.h>
 #include <net/tcp.h>
 #include <net/xfrm.h>
+#include <net/udp.h>
 #include <linux/bpf_trace.h>
 #include <net/xdp_sock.h>
 #include <linux/inetdevice.h>
+#include <net/inet_hashtables.h>
+#include <net/inet6_hashtables.h>
 #include <net/ip_fib.h>
 #include <net/flow.h>
 #include <net/arp.h>
 #include <net/ipv6.h>
+#include <net/net_namespace.h>
 #include <linux/seg6_local.h>
 #include <net/seg6.h>
 #include <net/seg6_local.h>
@@ -4811,6 +4815,135 @@ static const struct bpf_func_proto bpf_lwt_seg6_adjust_srh_proto = {
 };
 #endif /* CONFIG_IPV6_SEG6_BPF */
 
+struct sock *sk_lookup(struct net *net, struct bpf_sock_tuple *tuple,
+		       struct sk_buff *skb, u8 proto)
+{
+	int dif = skb->dev->ifindex;
+	bool refcounted = false;
+	struct sock *sk = NULL;
+
+	if (tuple->family == AF_INET) {
+		int sdif = inet_sdif(skb);
+
+		if (proto == IPPROTO_TCP)
+			sk = __inet_lookup(net, &tcp_hashinfo, skb, 0,
+					   tuple->saddr.ipv4, tuple->sport,
+					   tuple->daddr.ipv4, tuple->dport,
+					   dif, sdif, &refcounted);
+		else
+			sk = __udp4_lib_lookup(net,
+					       tuple->saddr.ipv4, tuple->sport,
+					       tuple->daddr.ipv4, tuple->dport,
+					       dif, sdif, &udp_table, skb);
+#if IS_ENABLED(CONFIG_IPV6)
+	} else {
+		struct in6_addr *src6 = (struct in6_addr *)&tuple->saddr.ipv6;
+		struct in6_addr *dst6 = (struct in6_addr *)&tuple->daddr.ipv6;
+		int sdif = inet6_sdif(skb);
+
+		if (proto == IPPROTO_TCP)
+			sk = __inet6_lookup(net, &tcp_hashinfo, skb, 0,
+					    src6, tuple->sport,
+					    dst6, tuple->dport,
+					    dif, sdif, &refcounted);
+		else
+			sk = __udp6_lib_lookup(net, src6, tuple->sport,
+					       dst6, tuple->dport,
+					       dif, sdif, &udp_table, skb);
+	}
+#endif
+
+	if (unlikely(sk && !refcounted && !sock_flag(sk, SOCK_RCU_FREE))) {
+		WARN_ONCE(1, "Found non-RCU, unreferenced socket!");
+		sk = NULL;
+	}
+	return sk;
+}
+
+/* bpf_sk_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.
+ * Returns the socket as an 'unsigned long' to simplify the casting in the
+ * callers to satisfy BPF_CALL declarations.
+ */
+static unsigned long
+bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
+	      u8 proto, u32 netns_id, u64 flags)
+{
+	struct net *caller_net = dev_net(skb->dev);
+	struct sock *sk = NULL;
+	struct net *net;
+
+	if (unlikely(len != sizeof(struct bpf_sock_tuple) || flags ||
+		     (tuple->family != AF_INET && tuple->family != AF_INET6)))
+		goto out;
+
+	if (netns_id)
+		net = get_net_ns_by_id(caller_net, netns_id);
+	else
+		net = caller_net;
+	if (unlikely(!net))
+		goto out;
+	sk = sk_lookup(net, tuple, skb, proto);
+	put_net(net);
+
+	if (sk)
+		sk = sk_to_full_sk(sk);
+out:
+	return (unsigned long) sk;
+}
+
+BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
+	   struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
+{
+	return bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, netns_id, flags);
+}
+
+static const struct bpf_func_proto bpf_sk_lookup_tcp_proto = {
+	.func		= bpf_sk_lookup_tcp,
+	.gpl_only	= false,
+	.ret_type	= RET_PTR_TO_SOCKET_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_udp, struct sk_buff *, skb,
+	   struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
+{
+	return bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, netns_id, flags);
+}
+
+static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
+	.func		= bpf_sk_lookup_udp,
+	.gpl_only	= false,
+	.ret_type	= RET_PTR_TO_SOCKET_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_2(bpf_sk_release, struct sock *, sk, u64, flags)
+{
+	if (!sock_flag(sk, SOCK_RCU_FREE))
+		sock_gen_put(sk);
+
+	if (unlikely(flags))
+		return -EINVAL;
+	return 0;
+}
+
+static const struct bpf_func_proto bpf_sk_release_proto = {
+	.func		= bpf_sk_release,
+	.gpl_only	= false,
+	.ret_type	= RET_INTEGER,
+	.arg1_type	= ARG_PTR_TO_SOCKET,
+	.arg2_type	= ARG_ANYTHING,
+};
+
 bool bpf_helper_changes_pkt_data(void *func)
 {
 	if (func == bpf_skb_vlan_push ||
@@ -5017,6 +5150,12 @@ tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 	case BPF_FUNC_skb_ancestor_cgroup_id:
 		return &bpf_skb_ancestor_cgroup_id_proto;
 #endif
+	case BPF_FUNC_sk_lookup_tcp:
+		return &bpf_sk_lookup_tcp_proto;
+	case BPF_FUNC_sk_lookup_udp:
+		return &bpf_sk_lookup_udp_proto;
+	case BPF_FUNC_sk_release:
+		return &bpf_sk_release_proto;
 	default:
 		return bpf_base_func_proto(func_id);
 	}
@@ -5117,6 +5256,12 @@ sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
 		return &bpf_sk_redirect_hash_proto;
 	case BPF_FUNC_get_local_storage:
 		return &bpf_get_local_storage_proto;
+	case BPF_FUNC_sk_lookup_tcp:
+		return &bpf_sk_lookup_tcp_proto;
+	case BPF_FUNC_sk_lookup_udp:
+		return &bpf_sk_lookup_udp_proto;
+	case BPF_FUNC_sk_release:
+		return &bpf_sk_release_proto;
 	default:
 		return bpf_base_func_proto(func_id);
 	}
diff --git a/tools/include/uapi/linux/bpf.h b/tools/include/uapi/linux/bpf.h
index 66917a4eba27..8ed6e293113f 100644
--- a/tools/include/uapi/linux/bpf.h
+++ b/tools/include/uapi/linux/bpf.h
@@ -2141,6 +2141,41 @@ union bpf_attr {
  *		request in the skb.
  *	Return
  *		0 on success, or a negative error in case of failure.
+ *
+ * struct bpf_sock_ops *bpf_sk_lookup_tcp(ctx, tuple, tuple_size, netns, flags)
+ * 	Decription
+ * 		Look for TCP socket matching 'tuple'. The return value must
+ * 		be checked, and if non-NULL, released via bpf_sk_release().
+ * 		@ctx: pointer to ctx
+ * 		@tuple: pointer to struct bpf_sock_tuple
+ * 		@tuple_size: size of the tuple
+ * 		@netns: network namespace id
+ * 		@flags: flags value
+ * 	Return
+ * 		pointer to socket ops on success, or
+ * 		NULL in case of failure
+ *
+ * struct bpf_sock_ops *bpf_sk_lookup_udp(ctx, tuple, tuple_size, netns, flags)
+ * 	Decription
+ * 		Look for UDP socket matching 'tuple'. The return value must
+ * 		be checked, and if non-NULL, released via bpf_sk_release().
+ * 		@ctx: pointer to ctx
+ * 		@tuple: pointer to struct bpf_sock_tuple
+ * 		@tuple_size: size of the tuple
+ * 		@netns: network namespace id
+ * 		@flags: flags value
+ * 	Return
+ * 		pointer to socket ops on success, or
+ * 		NULL in case of failure
+ *
+ *  int bpf_sk_release(sock, flags)
+ * 	Description
+ * 		Release the reference held by 'sock'.
+ * 		@sock: Pointer reference to release. Must be found via
+ * 		       bpf_sk_lookup_xxx().
+ * 		@flags: flags value
+ * 	Return
+ * 		0 on success, or a negative error in case of failure.
  */
 #define __BPF_FUNC_MAPPER(FN)		\
 	FN(unspec),			\
@@ -2226,7 +2261,10 @@ union bpf_attr {
 	FN(get_current_cgroup_id),	\
 	FN(get_local_storage),		\
 	FN(sk_select_reuseport),	\
-	FN(skb_ancestor_cgroup_id),
+	FN(skb_ancestor_cgroup_id),	\
+	FN(sk_lookup_tcp),		\
+	FN(sk_lookup_udp),		\
+	FN(sk_release),
 
 /* integer value in 'imm' field of BPF_CALL instruction selects which helper
  * function eBPF program intends to call
@@ -2395,6 +2433,20 @@ struct bpf_sock {
 				 */
 };
 
+struct bpf_sock_tuple {
+	union {
+		__be32 ipv6[4];
+		__be32 ipv4;
+	} saddr;
+	union {
+		__be32 ipv6[4];
+		__be32 ipv4;
+	} daddr;
+	__be16 sport;
+	__be16 dport;
+	__u8 family;
+};
+
 #define XDP_PACKET_HEADROOM 256
 
 /* User return codes for XDP prog type.
diff --git a/tools/testing/selftests/bpf/bpf_helpers.h b/tools/testing/selftests/bpf/bpf_helpers.h
index e4be7730222d..88ce00c3aa0f 100644
--- a/tools/testing/selftests/bpf/bpf_helpers.h
+++ b/tools/testing/selftests/bpf/bpf_helpers.h
@@ -143,6 +143,18 @@ static unsigned long long (*bpf_skb_cgroup_id)(void *ctx) =
 	(void *) BPF_FUNC_skb_cgroup_id;
 static unsigned long long (*bpf_skb_ancestor_cgroup_id)(void *ctx, int level) =
 	(void *) BPF_FUNC_skb_ancestor_cgroup_id;
+static struct bpf_sock *(*bpf_sk_lookup_tcp)(void *ctx,
+					     struct bpf_sock_tuple *tuple,
+					     int size, unsigned int netns_id,
+					     unsigned long long flags) =
+	(void *) BPF_FUNC_sk_lookup_tcp;
+static struct bpf_sock *(*bpf_sk_lookup_udp)(void *ctx,
+					     struct bpf_sock_tuple *tuple,
+					     int size, unsigned int netns_id,
+					     unsigned long long flags) =
+	(void *) BPF_FUNC_sk_lookup_udp;
+static int (*bpf_sk_release)(struct bpf_sock *sk, unsigned long long flags) =
+	(void *) BPF_FUNC_sk_release;
 
 /* llvm builtin functions that eBPF C program may use to
  * emit BPF_LD_ABS and BPF_LD_IND instructions
-- 
2.17.1

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-12  0:36 ` [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF Joe Stringer
@ 2018-09-13  0:06   ` Alexei Starovoitov
  2018-09-14  6:57   ` kbuild test robot
  2018-09-14  7:11   ` kbuild test robot
  2 siblings, 0 replies; 12+ messages in thread
From: Alexei Starovoitov @ 2018-09-13  0:06 UTC (permalink / raw)
  To: Joe Stringer
  Cc: daniel, netdev, ast, john.fastabend, tgraf, kafai, nitin.hande,
	mauricio.vasquez

On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> socket listening on this host, and returns a socket pointer which the
> BPF program can then access to determine, for instance, whether to
> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> socket, so when a BPF program makes use of this function, it must
> subsequently pass the returned pointer into the newly added sk_release()
> to return the reference.
> 
> By way of example, the following pseudocode would filter inbound
> connections at XDP if there is no corresponding service listening for
> the traffic:
> 
>   struct bpf_sock_tuple tuple;
>   struct bpf_sock_ops *sk;
> 
>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
...
> +struct bpf_sock_tuple {
> +	union {
> +		__be32 ipv6[4];
> +		__be32 ipv4;
> +	} saddr;
> +	union {
> +		__be32 ipv6[4];
> +		__be32 ipv4;
> +	} daddr;
> +	__be16 sport;
> +	__be16 dport;
> +	__u8 family;
> +};

since we can pass ptr_to_packet into map lookup and other helpers now,
can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
then progs wouldn't need to copy bytes from the packet into tuple
to do a lookup.
The rest looks great to me.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
@ 2018-09-13 19:06 Alexei Starovoitov
  2018-09-13 20:55 ` Joe Stringer
  0 siblings, 1 reply; 12+ messages in thread
From: Alexei Starovoitov @ 2018-09-13 19:06 UTC (permalink / raw)
  To: Joe Stringer
  Cc: Daniel Borkmann, Network Development, Alexei Starovoitov,
	John Fastabend, Thomas Graf, Martin KaFai Lau, Nitin Hande,
	Mauricio Vasquez

On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
> On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
>> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
>> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
>> socket listening on this host, and returns a socket pointer which the
>> BPF program can then access to determine, for instance, whether to
>> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
>> socket, so when a BPF program makes use of this function, it must
>> subsequently pass the returned pointer into the newly added sk_release()
>> to return the reference.
>>
>> By way of example, the following pseudocode would filter inbound
>> connections at XDP if there is no corresponding service listening for
>> the traffic:
>>
>>   struct bpf_sock_tuple tuple;
>>   struct bpf_sock_ops *sk;
>>
>>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
>>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> ...
>> +struct bpf_sock_tuple {
>> +     union {
>> +             __be32 ipv6[4];
>> +             __be32 ipv4;
>> +     } saddr;
>> +     union {
>> +             __be32 ipv6[4];
>> +             __be32 ipv4;
>> +     } daddr;
>> +     __be16 sport;
>> +     __be16 dport;
>> +     __u8 family;
>> +};
>
> since we can pass ptr_to_packet into map lookup and other helpers now,
> can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> then progs wouldn't need to copy bytes from the packet into tuple
> to do a lookup.

have been thinking more about it.
since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
to infer family inside the helper, so it doesn't need to be passed explicitly?

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 19:06 [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF Alexei Starovoitov
@ 2018-09-13 20:55 ` Joe Stringer
  2018-09-13 20:57   ` Joe Stringer
  2018-09-13 21:01   ` Alexei Starovoitov
  0 siblings, 2 replies; 12+ messages in thread
From: Joe Stringer @ 2018-09-13 20:55 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Joe Stringer, daniel, netdev, ast, john fastabend, tgraf,
	Martin KaFai Lau, Nitin Hande, mauricio.vasquez

On Thu, 13 Sep 2018 at 12:06, Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> > On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> >> socket listening on this host, and returns a socket pointer which the
> >> BPF program can then access to determine, for instance, whether to
> >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> >> socket, so when a BPF program makes use of this function, it must
> >> subsequently pass the returned pointer into the newly added sk_release()
> >> to return the reference.
> >>
> >> By way of example, the following pseudocode would filter inbound
> >> connections at XDP if there is no corresponding service listening for
> >> the traffic:
> >>
> >>   struct bpf_sock_tuple tuple;
> >>   struct bpf_sock_ops *sk;
> >>
> >>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> >>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > ...
> >> +struct bpf_sock_tuple {
> >> +     union {
> >> +             __be32 ipv6[4];
> >> +             __be32 ipv4;
> >> +     } saddr;
> >> +     union {
> >> +             __be32 ipv6[4];
> >> +             __be32 ipv4;
> >> +     } daddr;
> >> +     __be16 sport;
> >> +     __be16 dport;
> >> +     __u8 family;
> >> +};
> >
> > since we can pass ptr_to_packet into map lookup and other helpers now,
> > can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> > then progs wouldn't need to copy bytes from the packet into tuple
> > to do a lookup.

If I follow, you're proposing that users should be able to pass a
pointer to the source address field of the L3 header, and assuming
that the L3 header ends with saddr+daddr (no options/extheaders), and
is immediately followed by the sport/dport then a packet pointer
should work for performing socket lookup. Then it is up to the BPF
program writer to ensure that this is the case, or otherwise fall back
to populating a copy of the sock tuple on the stack.

> have been thinking more about it.
> since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
> to infer family inside the helper, so it doesn't need to be passed explicitly?

Let me make sure I understand the proposal here.

The current structure and function prototypes are:

struct bpf_sock_tuple {
      union {
              __be32 ipv6[4];
              __be32 ipv4;
      } saddr;
      union {
              __be32 ipv6[4];
              __be32 ipv4;
      } daddr;
      __be16 sport;
      __be16 dport;
      __u8 family;
};

static struct bpf_sock *(*bpf_sk_lookup_tcp)(void *ctx,
                                           struct bpf_sock_tuple *tuple,
                                           int size, unsigned int netns_id,
                                           unsigned long long flags);
static struct bpf_sock *(*bpf_sk_lookup_udp)(void *ctx,
                                           struct bpf_sock_tuple *tuple,
                                           int size, unsigned int netns_id,
                                           unsigned long long flags);
static int (*bpf_sk_release)(struct bpf_sock *sk, unsigned long long flags);

You're proposing something like:

struct bpf_sock_tuple4 {
      __be32 saddr;
      __be32 daddr;
      __be16 sport;
      __be16 dport;
      __u8 family;
};

struct bpf_sock_tuple6 {
      __be32 saddr[4];
      __be32 daddr[4];
      __be16 sport;
      __be16 dport;
      __u8 family;
};

static struct bpf_sock *(*bpf_sk_lookup_tcp)(void *ctx,
                                           void *tuple,
                                           int size, unsigned int
netns_id,
                                           unsigned long long flags);
static struct bpf_sock *(*bpf_sk_lookup_udp)(void *ctx,
                                           void *tuple,
                                           int size, unsigned int netns_id,
                                           unsigned long long flags);
static int (*bpf_sk_release)(struct bpf_sock *sk, unsigned long long flags);

Then the implementation will check the size against either
"sizeof(struct bpf_sock_tuple4)" or "sizeof(struct bpf_sock_tuple6)"
and interpret as the v4 or v6 handler from this.

Sure, I can try this out.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 20:55 ` Joe Stringer
@ 2018-09-13 20:57   ` Joe Stringer
  2018-09-13 21:01   ` Alexei Starovoitov
  1 sibling, 0 replies; 12+ messages in thread
From: Joe Stringer @ 2018-09-13 20:57 UTC (permalink / raw)
  To: Joe Stringer
  Cc: Alexei Starovoitov, daniel, netdev, ast, john fastabend, tgraf,
	Martin KaFai Lau, Nitin Hande, mauricio.vasquez

On Thu, 13 Sep 2018 at 13:55, Joe Stringer <joe@wand.net.nz> wrote:
> struct bpf_sock_tuple4 {
>       __be32 saddr;
>       __be32 daddr;
>       __be16 sport;
>       __be16 dport;
>       __u8 family;
> };
>
> struct bpf_sock_tuple6 {
>       __be32 saddr[4];
>       __be32 daddr[4];
>       __be16 sport;
>       __be16 dport;
>       __u8 family;
> };

(ignore the family bit here, I forgot to remove it..)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 20:55 ` Joe Stringer
  2018-09-13 20:57   ` Joe Stringer
@ 2018-09-13 21:01   ` Alexei Starovoitov
  2018-09-13 21:17     ` Joe Stringer
  1 sibling, 1 reply; 12+ messages in thread
From: Alexei Starovoitov @ 2018-09-13 21:01 UTC (permalink / raw)
  To: Joe Stringer
  Cc: daniel, netdev, ast, john fastabend, tgraf, Martin KaFai Lau,
	Nitin Hande, mauricio.vasquez

On Thu, Sep 13, 2018 at 01:55:01PM -0700, Joe Stringer wrote:
> On Thu, 13 Sep 2018 at 12:06, Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > > On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> > >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> > >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> > >> socket listening on this host, and returns a socket pointer which the
> > >> BPF program can then access to determine, for instance, whether to
> > >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> > >> socket, so when a BPF program makes use of this function, it must
> > >> subsequently pass the returned pointer into the newly added sk_release()
> > >> to return the reference.
> > >>
> > >> By way of example, the following pseudocode would filter inbound
> > >> connections at XDP if there is no corresponding service listening for
> > >> the traffic:
> > >>
> > >>   struct bpf_sock_tuple tuple;
> > >>   struct bpf_sock_ops *sk;
> > >>
> > >>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> > >>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > > ...
> > >> +struct bpf_sock_tuple {
> > >> +     union {
> > >> +             __be32 ipv6[4];
> > >> +             __be32 ipv4;
> > >> +     } saddr;
> > >> +     union {
> > >> +             __be32 ipv6[4];
> > >> +             __be32 ipv4;
> > >> +     } daddr;
> > >> +     __be16 sport;
> > >> +     __be16 dport;
> > >> +     __u8 family;
> > >> +};
> > >
> > > since we can pass ptr_to_packet into map lookup and other helpers now,
> > > can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> > > then progs wouldn't need to copy bytes from the packet into tuple
> > > to do a lookup.
> 
> If I follow, you're proposing that users should be able to pass a
> pointer to the source address field of the L3 header, and assuming
> that the L3 header ends with saddr+daddr (no options/extheaders), and
> is immediately followed by the sport/dport then a packet pointer
> should work for performing socket lookup. Then it is up to the BPF
> program writer to ensure that this is the case, or otherwise fall back
> to populating a copy of the sock tuple on the stack.

yep.

> > have been thinking more about it.
> > since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
> > to infer family inside the helper, so it doesn't need to be passed explicitly?
> 
> Let me make sure I understand the proposal here.
> 
> The current structure and function prototypes are:
> 
> struct bpf_sock_tuple {
>       union {
>               __be32 ipv6[4];
>               __be32 ipv4;
>       } saddr;
>       union {
>               __be32 ipv6[4];
>               __be32 ipv4;
>       } daddr;
>       __be16 sport;
>       __be16 dport;
>       __u8 family;
> };
...
> You're proposing something like:
> 
> struct bpf_sock_tuple4 {
>       __be32 saddr;
>       __be32 daddr;
>       __be16 sport;
>       __be16 dport;
>       __u8 family;
> };
> 
> struct bpf_sock_tuple6 {
>       __be32 saddr[4];
>       __be32 daddr[4];
>       __be16 sport;
>       __be16 dport;
>       __u8 family;
> };

I think the split is unnecessary.
I'm proposing:
struct bpf_sock_tuple {
      union {
              __be32 ipv6[4];
              __be32 ipv4;
      } saddr;
      union {
              __be32 ipv6[4];
              __be32 ipv4;
      } daddr;
      __be16 sport;
      __be16 dport;
};

that points directly into the packet (when ipv4 options are not there)
and bpf_sk_lookup_tcp() uses 'size' argument to figure out ipv4/ipv6 family.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 21:01   ` Alexei Starovoitov
@ 2018-09-13 21:17     ` Joe Stringer
  2018-09-13 21:22       ` Alexei Starovoitov
  0 siblings, 1 reply; 12+ messages in thread
From: Joe Stringer @ 2018-09-13 21:17 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Joe Stringer, daniel, netdev, ast, john fastabend, tgraf,
	Martin KaFai Lau, Nitin Hande, mauricio.vasquez

On Thu, 13 Sep 2018 at 14:02, Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Thu, Sep 13, 2018 at 01:55:01PM -0700, Joe Stringer wrote:
> > On Thu, 13 Sep 2018 at 12:06, Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
> > > <alexei.starovoitov@gmail.com> wrote:
> > > > On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> > > >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> > > >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> > > >> socket listening on this host, and returns a socket pointer which the
> > > >> BPF program can then access to determine, for instance, whether to
> > > >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> > > >> socket, so when a BPF program makes use of this function, it must
> > > >> subsequently pass the returned pointer into the newly added sk_release()
> > > >> to return the reference.
> > > >>
> > > >> By way of example, the following pseudocode would filter inbound
> > > >> connections at XDP if there is no corresponding service listening for
> > > >> the traffic:
> > > >>
> > > >>   struct bpf_sock_tuple tuple;
> > > >>   struct bpf_sock_ops *sk;
> > > >>
> > > >>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> > > >>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > > > ...
> > > >> +struct bpf_sock_tuple {
> > > >> +     union {
> > > >> +             __be32 ipv6[4];
> > > >> +             __be32 ipv4;
> > > >> +     } saddr;
> > > >> +     union {
> > > >> +             __be32 ipv6[4];
> > > >> +             __be32 ipv4;
> > > >> +     } daddr;
> > > >> +     __be16 sport;
> > > >> +     __be16 dport;
> > > >> +     __u8 family;
> > > >> +};
> > > >
> > > > since we can pass ptr_to_packet into map lookup and other helpers now,
> > > > can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> > > > then progs wouldn't need to copy bytes from the packet into tuple
> > > > to do a lookup.
> >
> > If I follow, you're proposing that users should be able to pass a
> > pointer to the source address field of the L3 header, and assuming
> > that the L3 header ends with saddr+daddr (no options/extheaders), and
> > is immediately followed by the sport/dport then a packet pointer
> > should work for performing socket lookup. Then it is up to the BPF
> > program writer to ensure that this is the case, or otherwise fall back
> > to populating a copy of the sock tuple on the stack.
>
> yep.
>
> > > have been thinking more about it.
> > > since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
> > > to infer family inside the helper, so it doesn't need to be passed explicitly?
> >
> > Let me make sure I understand the proposal here.
> >
> > The current structure and function prototypes are:
> >
> > struct bpf_sock_tuple {
> >       union {
> >               __be32 ipv6[4];
> >               __be32 ipv4;
> >       } saddr;
> >       union {
> >               __be32 ipv6[4];
> >               __be32 ipv4;
> >       } daddr;
> >       __be16 sport;
> >       __be16 dport;
> >       __u8 family;
> > };
> ...
> > You're proposing something like:
> >
> > struct bpf_sock_tuple4 {
> >       __be32 saddr;
> >       __be32 daddr;
> >       __be16 sport;
> >       __be16 dport;
> >       __u8 family;
> > };
> >
> > struct bpf_sock_tuple6 {
> >       __be32 saddr[4];
> >       __be32 daddr[4];
> >       __be16 sport;
> >       __be16 dport;
> >       __u8 family;
> > };
>
> I think the split is unnecessary.
> I'm proposing:
> struct bpf_sock_tuple {
>       union {
>               __be32 ipv6[4];
>               __be32 ipv4;
>       } saddr;
>       union {
>               __be32 ipv6[4];
>               __be32 ipv4;
>       } daddr;
>       __be16 sport;
>       __be16 dport;
> };
>
> that points directly into the packet (when ipv4 options are not there)
> and bpf_sk_lookup_tcp() uses 'size' argument to figure out ipv4/ipv6 family.

Needs to be subtly different, the 'sport'/'dport' offset would be
wrong in the IPv4 case otherwise:

$ cat foo.c
#include <linux/types.h>

struct bpf_sock_tuple {
     union {
             __be32 ipv6[4];
             __be32 ipv4;
     } saddr;
     union {
             __be32 ipv6[4];
             __be32 ipv4;
     } daddr;
     __be16 sport;
     __be16 dport;
};

int main(int argc, char *argv[]) {
       struct bpf_sock_tuple tuple;

       return 0;
}
$ gcc -g ./foo.c -o foo.o
$ pahole foo.o
struct bpf_sock_tuple {
       union {
               __be32             ipv6[4];              /*          16 */
               __be32             ipv4;                 /*           4 */
       } saddr;                                         /*     0    16 */
       union {
               __be32             ipv6[4];              /*          16 */
               __be32             ipv4;                 /*           4 */
       } daddr;                                         /*    16    16 */
       __be16                     sport;                /*    32     2 */
       __be16                     dport;                /*    34     2 */

       /* size: 36, cachelines: 1, members: 4 */
       /* last cacheline: 36 bytes */
};

---

We could take my definitions above and do the following if we want to
try to type the helper definition:

union bpf_sock_tuple {
       struct bpf_sock_tuple4 t4;
       struct bpf_sock_tuple6 t6;
};

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 21:17     ` Joe Stringer
@ 2018-09-13 21:22       ` Alexei Starovoitov
  2018-09-13 21:24         ` Joe Stringer
  0 siblings, 1 reply; 12+ messages in thread
From: Alexei Starovoitov @ 2018-09-13 21:22 UTC (permalink / raw)
  To: Joe Stringer
  Cc: daniel, netdev, ast, john fastabend, tgraf, Martin KaFai Lau,
	Nitin Hande, mauricio.vasquez

On Thu, Sep 13, 2018 at 02:17:17PM -0700, Joe Stringer wrote:
> On Thu, 13 Sep 2018 at 14:02, Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Thu, Sep 13, 2018 at 01:55:01PM -0700, Joe Stringer wrote:
> > > On Thu, 13 Sep 2018 at 12:06, Alexei Starovoitov
> > > <alexei.starovoitov@gmail.com> wrote:
> > > >
> > > > On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
> > > > <alexei.starovoitov@gmail.com> wrote:
> > > > > On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> > > > >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> > > > >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> > > > >> socket listening on this host, and returns a socket pointer which the
> > > > >> BPF program can then access to determine, for instance, whether to
> > > > >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> > > > >> socket, so when a BPF program makes use of this function, it must
> > > > >> subsequently pass the returned pointer into the newly added sk_release()
> > > > >> to return the reference.
> > > > >>
> > > > >> By way of example, the following pseudocode would filter inbound
> > > > >> connections at XDP if there is no corresponding service listening for
> > > > >> the traffic:
> > > > >>
> > > > >>   struct bpf_sock_tuple tuple;
> > > > >>   struct bpf_sock_ops *sk;
> > > > >>
> > > > >>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> > > > >>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > > > > ...
> > > > >> +struct bpf_sock_tuple {
> > > > >> +     union {
> > > > >> +             __be32 ipv6[4];
> > > > >> +             __be32 ipv4;
> > > > >> +     } saddr;
> > > > >> +     union {
> > > > >> +             __be32 ipv6[4];
> > > > >> +             __be32 ipv4;
> > > > >> +     } daddr;
> > > > >> +     __be16 sport;
> > > > >> +     __be16 dport;
> > > > >> +     __u8 family;
> > > > >> +};
> > > > >
> > > > > since we can pass ptr_to_packet into map lookup and other helpers now,
> > > > > can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> > > > > then progs wouldn't need to copy bytes from the packet into tuple
> > > > > to do a lookup.
> > >
> > > If I follow, you're proposing that users should be able to pass a
> > > pointer to the source address field of the L3 header, and assuming
> > > that the L3 header ends with saddr+daddr (no options/extheaders), and
> > > is immediately followed by the sport/dport then a packet pointer
> > > should work for performing socket lookup. Then it is up to the BPF
> > > program writer to ensure that this is the case, or otherwise fall back
> > > to populating a copy of the sock tuple on the stack.
> >
> > yep.
> >
> > > > have been thinking more about it.
> > > > since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
> > > > to infer family inside the helper, so it doesn't need to be passed explicitly?
> > >
> > > Let me make sure I understand the proposal here.
> > >
> > > The current structure and function prototypes are:
> > >
> > > struct bpf_sock_tuple {
> > >       union {
> > >               __be32 ipv6[4];
> > >               __be32 ipv4;
> > >       } saddr;
> > >       union {
> > >               __be32 ipv6[4];
> > >               __be32 ipv4;
> > >       } daddr;
> > >       __be16 sport;
> > >       __be16 dport;
> > >       __u8 family;
> > > };
> > ...
> > > You're proposing something like:
> > >
> > > struct bpf_sock_tuple4 {
> > >       __be32 saddr;
> > >       __be32 daddr;
> > >       __be16 sport;
> > >       __be16 dport;
> > >       __u8 family;
> > > };
> > >
> > > struct bpf_sock_tuple6 {
> > >       __be32 saddr[4];
> > >       __be32 daddr[4];
> > >       __be16 sport;
> > >       __be16 dport;
> > >       __u8 family;
> > > };
> >
> > I think the split is unnecessary.
> > I'm proposing:
> > struct bpf_sock_tuple {
> >       union {
> >               __be32 ipv6[4];
> >               __be32 ipv4;
> >       } saddr;
> >       union {
> >               __be32 ipv6[4];
> >               __be32 ipv4;
> >       } daddr;
> >       __be16 sport;
> >       __be16 dport;
> > };
> >
> > that points directly into the packet (when ipv4 options are not there)
> > and bpf_sk_lookup_tcp() uses 'size' argument to figure out ipv4/ipv6 family.
> 
> Needs to be subtly different, the 'sport'/'dport' offset would be
> wrong in the IPv4 case otherwise:

ahh. right.

> 
> We could take my definitions above and do the following if we want to
> try to type the helper definition:
> 
> union bpf_sock_tuple {
>        struct bpf_sock_tuple4 t4;
>        struct bpf_sock_tuple6 t6;
> };

yes. sounds great to me. Much better than 'void *' in the helper.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 21:22       ` Alexei Starovoitov
@ 2018-09-13 21:24         ` Joe Stringer
  2018-09-13 22:23           ` Alexei Starovoitov
  0 siblings, 1 reply; 12+ messages in thread
From: Joe Stringer @ 2018-09-13 21:24 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: Joe Stringer, daniel, netdev, ast, john fastabend, tgraf,
	Martin KaFai Lau, Nitin Hande, mauricio.vasquez

On Thu, 13 Sep 2018 at 14:22, Alexei Starovoitov
<alexei.starovoitov@gmail.com> wrote:
>
> On Thu, Sep 13, 2018 at 02:17:17PM -0700, Joe Stringer wrote:
> > On Thu, 13 Sep 2018 at 14:02, Alexei Starovoitov
> > <alexei.starovoitov@gmail.com> wrote:
> > >
> > > On Thu, Sep 13, 2018 at 01:55:01PM -0700, Joe Stringer wrote:
> > > > On Thu, 13 Sep 2018 at 12:06, Alexei Starovoitov
> > > > <alexei.starovoitov@gmail.com> wrote:
> > > > >
> > > > > On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
> > > > > <alexei.starovoitov@gmail.com> wrote:
> > > > > > On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> > > > > >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> > > > > >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> > > > > >> socket listening on this host, and returns a socket pointer which the
> > > > > >> BPF program can then access to determine, for instance, whether to
> > > > > >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> > > > > >> socket, so when a BPF program makes use of this function, it must
> > > > > >> subsequently pass the returned pointer into the newly added sk_release()
> > > > > >> to return the reference.
> > > > > >>
> > > > > >> By way of example, the following pseudocode would filter inbound
> > > > > >> connections at XDP if there is no corresponding service listening for
> > > > > >> the traffic:
> > > > > >>
> > > > > >>   struct bpf_sock_tuple tuple;
> > > > > >>   struct bpf_sock_ops *sk;
> > > > > >>
> > > > > >>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> > > > > >>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > > > > > ...
> > > > > >> +struct bpf_sock_tuple {
> > > > > >> +     union {
> > > > > >> +             __be32 ipv6[4];
> > > > > >> +             __be32 ipv4;
> > > > > >> +     } saddr;
> > > > > >> +     union {
> > > > > >> +             __be32 ipv6[4];
> > > > > >> +             __be32 ipv4;
> > > > > >> +     } daddr;
> > > > > >> +     __be16 sport;
> > > > > >> +     __be16 dport;
> > > > > >> +     __u8 family;
> > > > > >> +};
> > > > > >
> > > > > > since we can pass ptr_to_packet into map lookup and other helpers now,
> > > > > > can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> > > > > > then progs wouldn't need to copy bytes from the packet into tuple
> > > > > > to do a lookup.
> > > >
> > > > If I follow, you're proposing that users should be able to pass a
> > > > pointer to the source address field of the L3 header, and assuming
> > > > that the L3 header ends with saddr+daddr (no options/extheaders), and
> > > > is immediately followed by the sport/dport then a packet pointer
> > > > should work for performing socket lookup. Then it is up to the BPF
> > > > program writer to ensure that this is the case, or otherwise fall back
> > > > to populating a copy of the sock tuple on the stack.
> > >
> > > yep.
> > >
> > > > > have been thinking more about it.
> > > > > since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
> > > > > to infer family inside the helper, so it doesn't need to be passed explicitly?
> > > >
> > > > Let me make sure I understand the proposal here.
> > > >
> > > > The current structure and function prototypes are:
> > > >
> > > > struct bpf_sock_tuple {
> > > >       union {
> > > >               __be32 ipv6[4];
> > > >               __be32 ipv4;
> > > >       } saddr;
> > > >       union {
> > > >               __be32 ipv6[4];
> > > >               __be32 ipv4;
> > > >       } daddr;
> > > >       __be16 sport;
> > > >       __be16 dport;
> > > >       __u8 family;
> > > > };
> > > ...
> > > > You're proposing something like:
> > > >
> > > > struct bpf_sock_tuple4 {
> > > >       __be32 saddr;
> > > >       __be32 daddr;
> > > >       __be16 sport;
> > > >       __be16 dport;
> > > >       __u8 family;
> > > > };
> > > >
> > > > struct bpf_sock_tuple6 {
> > > >       __be32 saddr[4];
> > > >       __be32 daddr[4];
> > > >       __be16 sport;
> > > >       __be16 dport;
> > > >       __u8 family;
> > > > };
> > >
> > > I think the split is unnecessary.
> > > I'm proposing:
> > > struct bpf_sock_tuple {
> > >       union {
> > >               __be32 ipv6[4];
> > >               __be32 ipv4;
> > >       } saddr;
> > >       union {
> > >               __be32 ipv6[4];
> > >               __be32 ipv4;
> > >       } daddr;
> > >       __be16 sport;
> > >       __be16 dport;
> > > };
> > >
> > > that points directly into the packet (when ipv4 options are not there)
> > > and bpf_sk_lookup_tcp() uses 'size' argument to figure out ipv4/ipv6 family.
> >
> > Needs to be subtly different, the 'sport'/'dport' offset would be
> > wrong in the IPv4 case otherwise:
>
> ahh. right.
>
> >
> > We could take my definitions above and do the following if we want to
> > try to type the helper definition:
> >
> > union bpf_sock_tuple {
> >        struct bpf_sock_tuple4 t4;
> >        struct bpf_sock_tuple6 t6;
> > };
>
> yes. sounds great to me. Much better than 'void *' in the helper.

Could even do something like this:

$ cat foo.c
#include <linux/types.h>

struct bpf_sock_tuple {
   union {
   struct {
       __be32 saddr;
       __be32 daddr;
       __be16 sport;
       __be16 dport;
   } ipv4;
   struct {
       __be32 saddr[4];
       __be32 daddr[4];
       __be16 sport;
       __be16 dport;
   } ipv6;
   };
};

int main(int argc, char *argv[]) {
       struct bpf_sock_tuple tuple;

       return 0;
}
$ gcc -g ./foo.c -o foo.o
$ pahole foo.o
struct bpf_sock_tuple {
       union {
               struct {
                       __be32     saddr;                /*     0     4 */
                       __be32     daddr;                /*     4     4 */
                       __be16     sport;                /*     8     2 */
                       __be16     dport;                /*    10     2 */
               } ipv4;                                  /*          12 */
               struct {
                       __be32     saddr[4];             /*     0    16 */
                       __be32     daddr[4];             /*    16    16 */
                       __be16     sport;                /*    32     2 */
                       __be16     dport;                /*    34     2 */
               } ipv6;                                  /*          36 */
       };                                               /*     0    36 */

       /* size: 36, cachelines: 1, members: 1 */
       /* last cacheline: 36 bytes */
};

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-13 21:24         ` Joe Stringer
@ 2018-09-13 22:23           ` Alexei Starovoitov
  0 siblings, 0 replies; 12+ messages in thread
From: Alexei Starovoitov @ 2018-09-13 22:23 UTC (permalink / raw)
  To: Joe Stringer
  Cc: daniel, netdev, ast, john fastabend, tgraf, Martin KaFai Lau,
	Nitin Hande, mauricio.vasquez

On Thu, Sep 13, 2018 at 02:24:03PM -0700, Joe Stringer wrote:
> On Thu, 13 Sep 2018 at 14:22, Alexei Starovoitov
> <alexei.starovoitov@gmail.com> wrote:
> >
> > On Thu, Sep 13, 2018 at 02:17:17PM -0700, Joe Stringer wrote:
> > > On Thu, 13 Sep 2018 at 14:02, Alexei Starovoitov
> > > <alexei.starovoitov@gmail.com> wrote:
> > > >
> > > > On Thu, Sep 13, 2018 at 01:55:01PM -0700, Joe Stringer wrote:
> > > > > On Thu, 13 Sep 2018 at 12:06, Alexei Starovoitov
> > > > > <alexei.starovoitov@gmail.com> wrote:
> > > > > >
> > > > > > On Wed, Sep 12, 2018 at 5:06 PM, Alexei Starovoitov
> > > > > > <alexei.starovoitov@gmail.com> wrote:
> > > > > > > On Tue, Sep 11, 2018 at 05:36:36PM -0700, Joe Stringer wrote:
> > > > > > >> This patch adds new BPF helper functions, bpf_sk_lookup_tcp() and
> > > > > > >> bpf_sk_lookup_udp() which allows BPF programs to find out if there is a
> > > > > > >> socket listening on this host, and returns a socket pointer which the
> > > > > > >> BPF program can then access to determine, for instance, whether to
> > > > > > >> forward or drop traffic. bpf_sk_lookup_xxx() may take a reference on the
> > > > > > >> socket, so when a BPF program makes use of this function, it must
> > > > > > >> subsequently pass the returned pointer into the newly added sk_release()
> > > > > > >> to return the reference.
> > > > > > >>
> > > > > > >> By way of example, the following pseudocode would filter inbound
> > > > > > >> connections at XDP if there is no corresponding service listening for
> > > > > > >> the traffic:
> > > > > > >>
> > > > > > >>   struct bpf_sock_tuple tuple;
> > > > > > >>   struct bpf_sock_ops *sk;
> > > > > > >>
> > > > > > >>   populate_tuple(ctx, &tuple); // Extract the 5tuple from the packet
> > > > > > >>   sk = bpf_sk_lookup_tcp(ctx, &tuple, sizeof tuple, netns, 0);
> > > > > > > ...
> > > > > > >> +struct bpf_sock_tuple {
> > > > > > >> +     union {
> > > > > > >> +             __be32 ipv6[4];
> > > > > > >> +             __be32 ipv4;
> > > > > > >> +     } saddr;
> > > > > > >> +     union {
> > > > > > >> +             __be32 ipv6[4];
> > > > > > >> +             __be32 ipv4;
> > > > > > >> +     } daddr;
> > > > > > >> +     __be16 sport;
> > > > > > >> +     __be16 dport;
> > > > > > >> +     __u8 family;
> > > > > > >> +};
> > > > > > >
> > > > > > > since we can pass ptr_to_packet into map lookup and other helpers now,
> > > > > > > can you move 'family' out of bpf_sock_tuple and combine with netns_id arg?
> > > > > > > then progs wouldn't need to copy bytes from the packet into tuple
> > > > > > > to do a lookup.
> > > > >
> > > > > If I follow, you're proposing that users should be able to pass a
> > > > > pointer to the source address field of the L3 header, and assuming
> > > > > that the L3 header ends with saddr+daddr (no options/extheaders), and
> > > > > is immediately followed by the sport/dport then a packet pointer
> > > > > should work for performing socket lookup. Then it is up to the BPF
> > > > > program writer to ensure that this is the case, or otherwise fall back
> > > > > to populating a copy of the sock tuple on the stack.
> > > >
> > > > yep.
> > > >
> > > > > > have been thinking more about it.
> > > > > > since only ipv4 and ipv6 supported may be use size of bpf_sock_tuple
> > > > > > to infer family inside the helper, so it doesn't need to be passed explicitly?
> > > > >
> > > > > Let me make sure I understand the proposal here.
> > > > >
> > > > > The current structure and function prototypes are:
> > > > >
> > > > > struct bpf_sock_tuple {
> > > > >       union {
> > > > >               __be32 ipv6[4];
> > > > >               __be32 ipv4;
> > > > >       } saddr;
> > > > >       union {
> > > > >               __be32 ipv6[4];
> > > > >               __be32 ipv4;
> > > > >       } daddr;
> > > > >       __be16 sport;
> > > > >       __be16 dport;
> > > > >       __u8 family;
> > > > > };
> > > > ...
> > > > > You're proposing something like:
> > > > >
> > > > > struct bpf_sock_tuple4 {
> > > > >       __be32 saddr;
> > > > >       __be32 daddr;
> > > > >       __be16 sport;
> > > > >       __be16 dport;
> > > > >       __u8 family;
> > > > > };
> > > > >
> > > > > struct bpf_sock_tuple6 {
> > > > >       __be32 saddr[4];
> > > > >       __be32 daddr[4];
> > > > >       __be16 sport;
> > > > >       __be16 dport;
> > > > >       __u8 family;
> > > > > };
> > > >
> > > > I think the split is unnecessary.
> > > > I'm proposing:
> > > > struct bpf_sock_tuple {
> > > >       union {
> > > >               __be32 ipv6[4];
> > > >               __be32 ipv4;
> > > >       } saddr;
> > > >       union {
> > > >               __be32 ipv6[4];
> > > >               __be32 ipv4;
> > > >       } daddr;
> > > >       __be16 sport;
> > > >       __be16 dport;
> > > > };
> > > >
> > > > that points directly into the packet (when ipv4 options are not there)
> > > > and bpf_sk_lookup_tcp() uses 'size' argument to figure out ipv4/ipv6 family.
> > >
> > > Needs to be subtly different, the 'sport'/'dport' offset would be
> > > wrong in the IPv4 case otherwise:
> >
> > ahh. right.
> >
> > >
> > > We could take my definitions above and do the following if we want to
> > > try to type the helper definition:
> > >
> > > union bpf_sock_tuple {
> > >        struct bpf_sock_tuple4 t4;
> > >        struct bpf_sock_tuple6 t6;
> > > };
> >
> > yes. sounds great to me. Much better than 'void *' in the helper.
> 
> Could even do something like this:
> 
> $ cat foo.c
> #include <linux/types.h>
> 
> struct bpf_sock_tuple {
>    union {
>    struct {
>        __be32 saddr;
>        __be32 daddr;
>        __be16 sport;
>        __be16 dport;
>    } ipv4;
>    struct {
>        __be32 saddr[4];
>        __be32 daddr[4];
>        __be16 sport;
>        __be16 dport;
>    } ipv6;
>    };
> };

both solutions look fine.
I'd go with whichever one is cleaner looking from bpf prog pov.
Both probably need some casting of skb->data pointer.

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-12  0:36 ` [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF Joe Stringer
  2018-09-13  0:06   ` Alexei Starovoitov
@ 2018-09-14  6:57   ` kbuild test robot
  2018-09-14  7:11   ` kbuild test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2018-09-14  6:57 UTC (permalink / raw)
  To: Joe Stringer
  Cc: kbuild-all, daniel, netdev, ast, john.fastabend, tgraf, kafai,
	nitin.hande, mauricio.vasquez

[-- Attachment #1: Type: text/plain, Size: 19595 bytes --]

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/0day-ci/linux/commits/Joe-Stringer/Add-socket-lookup-support/20180914-134632
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: xtensa-common_defconfig (attached as .config)
compiler: xtensa-linux-gcc (GCC) 8.1.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.1.0 make.cross ARCH=xtensa 

All errors (new ones prefixed by >>):

   net/core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net/core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____bpf_sk_release'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^~~~
   include/linux/filter.h:443:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net/core/filter.c:4941:11: error: initializer element is not constant
     .func  = bpf_sk_release,
              ^~~~~~~~~~~~~~
   net/core/filter.c:4941:11: note: (near initialization for 'bpf_sk_release_proto.func')
   net/core/filter.c:4980:1: error: invalid storage class for function 'bpf_base_func_proto'
    bpf_base_func_proto(enum bpf_func_id func_id)
    ^~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5009:1: error: invalid storage class for function 'sock_filter_func_proto'
    sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5025:1: error: invalid storage class for function 'sock_addr_func_proto'
    sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5051:1: error: invalid storage class for function 'sk_filter_func_proto'
    sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5068:1: error: invalid storage class for function 'cg_skb_func_proto'
    cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net/core/filter.c:5079:1: error: invalid storage class for function 'tc_cls_act_func_proto'
    tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5166:1: error: invalid storage class for function 'xdp_func_proto'
    xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~
   net/core/filter.c:5193:1: error: invalid storage class for function 'sock_ops_func_proto'
    sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5216:1: error: invalid storage class for function 'sk_msg_func_proto'
    sk_msg_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net/core/filter.c:5237:1: error: invalid storage class for function 'sk_skb_func_proto'
    sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net/core/filter.c:5272:1: error: invalid storage class for function 'lwt_out_func_proto'
    lwt_out_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~
   net/core/filter.c:5299:1: error: invalid storage class for function 'lwt_in_func_proto'
    lwt_in_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net/core/filter.c:5310:1: error: invalid storage class for function 'lwt_xmit_func_proto'
    lwt_xmit_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5345:1: error: invalid storage class for function 'lwt_seg6local_func_proto'
    lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5361:13: error: invalid storage class for function 'bpf_skb_is_valid_access'
    static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type,
                ^~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5404:13: error: invalid storage class for function 'sk_filter_is_valid_access'
    static bool sk_filter_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5430:13: error: invalid storage class for function 'lwt_is_valid_access'
    static bool lwt_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5466:13: error: invalid storage class for function '__sock_filter_check_attach_type'
    static bool __sock_filter_check_attach_type(int off,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5509:13: error: invalid storage class for function '__sock_filter_check_size'
    static bool __sock_filter_check_size(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5536:13: error: invalid storage class for function 'sock_filter_is_valid_access'
    static bool sock_filter_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5547:12: error: invalid storage class for function 'bpf_unclone_prologue'
    static int bpf_unclone_prologue(struct bpf_insn *insn_buf, bool direct_write,
               ^~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5586:12: error: invalid storage class for function 'bpf_gen_ld_abs'
    static int bpf_gen_ld_abs(const struct bpf_insn *orig,
               ^~~~~~~~~~~~~~
   net/core/filter.c:5621:12: error: invalid storage class for function 'tc_cls_act_prologue'
    static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write,
               ^~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5627:13: error: invalid storage class for function 'tc_cls_act_is_valid_access'
    static bool tc_cls_act_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5662:13: error: invalid storage class for function '__is_valid_xdp_access'
    static bool __is_valid_xdp_access(int off, int size)
                ^~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5674:13: error: invalid storage class for function 'xdp_is_valid_access'
    static bool xdp_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~
   In file included from include/linux/linkage.h:7,
                    from include/linux/kernel.h:7,
                    from include/linux/list.h:9,
                    from include/linux/module.h:9,
                    from net/core/filter.c:24:
>> net/core/filter.c:5712:19: error: non-static declaration of 'bpf_warn_invalid_xdp_action' follows static declaration
    EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   include/linux/export.h:79:21: note: in definition of macro '___EXPORT_SYMBOL'
     extern typeof(sym) sym;      \
                        ^~~
   net/core/filter.c:5712:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
    ^~~~~~~~~~~~~~~~~
   net/core/filter.c:5704:6: note: previous definition of 'bpf_warn_invalid_xdp_action' was here
    void bpf_warn_invalid_xdp_action(u32 act)
         ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5714:13: error: invalid storage class for function 'sock_addr_is_valid_access'
    static bool sock_addr_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5801:13: error: invalid storage class for function 'sock_ops_is_valid_access'
    static bool sock_ops_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5842:12: error: invalid storage class for function 'sk_skb_prologue'
    static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write,
               ^~~~~~~~~~~~~~~
   net/core/filter.c:5848:13: error: invalid storage class for function 'sk_skb_is_valid_access'
    static bool sk_skb_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5883:13: error: invalid storage class for function 'sk_msg_is_valid_access'
    static bool sk_msg_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:5915:12: error: invalid storage class for function 'bpf_convert_ctx_access'
    static u32 bpf_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:6318:12: error: invalid storage class for function 'tc_cls_act_convert_ctx_access'
    static u32 tc_cls_act_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:6342:12: error: invalid storage class for function 'xdp_convert_ctx_access'
    static u32 xdp_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:6462:12: error: invalid storage class for function 'sock_addr_convert_ctx_access'
    static u32 sock_addr_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:6551:12: error: invalid storage class for function 'sock_ops_convert_ctx_access'
    static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:6890:12: error: invalid storage class for function 'sk_skb_convert_ctx_access'
    static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~
   net/core/filter.c:6915:12: error: invalid storage class for function 'sk_msg_convert_ctx_access'
    static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/linux/linkage.h:7,
                    from include/linux/kernel.h:7,
                    from include/linux/list.h:9,
                    from include/linux/module.h:9,
                    from net/core/filter.c:24:
>> net/core/filter.c:7190:19: error: non-static declaration of 'sk_detach_filter' follows static declaration
    EXPORT_SYMBOL_GPL(sk_detach_filter);
                      ^~~~~~~~~~~~~~~~
   include/linux/export.h:79:21: note: in definition of macro '___EXPORT_SYMBOL'
     extern typeof(sym) sym;      \
                        ^~~
   net/core/filter.c:7190:1: note: in expansion of macro 'EXPORT_SYMBOL_GPL'
    EXPORT_SYMBOL_GPL(sk_detach_filter);
    ^~~~~~~~~~~~~~~~~
   net/core/filter.c:7172:5: note: previous definition of 'sk_detach_filter' was here
    int sk_detach_filter(struct sock *sk)
        ^~~~~~~~~~~~~~~~
   net/core/filter.c:7247:13: error: invalid storage class for function 'bpf_init_reuseport_kern'
    static void bpf_init_reuseport_kern(struct sk_reuseport_kern *reuse_kern,
                ^~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/net/sock.h:64,
                    from include/linux/sock_diag.h:8,
                    from net/core/filter.c:29:
   include/linux/filter.h:432:6: error: invalid storage class for function '____sk_select_reuseport'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^~~~
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net/core/filter.c:7277:12: error: static declaration of 'sk_select_reuseport' follows non-static declaration
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
               ^~~~~~~~~~~~~~~~~~~
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net/core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net/core/filter.c:7277:12: note: previous declaration of 'sk_select_reuseport' was here
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
               ^~~~~~~~~~~~~~~~~~~
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net/core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net/core/filter.c: In function 'sk_select_reuseport':
   include/linux/filter.h:436:10: error: implicit declaration of function '____sk_select_reuseport'; did you mean 'sk_select_reuseport'? [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^~~~
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net/core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____sk_select_reuseport'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^~~~
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net/core/filter.c:7323:20: error: initializer element is not constant
     .func           = sk_select_reuseport,
                       ^~~~~~~~~~~~~~~~~~~
   net/core/filter.c:7323:20: note: (near initialization for 'sk_select_reuseport_proto.func')
   In file included from include/net/sock.h:64,
                    from include/linux/sock_diag.h:8,
                    from net/core/filter.c:29:
   include/linux/filter.h:432:6: error: invalid storage class for function '____sk_reuseport_load_bytes'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^~~~
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net/core/filter.c:7332:12: error: static declaration of 'sk_reuseport_load_bytes' follows non-static declaration
    BPF_CALL_4(sk_reuseport_load_bytes,
               ^~~~~~~~~~~~~~~~~~~~~~~
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net/core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net/core/filter.c:7332:12: note: previous declaration of 'sk_reuseport_load_bytes' was here
    BPF_CALL_4(sk_reuseport_load_bytes,
               ^~~~~~~~~~~~~~~~~~~~~~~
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net/core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net/core/filter.c: In function 'sk_reuseport_load_bytes':
   include/linux/filter.h:436:10: error: implicit declaration of function '____sk_reuseport_load_bytes'; did you mean 'sk_reuseport_load_bytes'? [-Werror=implicit-function-declaration]

vim +/bpf_warn_invalid_xdp_action +5712 net/core/filter.c

6a773a15a Brenden Blanco  2016-07-19  5673  
6a773a15a Brenden Blanco  2016-07-19 @5674  static bool xdp_is_valid_access(int off, int size,
6a773a15a Brenden Blanco  2016-07-19  5675  				enum bpf_access_type type,
5e43f899b Andrey Ignatov  2018-03-30  5676  				const struct bpf_prog *prog,
239946314 Yonghong Song   2017-06-22  5677  				struct bpf_insn_access_aux *info)
6a773a15a Brenden Blanco  2016-07-19  5678  {
0d8300325 Jakub Kicinski  2018-05-08  5679  	if (type == BPF_WRITE) {
0d8300325 Jakub Kicinski  2018-05-08  5680  		if (bpf_prog_is_dev_bound(prog->aux)) {
0d8300325 Jakub Kicinski  2018-05-08  5681  			switch (off) {
0d8300325 Jakub Kicinski  2018-05-08  5682  			case offsetof(struct xdp_md, rx_queue_index):
0d8300325 Jakub Kicinski  2018-05-08  5683  				return __is_valid_xdp_access(off, size);
0d8300325 Jakub Kicinski  2018-05-08  5684  			}
0d8300325 Jakub Kicinski  2018-05-08  5685  		}
6a773a15a Brenden Blanco  2016-07-19  5686  		return false;
0d8300325 Jakub Kicinski  2018-05-08  5687  	}
6a773a15a Brenden Blanco  2016-07-19  5688  
6a773a15a Brenden Blanco  2016-07-19  5689  	switch (off) {
6a773a15a Brenden Blanco  2016-07-19  5690  	case offsetof(struct xdp_md, data):
239946314 Yonghong Song   2017-06-22  5691  		info->reg_type = PTR_TO_PACKET;
6a773a15a Brenden Blanco  2016-07-19  5692  		break;
de8f3a83b Daniel Borkmann 2017-09-25  5693  	case offsetof(struct xdp_md, data_meta):
de8f3a83b Daniel Borkmann 2017-09-25  5694  		info->reg_type = PTR_TO_PACKET_META;
de8f3a83b Daniel Borkmann 2017-09-25  5695  		break;
6a773a15a Brenden Blanco  2016-07-19  5696  	case offsetof(struct xdp_md, data_end):
239946314 Yonghong Song   2017-06-22  5697  		info->reg_type = PTR_TO_PACKET_END;
6a773a15a Brenden Blanco  2016-07-19  5698  		break;
6a773a15a Brenden Blanco  2016-07-19  5699  	}
6a773a15a Brenden Blanco  2016-07-19  5700  
1afaf661b Daniel Borkmann 2016-12-04  5701  	return __is_valid_xdp_access(off, size);
6a773a15a Brenden Blanco  2016-07-19  5702  }
6a773a15a Brenden Blanco  2016-07-19  5703  
6a773a15a Brenden Blanco  2016-07-19  5704  void bpf_warn_invalid_xdp_action(u32 act)
6a773a15a Brenden Blanco  2016-07-19  5705  {
9beb8bedb Daniel Borkmann 2017-09-09  5706  	const u32 act_max = XDP_REDIRECT;
9beb8bedb Daniel Borkmann 2017-09-09  5707  
9beb8bedb Daniel Borkmann 2017-09-09  5708  	WARN_ONCE(1, "%s XDP return value %u, expect packet loss!\n",
9beb8bedb Daniel Borkmann 2017-09-09  5709  		  act > act_max ? "Illegal" : "Driver unsupported",
9beb8bedb Daniel Borkmann 2017-09-09  5710  		  act);
6a773a15a Brenden Blanco  2016-07-19  5711  }
6a773a15a Brenden Blanco  2016-07-19 @5712  EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action);
6a773a15a Brenden Blanco  2016-07-19  5713  

:::::: The code at line 5712 was first introduced by commit
:::::: 6a773a15a1e8874e5eccd2f29190c31085912c95 bpf: add XDP prog type for early driver filter

:::::: TO: Brenden Blanco <bblanco@plumgrid.com>
:::::: CC: David S. Miller <davem@davemloft.net>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 10358 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF
  2018-09-12  0:36 ` [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF Joe Stringer
  2018-09-13  0:06   ` Alexei Starovoitov
  2018-09-14  6:57   ` kbuild test robot
@ 2018-09-14  7:11   ` kbuild test robot
  2 siblings, 0 replies; 12+ messages in thread
From: kbuild test robot @ 2018-09-14  7:11 UTC (permalink / raw)
  To: Joe Stringer
  Cc: kbuild-all, daniel, netdev, ast, john.fastabend, tgraf, kafai,
	nitin.hande, mauricio.vasquez

[-- Attachment #1: Type: text/plain, Size: 41175 bytes --]

Hi Joe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on bpf-next/master]

url:    https://github.com/0day-ci/linux/commits/Joe-Stringer/Add-socket-lookup-support/20180914-134632
base:   https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master
config: x86_64-randconfig-s0-09141346 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=x86_64 

All error/warnings (new ones prefixed by >>):

   net/core/filter.c: In function 'sk_lookup':
>> net/core/filter.c:4870:1: error: invalid storage class for function 'bpf_sk_lookup'
    bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
    ^~~~~~~~~~~~~
>> net/core/filter.c:4869:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
    static unsigned long
    ^~~~~~
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net/core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____bpf_sk_lookup_tcp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
>> net/core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
>> net/core/filter.c:4896:12: error: static declaration of 'bpf_sk_lookup_tcp' follows non-static declaration
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
>> net/core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c:4896:12: note: previous declaration of 'bpf_sk_lookup_tcp' was here
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
>> net/core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c: In function 'bpf_sk_lookup_tcp':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____bpf_sk_lookup_tcp' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
>> net/core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____bpf_sk_lookup_tcp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
>> net/core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
>> net/core/filter.c:4903:11: error: initializer element is not constant
     .func  = bpf_sk_lookup_tcp,
              ^~~~~~~~~~~~~~~~~
   net/core/filter.c:4903:11: note: (near initialization for 'bpf_sk_lookup_tcp_proto.func')
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net/core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____bpf_sk_lookup_udp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
>> net/core/filter.c:4913:12: error: static declaration of 'bpf_sk_lookup_udp' follows non-static declaration
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net/core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c:4913:12: note: previous declaration of 'bpf_sk_lookup_udp' was here
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net/core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c: In function 'bpf_sk_lookup_udp':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____bpf_sk_lookup_udp' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____bpf_sk_lookup_udp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net/core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net/core/filter.c:4920:11: error: initializer element is not constant
     .func  = bpf_sk_lookup_udp,
              ^~~~~~~~~~~~~~~~~
   net/core/filter.c:4920:11: note: (near initialization for 'bpf_sk_lookup_udp_proto.func')
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net/core/filter.c:29:
--
   net//core/filter.c: In function 'sk_lookup':
   net//core/filter.c:4870:1: error: invalid storage class for function 'bpf_sk_lookup'
    bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
    ^~~~~~~~~~~~~
   net//core/filter.c:4869:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
    static unsigned long
    ^~~~~~
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net//core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____bpf_sk_lookup_tcp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c:4896:12: error: static declaration of 'bpf_sk_lookup_tcp' follows non-static declaration
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net//core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c:4896:12: note: previous declaration of 'bpf_sk_lookup_tcp' was here
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net//core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c: In function 'bpf_sk_lookup_tcp':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____bpf_sk_lookup_tcp' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____bpf_sk_lookup_tcp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4896:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c:4903:11: error: initializer element is not constant
     .func  = bpf_sk_lookup_tcp,
              ^~~~~~~~~~~~~~~~~
   net//core/filter.c:4903:11: note: (near initialization for 'bpf_sk_lookup_tcp_proto.func')
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net//core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____bpf_sk_lookup_udp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c:4913:12: error: static declaration of 'bpf_sk_lookup_udp' follows non-static declaration
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net//core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c:4913:12: note: previous declaration of 'bpf_sk_lookup_udp' was here
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net//core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c: In function 'bpf_sk_lookup_udp':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____bpf_sk_lookup_udp' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____bpf_sk_lookup_udp'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4913:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
    ^~~~~~~~~~
   net//core/filter.c:4920:11: error: initializer element is not constant
     .func  = bpf_sk_lookup_udp,
              ^~~~~~~~~~~~~~~~~
   net//core/filter.c:4920:11: note: (near initialization for 'bpf_sk_lookup_udp_proto.func')
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net//core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____bpf_sk_release'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
   include/linux/filter.h:443:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net//core/filter.c:4930:12: error: static declaration of 'bpf_sk_release' follows non-static declaration
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net//core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net//core/filter.c:4930:12: note: previous declaration of 'bpf_sk_release' was here
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net//core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net//core/filter.c: In function 'bpf_sk_release':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____bpf_sk_release' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
   include/linux/filter.h:443:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____bpf_sk_release'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
   include/linux/filter.h:443:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_2(name, ...) BPF_CALL_x(2, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:4930:1: note: in expansion of macro 'BPF_CALL_2'
    BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
    ^~~~~~~~~~
   net//core/filter.c:4941:11: error: initializer element is not constant
     .func  = bpf_sk_release,
              ^~~~~~~~~~~~~~
   net//core/filter.c:4941:11: note: (near initialization for 'bpf_sk_release_proto.func')
   net//core/filter.c:4980:1: error: invalid storage class for function 'bpf_base_func_proto'
    bpf_base_func_proto(enum bpf_func_id func_id)
    ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5009:1: error: invalid storage class for function 'sock_filter_func_proto'
    sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5025:1: error: invalid storage class for function 'sock_addr_func_proto'
    sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5051:1: error: invalid storage class for function 'sk_filter_func_proto'
    sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5068:1: error: invalid storage class for function 'cg_skb_func_proto'
    cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net//core/filter.c:5079:1: error: invalid storage class for function 'tc_cls_act_func_proto'
    tc_cls_act_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5166:1: error: invalid storage class for function 'xdp_func_proto'
    xdp_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~
   net//core/filter.c:5193:1: error: invalid storage class for function 'sock_ops_func_proto'
    sock_ops_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5216:1: error: invalid storage class for function 'sk_msg_func_proto'
    sk_msg_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net//core/filter.c:5237:1: error: invalid storage class for function 'sk_skb_func_proto'
    sk_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net//core/filter.c:5272:1: error: invalid storage class for function 'lwt_out_func_proto'
    lwt_out_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~
   net//core/filter.c:5299:1: error: invalid storage class for function 'lwt_in_func_proto'
    lwt_in_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~
   net//core/filter.c:5310:1: error: invalid storage class for function 'lwt_xmit_func_proto'
    lwt_xmit_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5345:1: error: invalid storage class for function 'lwt_seg6local_func_proto'
    lwt_seg6local_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
    ^~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5361:13: error: invalid storage class for function 'bpf_skb_is_valid_access'
    static bool bpf_skb_is_valid_access(int off, int size, enum bpf_access_type type,
                ^~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5404:13: error: invalid storage class for function 'sk_filter_is_valid_access'
    static bool sk_filter_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5430:13: error: invalid storage class for function 'lwt_is_valid_access'
    static bool lwt_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5466:13: error: invalid storage class for function '__sock_filter_check_attach_type'
    static bool __sock_filter_check_attach_type(int off,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5509:13: error: invalid storage class for function '__sock_filter_check_size'
    static bool __sock_filter_check_size(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5536:13: error: invalid storage class for function 'sock_filter_is_valid_access'
    static bool sock_filter_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5547:12: error: invalid storage class for function 'bpf_unclone_prologue'
    static int bpf_unclone_prologue(struct bpf_insn *insn_buf, bool direct_write,
               ^~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5586:12: error: invalid storage class for function 'bpf_gen_ld_abs'
    static int bpf_gen_ld_abs(const struct bpf_insn *orig,
               ^~~~~~~~~~~~~~
   net//core/filter.c:5621:12: error: invalid storage class for function 'tc_cls_act_prologue'
    static int tc_cls_act_prologue(struct bpf_insn *insn_buf, bool direct_write,
               ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5627:13: error: invalid storage class for function 'tc_cls_act_is_valid_access'
    static bool tc_cls_act_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5662:13: error: invalid storage class for function '__is_valid_xdp_access'
    static bool __is_valid_xdp_access(int off, int size)
                ^~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5674:13: error: invalid storage class for function 'xdp_is_valid_access'
    static bool xdp_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5714:13: error: invalid storage class for function 'sock_addr_is_valid_access'
    static bool sock_addr_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5714:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
    static bool sock_addr_is_valid_access(int off, int size,
    ^~~~~~
   net//core/filter.c:5801:13: error: invalid storage class for function 'sock_ops_is_valid_access'
    static bool sock_ops_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5842:12: error: invalid storage class for function 'sk_skb_prologue'
    static int sk_skb_prologue(struct bpf_insn *insn_buf, bool direct_write,
               ^~~~~~~~~~~~~~~
   net//core/filter.c:5848:13: error: invalid storage class for function 'sk_skb_is_valid_access'
    static bool sk_skb_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5883:13: error: invalid storage class for function 'sk_msg_is_valid_access'
    static bool sk_msg_is_valid_access(int off, int size,
                ^~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:5915:12: error: invalid storage class for function 'bpf_convert_ctx_access'
    static u32 bpf_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:6318:12: error: invalid storage class for function 'tc_cls_act_convert_ctx_access'
    static u32 tc_cls_act_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:6342:12: error: invalid storage class for function 'xdp_convert_ctx_access'
    static u32 xdp_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:6462:12: error: invalid storage class for function 'sock_addr_convert_ctx_access'
    static u32 sock_addr_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:6551:12: error: invalid storage class for function 'sock_ops_convert_ctx_access'
    static u32 sock_ops_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:6890:12: error: invalid storage class for function 'sk_skb_convert_ctx_access'
    static u32 sk_skb_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:6915:12: error: invalid storage class for function 'sk_msg_convert_ctx_access'
    static u32 sk_msg_convert_ctx_access(enum bpf_access_type type,
               ^~~~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:7192:1: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
    int sk_get_filter(struct sock *sk, struct sock_filter __user *ubuf,
    ^~~
   net//core/filter.c:7247:13: error: invalid storage class for function 'bpf_init_reuseport_kern'
    static void bpf_init_reuseport_kern(struct sk_reuseport_kern *reuse_kern,
                ^~~~~~~~~~~~~~~~~~~~~~~
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net//core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____sk_select_reuseport'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net//core/filter.c:7277:12: error: static declaration of 'sk_select_reuseport' follows non-static declaration
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net//core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net//core/filter.c:7277:12: note: previous declaration of 'sk_select_reuseport' was here
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net//core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_select_reuseport':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____sk_select_reuseport' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____sk_select_reuseport'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7277:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_select_reuseport, struct sk_reuseport_kern *, reuse_kern,
    ^~~~~~~~~~
   net//core/filter.c:7323:20: error: initializer element is not constant
     .func           = sk_select_reuseport,
                       ^~~~~~~~~~~~~~~~~~~
   net//core/filter.c:7323:20: note: (near initialization for 'sk_select_reuseport_proto.func')
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net//core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____sk_reuseport_load_bytes'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net//core/filter.c:7332:12: error: static declaration of 'sk_reuseport_load_bytes' follows non-static declaration
    BPF_CALL_4(sk_reuseport_load_bytes,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net//core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net//core/filter.c:7332:12: note: previous declaration of 'sk_reuseport_load_bytes' was here
    BPF_CALL_4(sk_reuseport_load_bytes,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net//core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_reuseport_load_bytes':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____sk_reuseport_load_bytes' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____sk_reuseport_load_bytes'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^
   include/linux/filter.h:445:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_4(name, ...) BPF_CALL_x(4, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7332:1: note: in expansion of macro 'BPF_CALL_4'
    BPF_CALL_4(sk_reuseport_load_bytes,
    ^~~~~~~~~~
   net//core/filter.c:7340:11: error: initializer element is not constant
     .func  = sk_reuseport_load_bytes,
              ^~~~~~~~~~~~~~~~~~~~~~~
   net//core/filter.c:7340:11: note: (near initialization for 'sk_reuseport_load_bytes_proto.func')
   In file included from include/net/sock.h:64:0,
                    from include/linux/sock_diag.h:8,
                    from net//core/filter.c:29:
>> include/linux/filter.h:432:6: error: invalid storage class for function '____sk_reuseport_load_bytes_relative'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__));   \
         ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7349:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(sk_reuseport_load_bytes_relative,
    ^~~~~~~~~~
   net//core/filter.c:7349:12: error: static declaration of 'sk_reuseport_load_bytes_relative' follows non-static declaration
    BPF_CALL_5(sk_reuseport_load_bytes_relative,
               ^
   include/linux/filter.h:434:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__))        \
         ^~~~
   net//core/filter.c:7349:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(sk_reuseport_load_bytes_relative,
    ^~~~~~~~~~
   net//core/filter.c:7349:12: note: previous declaration of 'sk_reuseport_load_bytes_relative' was here
    BPF_CALL_5(sk_reuseport_load_bytes_relative,
               ^
   include/linux/filter.h:433:6: note: in definition of macro 'BPF_CALL_x'
     u64 name(__BPF_REG(x, __BPF_DECL_REGS, __BPF_N, __VA_ARGS__));        \
         ^~~~
   net//core/filter.c:7349:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(sk_reuseport_load_bytes_relative,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_reuseport_load_bytes_relative':
>> include/linux/filter.h:436:10: error: implicit declaration of function '____sk_reuseport_load_bytes_relative' [-Werror=implicit-function-declaration]
      return ____##name(__BPF_MAP(x,__BPF_CAST,__BPF_N,__VA_ARGS__));\
             ^
>> include/linux/filter.h:446:31: note: in expansion of macro 'BPF_CALL_x'
    #define BPF_CALL_5(name, ...) BPF_CALL_x(5, name, __VA_ARGS__)
                                  ^~~~~~~~~~
   net//core/filter.c:7349:1: note: in expansion of macro 'BPF_CALL_5'
    BPF_CALL_5(sk_reuseport_load_bytes_relative,
    ^~~~~~~~~~
   net//core/filter.c: In function 'sk_lookup':
   include/linux/filter.h:439:6: error: invalid storage class for function '____sk_reuseport_load_bytes_relative'
     u64 ____##name(__BPF_MAP(x, __BPF_DECL_ARGS, __BPF_V, __VA_ARGS__))
         ^

vim +/bpf_sk_lookup +4870 net/core/filter.c

  4863	
  4864	/* bpf_sk_lookup performs the core lookup for different types of sockets,
  4865	 * taking a reference on the socket if it doesn't have the flag SOCK_RCU_FREE.
  4866	 * Returns the socket as an 'unsigned long' to simplify the casting in the
  4867	 * callers to satisfy BPF_CALL declarations.
  4868	 */
> 4869	static unsigned long
> 4870	bpf_sk_lookup(struct sk_buff *skb, struct bpf_sock_tuple *tuple, u32 len,
  4871		      u8 proto, u32 netns_id, u64 flags)
  4872	{
  4873		struct net *caller_net = dev_net(skb->dev);
  4874		struct sock *sk = NULL;
  4875		struct net *net;
  4876	
  4877		if (unlikely(len != sizeof(struct bpf_sock_tuple) || flags ||
  4878			     (tuple->family != AF_INET && tuple->family != AF_INET6)))
  4879			goto out;
  4880	
  4881		if (netns_id)
  4882			net = get_net_ns_by_id(caller_net, netns_id);
  4883		else
  4884			net = caller_net;
  4885		if (unlikely(!net))
  4886			goto out;
  4887		sk = sk_lookup(net, tuple, skb, proto);
  4888		put_net(net);
  4889	
  4890		if (sk)
  4891			sk = sk_to_full_sk(sk);
  4892	out:
  4893		return (unsigned long) sk;
  4894	}
  4895	
> 4896	BPF_CALL_5(bpf_sk_lookup_tcp, struct sk_buff *, skb,
  4897		   struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
  4898	{
  4899		return bpf_sk_lookup(skb, tuple, len, IPPROTO_TCP, netns_id, flags);
  4900	}
  4901	
  4902	static const struct bpf_func_proto bpf_sk_lookup_tcp_proto = {
> 4903		.func		= bpf_sk_lookup_tcp,
  4904		.gpl_only	= false,
  4905		.ret_type	= RET_PTR_TO_SOCKET_OR_NULL,
  4906		.arg1_type	= ARG_PTR_TO_CTX,
  4907		.arg2_type	= ARG_PTR_TO_MEM,
  4908		.arg3_type	= ARG_CONST_SIZE,
  4909		.arg4_type	= ARG_ANYTHING,
  4910		.arg5_type	= ARG_ANYTHING,
  4911	};
  4912	
> 4913	BPF_CALL_5(bpf_sk_lookup_udp, struct sk_buff *, skb,
  4914		   struct bpf_sock_tuple *, tuple, u32, len, u32, netns_id, u64, flags)
  4915	{
  4916		return bpf_sk_lookup(skb, tuple, len, IPPROTO_UDP, netns_id, flags);
  4917	}
  4918	
  4919	static const struct bpf_func_proto bpf_sk_lookup_udp_proto = {
  4920		.func		= bpf_sk_lookup_udp,
  4921		.gpl_only	= false,
  4922		.ret_type	= RET_PTR_TO_SOCKET_OR_NULL,
  4923		.arg1_type	= ARG_PTR_TO_CTX,
  4924		.arg2_type	= ARG_PTR_TO_MEM,
  4925		.arg3_type	= ARG_CONST_SIZE,
  4926		.arg4_type	= ARG_ANYTHING,
  4927		.arg5_type	= ARG_ANYTHING,
  4928	};
  4929	
> 4930	BPF_CALL_2(bpf_sk_release, struct sock *, sk, u64, flags)
  4931	{
  4932		if (!sock_flag(sk, SOCK_RCU_FREE))
  4933			sock_gen_put(sk);
  4934	
  4935		if (unlikely(flags))
  4936			return -EINVAL;
  4937		return 0;
  4938	}
  4939	
  4940	static const struct bpf_func_proto bpf_sk_release_proto = {
> 4941		.func		= bpf_sk_release,
  4942		.gpl_only	= false,
  4943		.ret_type	= RET_INTEGER,
  4944		.arg1_type	= ARG_PTR_TO_SOCKET,
  4945		.arg2_type	= ARG_ANYTHING,
  4946	};
  4947	
  4948	bool bpf_helper_changes_pkt_data(void *func)
  4949	{
  4950		if (func == bpf_skb_vlan_push ||
  4951		    func == bpf_skb_vlan_pop ||
  4952		    func == bpf_skb_store_bytes ||
  4953		    func == bpf_skb_change_proto ||
  4954		    func == bpf_skb_change_head ||
  4955		    func == sk_skb_change_head ||
  4956		    func == bpf_skb_change_tail ||
  4957		    func == sk_skb_change_tail ||
  4958		    func == bpf_skb_adjust_room ||
  4959		    func == bpf_skb_pull_data ||
  4960		    func == sk_skb_pull_data ||
  4961		    func == bpf_clone_redirect ||
  4962		    func == bpf_l3_csum_replace ||
  4963		    func == bpf_l4_csum_replace ||
  4964		    func == bpf_xdp_adjust_head ||
  4965		    func == bpf_xdp_adjust_meta ||
  4966		    func == bpf_msg_pull_data ||
  4967		    func == bpf_xdp_adjust_tail ||
  4968	#if IS_ENABLED(CONFIG_IPV6_SEG6_BPF)
  4969		    func == bpf_lwt_seg6_store_bytes ||
  4970		    func == bpf_lwt_seg6_adjust_srh ||
  4971		    func == bpf_lwt_seg6_action ||
  4972	#endif
  4973		    func == bpf_lwt_push_encap)
  4974			return true;
  4975	
  4976		return false;
  4977	}
  4978	
  4979	static const struct bpf_func_proto *
> 4980	bpf_base_func_proto(enum bpf_func_id func_id)
  4981	{
  4982		switch (func_id) {
  4983		case BPF_FUNC_map_lookup_elem:
  4984			return &bpf_map_lookup_elem_proto;
  4985		case BPF_FUNC_map_update_elem:
  4986			return &bpf_map_update_elem_proto;
  4987		case BPF_FUNC_map_delete_elem:
  4988			return &bpf_map_delete_elem_proto;
  4989		case BPF_FUNC_get_prandom_u32:
  4990			return &bpf_get_prandom_u32_proto;
  4991		case BPF_FUNC_get_smp_processor_id:
  4992			return &bpf_get_raw_smp_processor_id_proto;
  4993		case BPF_FUNC_get_numa_node_id:
  4994			return &bpf_get_numa_node_id_proto;
  4995		case BPF_FUNC_tail_call:
  4996			return &bpf_tail_call_proto;
  4997		case BPF_FUNC_ktime_get_ns:
  4998			return &bpf_ktime_get_ns_proto;
  4999		case BPF_FUNC_trace_printk:
  5000			if (capable(CAP_SYS_ADMIN))
  5001				return bpf_get_trace_printk_proto();
  5002			/* else: fall through */
  5003		default:
  5004			return NULL;
  5005		}
  5006	}
  5007	
  5008	static const struct bpf_func_proto *
> 5009	sock_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
  5010	{
  5011		switch (func_id) {
  5012		/* inet and inet6 sockets are created in a process
  5013		 * context so there is always a valid uid/gid
  5014		 */
  5015		case BPF_FUNC_get_current_uid_gid:
  5016			return &bpf_get_current_uid_gid_proto;
  5017		case BPF_FUNC_get_local_storage:
  5018			return &bpf_get_local_storage_proto;
  5019		default:
  5020			return bpf_base_func_proto(func_id);
  5021		}
  5022	}
  5023	
  5024	static const struct bpf_func_proto *
> 5025	sock_addr_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
  5026	{
  5027		switch (func_id) {
  5028		/* inet and inet6 sockets are created in a process
  5029		 * context so there is always a valid uid/gid
  5030		 */
  5031		case BPF_FUNC_get_current_uid_gid:
  5032			return &bpf_get_current_uid_gid_proto;
  5033		case BPF_FUNC_bind:
  5034			switch (prog->expected_attach_type) {
  5035			case BPF_CGROUP_INET4_CONNECT:
  5036			case BPF_CGROUP_INET6_CONNECT:
  5037				return &bpf_bind_proto;
  5038			default:
  5039				return NULL;
  5040			}
  5041		case BPF_FUNC_get_socket_cookie:
  5042			return &bpf_get_socket_cookie_sock_addr_proto;
  5043		case BPF_FUNC_get_local_storage:
  5044			return &bpf_get_local_storage_proto;
  5045		default:
  5046			return bpf_base_func_proto(func_id);
  5047		}
  5048	}
  5049	
  5050	static const struct bpf_func_proto *
> 5051	sk_filter_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
  5052	{
  5053		switch (func_id) {
  5054		case BPF_FUNC_skb_load_bytes:
  5055			return &bpf_skb_load_bytes_proto;
  5056		case BPF_FUNC_skb_load_bytes_relative:
  5057			return &bpf_skb_load_bytes_relative_proto;
  5058		case BPF_FUNC_get_socket_cookie:
  5059			return &bpf_get_socket_cookie_proto;
  5060		case BPF_FUNC_get_socket_uid:
  5061			return &bpf_get_socket_uid_proto;
  5062		default:
  5063			return bpf_base_func_proto(func_id);
  5064		}
  5065	}
  5066	
  5067	static const struct bpf_func_proto *
> 5068	cg_skb_func_proto(enum bpf_func_id func_id, const struct bpf_prog *prog)
  5069	{
  5070		switch (func_id) {
  5071		case BPF_FUNC_get_local_storage:
  5072			return &bpf_get_local_storage_proto;
  5073		default:
  5074			return sk_filter_func_proto(func_id, prog);
  5075		}
  5076	}
  5077	

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation

[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 26893 bytes --]

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2018-09-14 12:25 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-13 19:06 [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF Alexei Starovoitov
2018-09-13 20:55 ` Joe Stringer
2018-09-13 20:57   ` Joe Stringer
2018-09-13 21:01   ` Alexei Starovoitov
2018-09-13 21:17     ` Joe Stringer
2018-09-13 21:22       ` Alexei Starovoitov
2018-09-13 21:24         ` Joe Stringer
2018-09-13 22:23           ` Alexei Starovoitov
  -- strict thread matches above, loose matches on Subject: below --
2018-09-12  0:36 [PATCH bpf-next 00/11] Add socket lookup support Joe Stringer
2018-09-12  0:36 ` [PATCH bpf-next 07/11] bpf: Add helper to retrieve socket in BPF Joe Stringer
2018-09-13  0:06   ` Alexei Starovoitov
2018-09-14  6:57   ` kbuild test robot
2018-09-14  7:11   ` kbuild test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).