Thread (25 messages) 25 messages, 5 authors, 2021-08-19

[[RFC xdp-hints] 16/16] samples/bpf: Show XDP hints usage

From: Ederson de Souza <hidden>
Date: 2021-08-03 01:03:55
Subsystem: bpf [general] (safe dynamic programs and tools), the rest, xdp (express data path) · Maintainers: Alexei Starovoitov, Daniel Borkmann, Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi, Linus Torvalds, David S. Miller, Jakub Kicinski, Jesper Dangaard Brouer, John Fastabend

An example of how to retrieve XDP hints/metadata from an XDP frame. To
get the xdp_hints struct, one can use:

$ bpftool net xdp show
  xdp:
  enp6s0(2) md_btf_id(44) md_btf_enabled(0)

To get the BTF id, and then:

$ bpftool btf dump id 44 format c > btf.h

But, in this example, to demonstrate BTF and CORE features, a simpler
struct was defined, containing the only field used by the sample.

A lowpoint is that it's not currently possible to use some CORE features
from "samples/bpf" directory, as those samples are currently built
without using "clang -target bpf". This way, it was not possible to use
"bpf_core_field_exists" macro to check, in runtime, the presence of a
given XDP hints field.
---
 samples/bpf/xdp_sample_pkts_kern.c | 21 +++++++++++++++++++++
 samples/bpf/xdp_sample_pkts_user.c |  4 +++-
 2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/samples/bpf/xdp_sample_pkts_kern.c b/samples/bpf/xdp_sample_pkts_kern.c
index 9cf76b340dd7..9f0b0c5a6237 100644
--- a/samples/bpf/xdp_sample_pkts_kern.c
+++ b/samples/bpf/xdp_sample_pkts_kern.c
@@ -3,6 +3,7 @@
 #include <linux/version.h>
 #include <uapi/linux/bpf.h>
 #include <bpf/bpf_helpers.h>
+#include <bpf/bpf_core_read.h>
 
 #define SAMPLE_SIZE 64ul
 
@@ -12,16 +13,23 @@ struct {
 	__uint(value_size, sizeof(u32));
 } my_map SEC(".maps");
 
+struct xdp_hints {
+	u64 rx_timestamp;
+};
+
 SEC("xdp_sample")
 int xdp_sample_prog(struct xdp_md *ctx)
 {
+	void *meta_data = (void *)(long)ctx->data_meta;
 	void *data_end = (void *)(long)ctx->data_end;
 	void *data = (void *)(long)ctx->data;
+	struct xdp_hints *hints;
 
 	/* Metadata will be in the perf event before the packet data. */
 	struct S {
 		u16 cookie;
 		u16 pkt_len;
+		u64 rx_timestamp;
 	} __packed metadata;
 
 	if (data < data_end) {
@@ -41,9 +49,22 @@ int xdp_sample_prog(struct xdp_md *ctx)
 
 		metadata.cookie = 0xdead;
 		metadata.pkt_len = (u16)(data_end - data);
+		metadata.rx_timestamp = 0;
 		sample_size = min(metadata.pkt_len, SAMPLE_SIZE);
 		flags |= (u64)sample_size << 32;
 
+		if (meta_data < data) {
+			hints = meta_data;
+			/* bpf_core_field_exists doesn't work from samples/bpf,
+			 * as it is only available for "clang -target bpf", which
+			 * is not used on samples/bpf. A program that can use
+			 * the "vmlinux.h" and "clang -target btf" could use this
+			 * call to check the existence of a given field in runtime
+			 */
+			/*if (bpf_core_field_exists(hints->rx_timestamp))*/
+				metadata.rx_timestamp = BPF_CORE_READ(hints, rx_timestamp);
+		}
+
 		ret = bpf_perf_event_output(ctx, &my_map, flags,
 					    &metadata, sizeof(metadata));
 		if (ret)
diff --git a/samples/bpf/xdp_sample_pkts_user.c b/samples/bpf/xdp_sample_pkts_user.c
index 495e09897bd3..b87e0ae8eb3d 100644
--- a/samples/bpf/xdp_sample_pkts_user.c
+++ b/samples/bpf/xdp_sample_pkts_user.c
@@ -76,6 +76,7 @@ static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
 	struct {
 		__u16 cookie;
 		__u16 pkt_len;
+		__u64 rx_timestamp;
 		__u8  pkt_data[SAMPLE_SIZE];
 	} __packed *e = data;
 	int i;
@@ -85,7 +86,8 @@ static void print_bpf_output(void *ctx, int cpu, void *data, __u32 size)
 		return;
 	}
 
-	printf("Pkt len: %-5d bytes. Ethernet hdr: ", e->pkt_len);
+	printf("Pkt len: %-5d bytes. RX timestamp: %llu Ethernet hdr: ", e->pkt_len,
+	       e->rx_timestamp);
 	for (i = 0; i < 14 && i < e->pkt_len; i++)
 		printf("%02x ", e->pkt_data[i]);
 	printf("\n");
-- 
2.32.0
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help