aboutsummaryrefslogtreecommitdiffstats
path: root/samples/bpf/xdp_router_ipv4_user.c
diff options
context:
space:
mode:
authorLorenzo Bianconi <lorenzo@kernel.org>2022-04-05 16:15:14 +0200
committerDaniel Borkmann <daniel@iogearbox.net>2022-04-08 22:10:57 +0200
commit587323cf6a6a6da074f0518444ee7da10f517f45 (patch)
tree4bfe567b3f8e5c193c62378d5f32f303077d9e26 /samples/bpf/xdp_router_ipv4_user.c
parentlibbpf: Allow WEAK and GLOBAL bindings during BTF fixup (diff)
downloadlinux-dev-587323cf6a6a6da074f0518444ee7da10f517f45.tar.xz
linux-dev-587323cf6a6a6da074f0518444ee7da10f517f45.zip
samples, bpf: Move routes monitor in xdp_router_ipv4 in a dedicated thread
In order to not miss any netlink message from the kernel, move routes monitor to a dedicated thread. Fixes: 85bf1f51691c ("samples: bpf: Convert xdp_router_ipv4 to XDP samples helper") Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://lore.kernel.org/bpf/e364b817c69ded73be24b677ab47a157f7c21b64.1649167911.git.lorenzo@kernel.org
Diffstat (limited to '')
-rw-r--r--samples/bpf/xdp_router_ipv4_user.c86
1 files changed, 54 insertions, 32 deletions
diff --git a/samples/bpf/xdp_router_ipv4_user.c b/samples/bpf/xdp_router_ipv4_user.c
index 7828784612ec..f32bbd5c32bf 100644
--- a/samples/bpf/xdp_router_ipv4_user.c
+++ b/samples/bpf/xdp_router_ipv4_user.c
@@ -25,6 +25,7 @@
#include <sys/resource.h>
#include <libgen.h>
#include <getopt.h>
+#include <pthread.h>
#include "xdp_sample_user.h"
#include "xdp_router_ipv4.skel.h"
@@ -38,6 +39,9 @@ static int arp_table_map_fd;
static int exact_match_map_fd;
static int tx_port_map_fd;
+static bool routes_thread_exit;
+static int interval = 5;
+
static int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_MAP_CNT |
SAMPLE_DEVMAP_XMIT_CNT_MULTI | SAMPLE_EXCEPTION_CNT;
@@ -445,7 +449,7 @@ cleanup:
/* Function to keep track and update changes in route and arp table
* Give regular statistics of packets forwarded
*/
-static void monitor_route(void *ctx)
+static void *monitor_routes_thread(void *arg)
{
struct pollfd fds_route, fds_arp;
struct sockaddr_nl la, lr;
@@ -455,7 +459,7 @@ static void monitor_route(void *ctx)
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
if (sock < 0) {
fprintf(stderr, "open netlink socket: %s\n", strerror(errno));
- return;
+ return NULL;
}
fcntl(sock, F_SETFL, O_NONBLOCK);
@@ -465,7 +469,7 @@ static void monitor_route(void *ctx)
if (bind(sock, (struct sockaddr *)&lr, sizeof(lr)) < 0) {
fprintf(stderr, "bind netlink socket: %s\n", strerror(errno));
close(sock);
- return;
+ return NULL;
}
fds_route.fd = sock;
@@ -475,7 +479,7 @@ static void monitor_route(void *ctx)
if (sock_arp < 0) {
fprintf(stderr, "open netlink socket: %s\n", strerror(errno));
close(sock);
- return;
+ return NULL;
}
fcntl(sock_arp, F_SETFL, O_NONBLOCK);
@@ -490,35 +494,51 @@ static void monitor_route(void *ctx)
fds_arp.fd = sock_arp;
fds_arp.events = POLL_IN;
- memset(buf, 0, sizeof(buf));
- if (poll(&fds_route, 1, 3) == POLL_IN) {
- nll = recv_msg(lr, sock);
- if (nll < 0) {
- fprintf(stderr, "recv from netlink: %s\n",
- strerror(nll));
- goto cleanup;
- }
+ /* dump route and arp tables */
+ if (get_arp_table(AF_INET) < 0) {
+ fprintf(stderr, "Failed reading arp table\n");
+ goto cleanup;
+ }
- nh = (struct nlmsghdr *)buf;
- read_route(nh, nll);
+ if (get_route_table(AF_INET) < 0) {
+ fprintf(stderr, "Failed reading route table\n");
+ goto cleanup;
}
- memset(buf, 0, sizeof(buf));
- if (poll(&fds_arp, 1, 3) == POLL_IN) {
- nll = recv_msg(la, sock_arp);
- if (nll < 0) {
- fprintf(stderr, "recv from netlink: %s\n",
- strerror(nll));
- goto cleanup;
+ while (!routes_thread_exit) {
+ memset(buf, 0, sizeof(buf));
+ if (poll(&fds_route, 1, 3) == POLL_IN) {
+ nll = recv_msg(lr, sock);
+ if (nll < 0) {
+ fprintf(stderr, "recv from netlink: %s\n",
+ strerror(nll));
+ goto cleanup;
+ }
+
+ nh = (struct nlmsghdr *)buf;
+ read_route(nh, nll);
}
- nh = (struct nlmsghdr *)buf;
- read_arp(nh, nll);
+ memset(buf, 0, sizeof(buf));
+ if (poll(&fds_arp, 1, 3) == POLL_IN) {
+ nll = recv_msg(la, sock_arp);
+ if (nll < 0) {
+ fprintf(stderr, "recv from netlink: %s\n",
+ strerror(nll));
+ goto cleanup;
+ }
+
+ nh = (struct nlmsghdr *)buf;
+ read_arp(nh, nll);
+ }
+
+ sleep(interval);
}
cleanup:
close(sock_arp);
close(sock);
+ return NULL;
}
static void usage(char *argv[], const struct option *long_options,
@@ -531,10 +551,11 @@ static void usage(char *argv[], const struct option *long_options,
int main(int argc, char **argv)
{
bool error = true, generic = false, force = false;
- int opt, interval = 5, ret = EXIT_FAIL_BPF;
+ int opt, ret = EXIT_FAIL_BPF;
struct xdp_router_ipv4 *skel;
int i, total_ifindex = argc - 1;
char **ifname_list = argv + 1;
+ pthread_t routes_thread;
int longindex = 0;
if (libbpf_set_strict_mode(LIBBPF_STRICT_ALL) < 0) {
@@ -653,24 +674,25 @@ int main(int argc, char **argv)
goto end_destroy;
}
- if (get_route_table(AF_INET) < 0) {
- fprintf(stderr, "Failed reading routing table\n");
+ ret = pthread_create(&routes_thread, NULL, monitor_routes_thread, NULL);
+ if (ret) {
+ fprintf(stderr, "Failed creating routes_thread: %s\n", strerror(-ret));
+ ret = EXIT_FAIL;
goto end_destroy;
}
- if (get_arp_table(AF_INET) < 0) {
- fprintf(stderr, "Failed reading arptable\n");
- goto end_destroy;
- }
+ ret = sample_run(interval, NULL, NULL);
+ routes_thread_exit = true;
- ret = sample_run(interval, monitor_route, NULL);
if (ret < 0) {
fprintf(stderr, "Failed during sample run: %s\n", strerror(-ret));
ret = EXIT_FAIL;
- goto end_destroy;
+ goto end_thread_wait;
}
ret = EXIT_OK;
+end_thread_wait:
+ pthread_join(routes_thread, NULL);
end_destroy:
xdp_router_ipv4__destroy(skel);
end: