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;
3839static int exact_match_map_fd ;
3940static int tx_port_map_fd ;
4041
42+ static bool routes_thread_exit ;
43+ static int interval = 5 ;
44+
4145static 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
519538cleanup :
520539 close (sock_arp );
521540 close (sock );
541+ return NULL ;
522542}
523543
524544static void usage (char * argv [], const struct option * long_options ,
@@ -531,10 +551,11 @@ static void usage(char *argv[], const struct option *long_options,
531551int 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 );
674696end_destroy :
675697 xdp_router_ipv4__destroy (skel );
676698end :
0 commit comments