25
25
#include <sys/resource.h>
26
26
#include <libgen.h>
27
27
#include <getopt.h>
28
+ #include <pthread.h>
28
29
#include "xdp_sample_user.h"
29
30
#include "xdp_router_ipv4.skel.h"
30
31
@@ -38,6 +39,9 @@ static int arp_table_map_fd;
38
39
static int exact_match_map_fd ;
39
40
static int tx_port_map_fd ;
40
41
42
+ static bool routes_thread_exit ;
43
+ static int interval = 5 ;
44
+
41
45
static int mask = SAMPLE_RX_CNT | SAMPLE_REDIRECT_ERR_MAP_CNT |
42
46
SAMPLE_DEVMAP_XMIT_CNT_MULTI | SAMPLE_EXCEPTION_CNT ;
43
47
@@ -445,7 +449,7 @@ static int get_arp_table(int rtm_family)
445
449
/* Function to keep track and update changes in route and arp table
446
450
* Give regular statistics of packets forwarded
447
451
*/
448
- static void monitor_route (void * ctx )
452
+ static void * monitor_routes_thread (void * arg )
449
453
{
450
454
struct pollfd fds_route , fds_arp ;
451
455
struct sockaddr_nl la , lr ;
@@ -455,7 +459,7 @@ static void monitor_route(void *ctx)
455
459
sock = socket (AF_NETLINK , SOCK_RAW , NETLINK_ROUTE );
456
460
if (sock < 0 ) {
457
461
fprintf (stderr , "open netlink socket: %s\n" , strerror (errno ));
458
- return ;
462
+ return NULL ;
459
463
}
460
464
461
465
fcntl (sock , F_SETFL , O_NONBLOCK );
@@ -465,7 +469,7 @@ static void monitor_route(void *ctx)
465
469
if (bind (sock , (struct sockaddr * )& lr , sizeof (lr )) < 0 ) {
466
470
fprintf (stderr , "bind netlink socket: %s\n" , strerror (errno ));
467
471
close (sock );
468
- return ;
472
+ return NULL ;
469
473
}
470
474
471
475
fds_route .fd = sock ;
@@ -475,7 +479,7 @@ static void monitor_route(void *ctx)
475
479
if (sock_arp < 0 ) {
476
480
fprintf (stderr , "open netlink socket: %s\n" , strerror (errno ));
477
481
close (sock );
478
- return ;
482
+ return NULL ;
479
483
}
480
484
481
485
fcntl (sock_arp , F_SETFL , O_NONBLOCK );
@@ -490,35 +494,51 @@ static void monitor_route(void *ctx)
490
494
fds_arp .fd = sock_arp ;
491
495
fds_arp .events = POLL_IN ;
492
496
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
+ }
501
502
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 ;
504
506
}
505
507
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 );
513
520
}
514
521
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 );
517
536
}
518
537
519
538
cleanup :
520
539
close (sock_arp );
521
540
close (sock );
541
+ return NULL ;
522
542
}
523
543
524
544
static void usage (char * argv [], const struct option * long_options ,
@@ -531,10 +551,11 @@ static void usage(char *argv[], const struct option *long_options,
531
551
int main (int argc , char * * argv )
532
552
{
533
553
bool error = true, generic = false, force = false;
534
- int opt , interval = 5 , ret = EXIT_FAIL_BPF ;
554
+ int opt , ret = EXIT_FAIL_BPF ;
535
555
struct xdp_router_ipv4 * skel ;
536
556
int i , total_ifindex = argc - 1 ;
537
557
char * * ifname_list = argv + 1 ;
558
+ pthread_t routes_thread ;
538
559
int longindex = 0 ;
539
560
540
561
if (libbpf_set_strict_mode (LIBBPF_STRICT_ALL ) < 0 ) {
@@ -653,24 +674,25 @@ int main(int argc, char **argv)
653
674
goto end_destroy ;
654
675
}
655
676
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 ;
658
681
goto end_destroy ;
659
682
}
660
683
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;
665
686
666
- ret = sample_run (interval , monitor_route , NULL );
667
687
if (ret < 0 ) {
668
688
fprintf (stderr , "Failed during sample run: %s\n" , strerror (- ret ));
669
689
ret = EXIT_FAIL ;
670
- goto end_destroy ;
690
+ goto end_thread_wait ;
671
691
}
672
692
ret = EXIT_OK ;
673
693
694
+ end_thread_wait :
695
+ pthread_join (routes_thread , NULL );
674
696
end_destroy :
675
697
xdp_router_ipv4__destroy (skel );
676
698
end :
0 commit comments