2525typedef enum {
2626 COMMAND_ADD = 0 ,
2727 COMMAND_DEL ,
28+ COMMAND_LIST ,
2829 COMMAND_UNUSED ,
2930} command_e ;
3031
@@ -58,12 +59,14 @@ typedef int (*command_call_pt)(options_t *);
5859
5960static int do_add_cmd (options_t * opt );
6061static int do_del_cmd (options_t * opt );
62+ static int do_list_cmd (options_t * opt );
6163
6264
6365// declare command function
6466static command_call_pt commands [] = {
6567 do_add_cmd ,
6668 do_del_cmd ,
69+ do_list_cmd ,
6770};
6871
6972
@@ -87,17 +90,18 @@ static void
8790show_usage (const char * name )
8891{
8992 const char * program_doc_fmt =
90- "Usage: %s cmd [rule]\n"
91- "\n"
92- "Commands:\n"
93- " -a cidr Add IP rule use, with -p 'action'\n"
94- " -d cidr Delete IP rule\n"
95- " -p action Apply action. support allow|deny\n"
96- " -h Print this help information\n"
97- "\n"
98- "Examples:\n"
99- " %s -a 192.168.1.0/24 -p allow\n"
100- " %s -d ::ffff:c612:13/128\n" ;
93+ "Usage: %s cmd [rule]\n"
94+ "\n"
95+ "Commands:\n"
96+ " -a cidr Add IP rule use, with -p 'action'\n"
97+ " -d cidr Delete IP rule\n"
98+ " -p action Apply action. support allow|deny\n"
99+ " -l List all IP rules\n"
100+ " -h Print this help information\n"
101+ "\n"
102+ "Examples:\n"
103+ " %s -a 192.168.1.0/24 -p allow\n"
104+ " %s -d ::ffff:c612:13/128\n" ;
101105
102106 printf (program_doc_fmt , name , name , name );
103107}
@@ -198,7 +202,7 @@ parse_cmdline(int argc, char *argv[], options_t *opt)
198202 int c ;
199203 char * err ;
200204
201- while ((c = getopt (argc , argv , "a:d:p:h " )) != -1 ) {
205+ while ((c = getopt (argc , argv , "a:d:p:lh " )) != -1 ) {
202206 switch (c ) {
203207 case 'a' :
204208 if (parse_cidr (optarg , & opt -> cidr , & err ) != 0 ) {
@@ -225,6 +229,10 @@ parse_cmdline(int argc, char *argv[], options_t *opt)
225229 }
226230 break ;
227231
232+ case 'l' :
233+ opt -> cmd = COMMAND_LIST ;
234+ break ;
235+
228236 case 'h' :
229237 show_usage (basename (argv [0 ]));
230238 exit (EXIT_SUCCESS );
@@ -298,12 +306,12 @@ do_add_cmd(options_t *opt)
298306 if (bpf_map_update_elem (fd , lpm , & opt -> action , BPF_ANY ) != 0 ) {
299307 log_err ("Failed to update bpf map item err(%d):%s\n" ,
300308 errno , strerror (errno ));
301- goto cleanup ;
309+ goto fail ;
302310 }
303311
304312 rc = 0 ;
305313
306- cleanup :
314+ fail :
307315
308316 free (lpm );
309317 close (fd );
@@ -341,12 +349,12 @@ do_del_cmd(options_t *opt)
341349 if (bpf_map_delete_elem (fd , lpm ) != 0 ) {
342350 log_err ("Failed to delete bpf map item err(%d):%s\n" ,
343351 errno , strerror (errno ));
344- goto cleanup ;
352+ goto fail ;
345353 }
346354
347355 rc = 0 ;
348356
349- cleanup :
357+ fail :
350358
351359 free (lpm );
352360 close (fd );
@@ -355,6 +363,103 @@ do_del_cmd(options_t *opt)
355363}
356364
357365
366+ static const char *
367+ action_str (enum xdp_action action )
368+ {
369+ switch (action ) {
370+ case XDP_PASS :
371+ return "allow" ;
372+
373+ case XDP_DROP :
374+ return "deny" ;
375+
376+ default :
377+ return "unknown" ;
378+ }
379+ }
380+
381+
382+ static int
383+ dump_rules (int af )
384+ {
385+ struct bpf_lpm_trie_key * key ;
386+ enum xdp_action action ;
387+ char buf [INET6_ADDRSTRLEN ];
388+ const char * p ;
389+ int rc , map_fd ;
390+
391+ key = NULL ;
392+ rc = map_fd = -1 ;
393+
394+ key = calloc (1 , sizeof (* key ) + sizeof (struct in6_addr ));
395+ if (key == NULL ) {
396+ log_err ("Failed to calloc, err(%d):%s\n" , errno , strerror (errno ));
397+ goto fail ;
398+ }
399+
400+ map_fd = open_bpf_map (af );
401+ if (map_fd == -1 ) {
402+ log_err ("Failed to open bpf map file, err(%d):%s\n" ,
403+ errno , strerror (errno ));
404+
405+ goto fail ;
406+ }
407+
408+ while (bpf_map_get_next_key (map_fd , key , key ) == 0 ) {
409+ if (bpf_map_lookup_elem (map_fd , key , & action )) {
410+ if (errno == ENOENT ) {
411+ continue ;
412+ }
413+
414+ log_err ("map lookup error: %s\n" , strerror (errno ));
415+ goto fail ;
416+ }
417+
418+ p = inet_ntop (af , key -> data , buf , INET6_ADDRSTRLEN );
419+ if (p == NULL ) {
420+ log_err ("inet_ntop error: %s\n" , strerror (errno ));
421+ goto fail ;
422+ }
423+
424+ printf (" %s/%d -> %s\n" , p , key -> prefixlen , action_str (action ));
425+ }
426+
427+ rc = 0 ;
428+
429+ fail :
430+ if (map_fd != -1 ) {
431+ close (map_fd );
432+ }
433+
434+ if (key != NULL ) {
435+ free (key );
436+ }
437+
438+ return rc ;
439+ }
440+
441+
442+ static int
443+ do_list_cmd (options_t * opt )
444+ {
445+ printf ("IPv4 Rule List:\n" );
446+ if (dump_rules (AF_INET ) != 0 ) {
447+ return -1 ;
448+ }
449+
450+ printf ("\n" );
451+
452+ printf ("IPv6 Rule List:\n" );
453+ if (dump_rules (AF_INET6 ) != 0 ) {
454+ return -1 ;
455+ }
456+
457+ printf ("\n" );
458+
459+ return 0 ;
460+ }
461+
462+
358463int
359464main (int argc , char * argv [])
360465{
0 commit comments