Skip to content

Commit 43afc2e

Browse files
authored
add dump rules (#4)
Signed-off-by: Xiaobo Liu <cppcoffee@gmail.com>
1 parent 8c92398 commit 43afc2e

File tree

3 files changed

+140
-28
lines changed

3 files changed

+140
-28
lines changed

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,13 @@ $ ./ipblock-rule -d 192.168.31.0/24
6464
```
6565

6666

67+
#### List rules
68+
69+
```shell
70+
$ ./ipblock-rule -l
71+
```
72+
73+
6774
### Reference
6875

6976
[BPF and XDP Reference Guide](https://docs.cilium.io/en/v1.10/bpf/)

src/loader.c

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -80,18 +80,18 @@ static void
8080
show_usage(const char *prog_name)
8181
{
8282
const char program_doc_fmt[] =
83-
"Usage: %s (options)\n"
84-
"\n"
85-
"Options:\n"
86-
" -d dev Operate on device <ifname>\n"
87-
" -u Unload XDP program instead of loading\n"
88-
" -A Auto mode. default mode\n"
89-
" -S Skb mode\n"
90-
" -N Native mode\n"
91-
" -O Offload mode\n"
92-
" -F Force install, replacing existing program on interface\n"
93-
" -D Debug output\n"
94-
" -h Print this help information\n";
83+
"Usage: %s (options)\n"
84+
"\n"
85+
"Options:\n"
86+
" -d dev Operate on device <ifname>\n"
87+
" -u Unload XDP program instead of loading\n"
88+
" -A Auto mode. default mode\n"
89+
" -S Skb mode\n"
90+
" -N Native mode\n"
91+
" -O Offload mode\n"
92+
" -F Force install, replacing existing program on interface\n"
93+
" -D Debug output\n"
94+
" -h Print this help information\n";
9595

9696
printf(program_doc_fmt, prog_name);
9797
}

src/rule.c

Lines changed: 121 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
typedef 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

5960
static int do_add_cmd(options_t *opt);
6061
static int do_del_cmd(options_t *opt);
62+
static int do_list_cmd(options_t *opt);
6163

6264

6365
// declare command function
6466
static 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
8790
show_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+
358463
int
359464
main(int argc, char *argv[])
360465
{

0 commit comments

Comments
 (0)