aboutsummaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2018-01-18 18:08:51 -0500
committerDaniel Borkmann <daniel@iogearbox.net>2018-01-19 17:26:41 -0500
commit8c417dc15f9522672795981dcb63d9099ca6bd8c (patch)
treeb6d14d27dd9c79219b79291db99683a4ba8b9f07 /tools
parentb471f2f1de8b816f1e799b80aa92588f3566e4bd (diff)
tools/bpf: add a testcase for MAP_GET_NEXT_KEY command of LPM_TRIE map
A test case is added in tools/testing/selftests/bpf/test_lpm_map.c for MAP_GET_NEXT_KEY command. A four node trie, which is described in kernel/bpf/lpm_trie.c, is built and the MAP_GET_NEXT_KEY results are checked. Signed-off-by: Yonghong Song <yhs@fb.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Diffstat (limited to 'tools')
-rw-r--r--tools/testing/selftests/bpf/test_lpm_map.c122
1 files changed, 122 insertions, 0 deletions
diff --git a/tools/testing/selftests/bpf/test_lpm_map.c b/tools/testing/selftests/bpf/test_lpm_map.c
index f61480641b6e..081510853c6d 100644
--- a/tools/testing/selftests/bpf/test_lpm_map.c
+++ b/tools/testing/selftests/bpf/test_lpm_map.c
@@ -521,6 +521,126 @@ static void test_lpm_delete(void)
521 close(map_fd); 521 close(map_fd);
522} 522}
523 523
524static void test_lpm_get_next_key(void)
525{
526 struct bpf_lpm_trie_key *key_p, *next_key_p;
527 size_t key_size;
528 __u32 value = 0;
529 int map_fd;
530
531 key_size = sizeof(*key_p) + sizeof(__u32);
532 key_p = alloca(key_size);
533 next_key_p = alloca(key_size);
534
535 map_fd = bpf_create_map(BPF_MAP_TYPE_LPM_TRIE, key_size, sizeof(value),
536 100, BPF_F_NO_PREALLOC);
537 assert(map_fd >= 0);
538
539 /* empty tree. get_next_key should return ENOENT */
540 assert(bpf_map_get_next_key(map_fd, NULL, key_p) == -1 &&
541 errno == ENOENT);
542
543 /* get and verify the first key, get the second one should fail. */
544 key_p->prefixlen = 16;
545 inet_pton(AF_INET, "192.168.0.0", key_p->data);
546 assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0);
547
548 memset(key_p, 0, key_size);
549 assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0);
550 assert(key_p->prefixlen == 16 && key_p->data[0] == 192 &&
551 key_p->data[1] == 168);
552
553 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == -1 &&
554 errno == ENOENT);
555
556 /* no exact matching key should get the first one in post order. */
557 key_p->prefixlen = 8;
558 assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0);
559 assert(key_p->prefixlen == 16 && key_p->data[0] == 192 &&
560 key_p->data[1] == 168);
561
562 /* add one more element (total two) */
563 key_p->prefixlen = 24;
564 inet_pton(AF_INET, "192.168.0.0", key_p->data);
565 assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0);
566
567 memset(key_p, 0, key_size);
568 assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0);
569 assert(key_p->prefixlen == 24 && key_p->data[0] == 192 &&
570 key_p->data[1] == 168 && key_p->data[2] == 0);
571
572 memset(next_key_p, 0, key_size);
573 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
574 assert(next_key_p->prefixlen == 16 && next_key_p->data[0] == 192 &&
575 next_key_p->data[1] == 168);
576
577 memcpy(key_p, next_key_p, key_size);
578 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == -1 &&
579 errno == ENOENT);
580
581 /* Add one more element (total three) */
582 key_p->prefixlen = 24;
583 inet_pton(AF_INET, "192.168.128.0", key_p->data);
584 assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0);
585
586 memset(key_p, 0, key_size);
587 assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0);
588 assert(key_p->prefixlen == 24 && key_p->data[0] == 192 &&
589 key_p->data[1] == 168 && key_p->data[2] == 0);
590
591 memset(next_key_p, 0, key_size);
592 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
593 assert(next_key_p->prefixlen == 24 && next_key_p->data[0] == 192 &&
594 next_key_p->data[1] == 168 && next_key_p->data[2] == 128);
595
596 memcpy(key_p, next_key_p, key_size);
597 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
598 assert(next_key_p->prefixlen == 16 && next_key_p->data[0] == 192 &&
599 next_key_p->data[1] == 168);
600
601 memcpy(key_p, next_key_p, key_size);
602 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == -1 &&
603 errno == ENOENT);
604
605 /* Add one more element (total four) */
606 key_p->prefixlen = 24;
607 inet_pton(AF_INET, "192.168.1.0", key_p->data);
608 assert(bpf_map_update_elem(map_fd, key_p, &value, 0) == 0);
609
610 memset(key_p, 0, key_size);
611 assert(bpf_map_get_next_key(map_fd, NULL, key_p) == 0);
612 assert(key_p->prefixlen == 24 && key_p->data[0] == 192 &&
613 key_p->data[1] == 168 && key_p->data[2] == 0);
614
615 memset(next_key_p, 0, key_size);
616 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
617 assert(next_key_p->prefixlen == 24 && next_key_p->data[0] == 192 &&
618 next_key_p->data[1] == 168 && next_key_p->data[2] == 1);
619
620 memcpy(key_p, next_key_p, key_size);
621 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
622 assert(next_key_p->prefixlen == 24 && next_key_p->data[0] == 192 &&
623 next_key_p->data[1] == 168 && next_key_p->data[2] == 128);
624
625 memcpy(key_p, next_key_p, key_size);
626 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
627 assert(next_key_p->prefixlen == 16 && next_key_p->data[0] == 192 &&
628 next_key_p->data[1] == 168);
629
630 memcpy(key_p, next_key_p, key_size);
631 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == -1 &&
632 errno == ENOENT);
633
634 /* no exact matching key should return the first one in post order */
635 key_p->prefixlen = 22;
636 inet_pton(AF_INET, "192.168.1.0", key_p->data);
637 assert(bpf_map_get_next_key(map_fd, key_p, next_key_p) == 0);
638 assert(next_key_p->prefixlen == 24 && next_key_p->data[0] == 192 &&
639 next_key_p->data[1] == 168 && next_key_p->data[2] == 0);
640
641 close(map_fd);
642}
643
524int main(void) 644int main(void)
525{ 645{
526 struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY }; 646 struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY };
@@ -545,6 +665,8 @@ int main(void)
545 665
546 test_lpm_delete(); 666 test_lpm_delete();
547 667
668 test_lpm_get_next_key();
669
548 printf("test_lpm: OK\n"); 670 printf("test_lpm: OK\n");
549 return 0; 671 return 0;
550} 672}