summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--op-mode-definitions/show-interfaces-bonding.xml6
-rw-r--r--op-mode-definitions/show-interfaces-ethernet.xml6
-rwxr-xr-xsrc/op_mode/show_xdp_stats.sh7
-rw-r--r--src/xdp/common/common.mk2
-rw-r--r--src/xdp/utils/xdp_stats.c49
5 files changed, 46 insertions, 24 deletions
diff --git a/op-mode-definitions/show-interfaces-bonding.xml b/op-mode-definitions/show-interfaces-bonding.xml
index c1c76b059..f6d9b3508 100644
--- a/op-mode-definitions/show-interfaces-bonding.xml
+++ b/op-mode-definitions/show-interfaces-bonding.xml
@@ -42,6 +42,12 @@
</leafNode>
</children>
</tagNode>
+ <leafNode name="xdp">
+ <properties>
+ <help>Show eXpress Data Path statistics</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/show_xdp_stats.sh bonding "$4"</command>
+ </leafNode>
</children>
</tagNode>
<node name="bonding">
diff --git a/op-mode-definitions/show-interfaces-ethernet.xml b/op-mode-definitions/show-interfaces-ethernet.xml
index bdcfa55f1..fc79f44bf 100644
--- a/op-mode-definitions/show-interfaces-ethernet.xml
+++ b/op-mode-definitions/show-interfaces-ethernet.xml
@@ -68,6 +68,12 @@
</leafNode>
</children>
</tagNode>
+ <leafNode name="xdp">
+ <properties>
+ <help>Show eXpress Data Path statistics</help>
+ </properties>
+ <command>sudo ${vyos_op_scripts_dir}/show_xdp_stats.sh ethernet "$4"</command>
+ </leafNode>
</children>
</tagNode>
<node name="ethernet">
diff --git a/src/op_mode/show_xdp_stats.sh b/src/op_mode/show_xdp_stats.sh
new file mode 100755
index 000000000..a4ef33107
--- /dev/null
+++ b/src/op_mode/show_xdp_stats.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+if cli-shell-api existsEffective interfaces $1 $2 xdp; then
+ /usr/sbin/xdp_stats --dev "$2"
+else
+ echo "XDP not enabled on $2"
+fi
diff --git a/src/xdp/common/common.mk b/src/xdp/common/common.mk
index 89aac68ef..ebe23a9ed 100644
--- a/src/xdp/common/common.mk
+++ b/src/xdp/common/common.mk
@@ -39,7 +39,7 @@ KERN_USER_H ?= $(wildcard common_kern_user.h)
CFLAGS ?= -g -I../include/
BPF_CFLAGS ?= -I../include/
-LIBS = -l:libbpf.a -lelf -lz $(USER_LIBS)
+LIBS = -l:libbpf.a -lelf $(USER_LIBS)
all: llvm-check $(USER_TARGETS) $(XDP_OBJ) $(COPY_LOADER) $(COPY_STATS)
diff --git a/src/xdp/utils/xdp_stats.c b/src/xdp/utils/xdp_stats.c
index 5dbec8351..f9fa7438f 100644
--- a/src/xdp/utils/xdp_stats.c
+++ b/src/xdp/utils/xdp_stats.c
@@ -197,6 +197,7 @@ static int stats_poll(const char *pin_dir, int map_fd, __u32 id,
{
struct bpf_map_info info = {};
struct stats_record prev, record = { 0 };
+ int counter = 0;
/* Trick to pretty printf with thousands separators use %' */
setlocale(LC_NUMERIC, "en_US");
@@ -219,6 +220,10 @@ static int stats_poll(const char *pin_dir, int map_fd, __u32 id,
stats_collect(map_fd, map_type, &record);
stats_print(&record, &prev);
sleep(interval);
+ counter++;
+ if (counter > 1) {
+ return 0;
+ }
}
return 0;
@@ -265,31 +270,29 @@ int main(int argc, char **argv)
return EXIT_FAIL_OPTION;
}
- for ( ;; ) {
- stats_map_fd = open_bpf_map_file(pin_dir, "xdp_stats_map", &info);
- if (stats_map_fd < 0) {
- return EXIT_FAIL_BPF;
- }
-
- /* check map info, e.g. datarec is expected size */
- err = check_map_fd_info(&info, &map_expect);
- if (err) {
- fprintf(stderr, "ERR: map via FD not compatible\n");
- return err;
- }
- if (verbose) {
- printf("\nCollecting stats from BPF map\n");
- printf(" - BPF map (bpf_map_type:%d) id:%d name:%s"
- " key_size:%d value_size:%d max_entries:%d\n",
- info.type, info.id, info.name,
- info.key_size, info.value_size, info.max_entries
- );
- }
+ stats_map_fd = open_bpf_map_file(pin_dir, "xdp_stats_map", &info);
+ if (stats_map_fd < 0) {
+ return EXIT_FAIL_BPF;
+ }
- err = stats_poll(pin_dir, stats_map_fd, info.id, info.type, interval);
- if (err < 0)
- return err;
+ /* check map info, e.g. datarec is expected size */
+ err = check_map_fd_info(&info, &map_expect);
+ if (err) {
+ fprintf(stderr, "ERR: map via FD not compatible\n");
+ return err;
}
+ if (verbose) {
+ printf("\nCollecting stats from BPF map\n");
+ printf(" - BPF map (bpf_map_type:%d) id:%d name:%s"
+ " key_size:%d value_size:%d max_entries:%d\n",
+ info.type, info.id, info.name,
+ info.key_size, info.value_size, info.max_entries
+ );
+ }
+
+ err = stats_poll(pin_dir, stats_map_fd, info.id, info.type, interval);
+ if (err < 0)
+ return err;
return EXIT_OK;
}