Skip to content

Commit 587323c

Browse files
LorenzoBianconiborkmann
authored andcommitted
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: 85bf1f5 ("samples: bpf: Convert xdp_router_ipv4 to XDP samples helper") Signed-off-by: Lorenzo Bianconi <[email protected]> Signed-off-by: Daniel Borkmann <[email protected]> Link: https://lore.kernel.org/bpf/e364b817c69ded73be24b677ab47a157f7c21b64.1649167911.git.lorenzo@kernel.org
1 parent 3a06ec0 commit 587323c

File tree

2 files changed

+55
-33
lines changed

2 files changed

+55
-33
lines changed

samples/bpf/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ TPROGLDLIBS_xdp_redirect += -lm
219219
TPROGLDLIBS_xdp_redirect_cpu += -lm
220220
TPROGLDLIBS_xdp_redirect_map += -lm
221221
TPROGLDLIBS_xdp_redirect_map_multi += -lm
222-
TPROGLDLIBS_xdp_router_ipv4 += -lm
222+
TPROGLDLIBS_xdp_router_ipv4 += -lm -pthread
223223
TPROGLDLIBS_tracex4 += -lrt
224224
TPROGLDLIBS_trace_output += -lrt
225225
TPROGLDLIBS_map_perf_test += -lrt

samples/bpf/xdp_router_ipv4_user.c

Lines changed: 54 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <sys/resource.h>
2626
#include <libgen.h>
2727
#include <getopt.h>
28+
#include <pthread.h>
2829
#include "xdp_sample_user.h"
2930
#include "xdp_router_ipv4.skel.h"
3031

@@ -38,6 +39,9 @@ static int arp_table_map_fd;
3839
static int exact_match_map_fd;
3940
static int tx_port_map_fd;
4041

42+
static bool routes_thread_exit;
43+
static int interval = 5;
44+
4145
static int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_MAP_CNT |
4246
SAMPLE_DEVMAP_XMIT_CNT_MULTI | SAMPLE_EXCEPTION_CNT;
4347

@@ -445,7 +449,7 @@ static int get_arp_table(int rtm_family)
445449
/* Function to keep track and update changes in route and arp table
446450
* Give regular statistics of packets forwarded
447451
*/
448-
static void monitor_route(void *ctx)
452+
static void *monitor_routes_thread(void *arg)
449453
{
450454
struct pollfd fds_route, fds_arp;
451455
struct sockaddr_nl la, lr;
@@ -455,7 +459,7 @@ static void monitor_route(void *ctx)
455459
sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
456460
if (sock < 0) {
457461
fprintf(stderr, "open netlink socket: %s\n", strerror(errno));
458-
return;
462+
return NULL;
459463
}
460464

461465
fcntl(sock, F_SETFL, O_NONBLOCK);
@@ -465,7 +469,7 @@ static void monitor_route(void *ctx)
465469
if (bind(sock, (struct sockaddr *)&lr, sizeof(lr)) < 0) {
466470
fprintf(stderr, "bind netlink socket: %s\n", strerror(errno));
467471
close(sock);
468-
return;
472+
return NULL;
469473
}
470474

471475
fds_route.fd = sock;
@@ -475,7 +479,7 @@ static void monitor_route(void *ctx)
475479
if (sock_arp < 0) {
476480
fprintf(stderr, "open netlink socket: %s\n", strerror(errno));
477481
close(sock);
478-
return;
482+
return NULL;
479483
}
480484

481485
fcntl(sock_arp, F_SETFL, O_NONBLOCK);
@@ -490,35 +494,51 @@ static void monitor_route(void *ctx)
490494
fds_arp.fd = sock_arp;
491495
fds_arp.events = POLL_IN;
492496

493-
memset(buf, 0, sizeof(buf));
494-
if (poll(&fds_route, 1, 3) == POLL_IN) {
495-
nll = recv_msg(lr, sock);
496-
if (nll < 0) {
497-
fprintf(stderr, "recv from netlink: %s\n",
498-
strerror(nll));
499-
goto cleanup;
500-
}
497+
/* dump route and arp tables */
498+
if (get_arp_table(AF_INET) < 0) {
499+
fprintf(stderr, "Failed reading arp table\n");
500+
goto cleanup;
501+
}
501502

502-
nh = (struct nlmsghdr *)buf;
503-
read_route(nh, nll);
503+
if (get_route_table(AF_INET) < 0) {
504+
fprintf(stderr, "Failed reading route table\n");
505+
goto cleanup;
504506
}
505507

506-
memset(buf, 0, sizeof(buf));
507-
if (poll(&fds_arp, 1, 3) == POLL_IN) {
508-
nll = recv_msg(la, sock_arp);
509-
if (nll < 0) {
510-
fprintf(stderr, "recv from netlink: %s\n",
511-
strerror(nll));
512-
goto cleanup;
508+
while (!routes_thread_exit) {
509+
memset(buf, 0, sizeof(buf));
510+
if (poll(&fds_route, 1, 3) == POLL_IN) {
511+
nll = recv_msg(lr, sock);
512+
if (nll < 0) {
513+
fprintf(stderr, "recv from netlink: %s\n",
514+
strerror(nll));
515+
goto cleanup;
516+
}
517+
518+
nh = (struct nlmsghdr *)buf;
519+
read_route(nh, nll);
513520
}
514521

515-
nh = (struct nlmsghdr *)buf;
516-
read_arp(nh, nll);
522+
memset(buf, 0, sizeof(buf));
523+
if (poll(&fds_arp, 1, 3) == POLL_IN) {
524+
nll = recv_msg(la, sock_arp);
525+
if (nll < 0) {
526+
fprintf(stderr, "recv from netlink: %s\n",
527+
strerror(nll));
528+
goto cleanup;
529+
}
530+
531+
nh = (struct nlmsghdr *)buf;
532+
read_arp(nh, nll);
533+
}
534+
535+
sleep(interval);
517536
}
518537

519538
cleanup:
520539
close(sock_arp);
521540
close(sock);
541+
return NULL;
522542
}
523543

524544
static void usage(char *argv[], const struct option *long_options,
@@ -531,10 +551,11 @@ static void usage(char *argv[], const struct option *long_options,
531551
int main(int argc, char **argv)
532552
{
533553
bool error = true, generic = false, force = false;
534-
int opt, interval = 5, ret = EXIT_FAIL_BPF;
554+
int opt, ret = EXIT_FAIL_BPF;
535555
struct xdp_router_ipv4 *skel;
536556
int i, total_ifindex = argc - 1;
537557
char **ifname_list = argv + 1;
558+
pthread_t routes_thread;
538559
int longindex = 0;
539560

540561
if (libbpf_set_strict_mode(LIBBPF_STRICT_ALL) < 0) {
@@ -653,24 +674,25 @@ int main(int argc, char **argv)
653674
goto end_destroy;
654675
}
655676

656-
if (get_route_table(AF_INET) < 0) {
657-
fprintf(stderr, "Failed reading routing table\n");
677+
ret = pthread_create(&routes_thread, NULL, monitor_routes_thread, NULL);
678+
if (ret) {
679+
fprintf(stderr, "Failed creating routes_thread: %s\n", strerror(-ret));
680+
ret = EXIT_FAIL;
658681
goto end_destroy;
659682
}
660683

661-
if (get_arp_table(AF_INET) < 0) {
662-
fprintf(stderr, "Failed reading arptable\n");
663-
goto end_destroy;
664-
}
684+
ret = sample_run(interval, NULL, NULL);
685+
routes_thread_exit = true;
665686

666-
ret = sample_run(interval, monitor_route, NULL);
667687
if (ret < 0) {
668688
fprintf(stderr, "Failed during sample run: %s\n", strerror(-ret));
669689
ret = EXIT_FAIL;
670-
goto end_destroy;
690+
goto end_thread_wait;
671691
}
672692
ret = EXIT_OK;
673693

694+
end_thread_wait:
695+
pthread_join(routes_thread, NULL);
674696
end_destroy:
675697
xdp_router_ipv4__destroy(skel);
676698
end:

0 commit comments

Comments
 (0)