summaryrefslogtreecommitdiff
path: root/nest
diff options
context:
space:
mode:
Diffstat (limited to 'nest')
-rw-r--r--nest/Makefile4
-rw-r--r--nest/a-path.c3
-rw-r--r--nest/a-path_test.c214
-rw-r--r--nest/a-set_test.c260
-rw-r--r--nest/iface.h1
-rw-r--r--nest/route.h2
6 files changed, 481 insertions, 3 deletions
diff --git a/nest/Makefile b/nest/Makefile
index 6f0f9a08..d673cee5 100644
--- a/nest/Makefile
+++ b/nest/Makefile
@@ -2,3 +2,7 @@ src := a-path.c a-set.c cli.c cmds.c iface.c locks.c neighbor.c password.c proto
obj := $(src-o-files)
$(all-daemon)
$(cf-local)
+
+tests_src := a-set_test.c a-path_test.c
+tests_targets := $(tests_targets) $(tests-target-files)
+tests_objs := $(tests_objs) $(src-o-files)
diff --git a/nest/a-path.c b/nest/a-path.c
index b453f702..bc2216a0 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -20,7 +20,7 @@
#define put_as put_u32
#define get_as get_u32
-#define BS 4
+#define BS 4 /* Base (default) size of ASN (autonomous system number) */
struct adata *
as_path_prepend(struct linpool *pool, struct adata *olda, u32 as)
@@ -499,7 +499,6 @@ pm_mark(struct pm_pos *pos, int i, int plen, int *nl, int *nh)
* (auxiliary position after last real position in AS path)
* is marked.
*/
-
int
as_path_match(struct adata *path, struct f_path_mask *mask)
{
diff --git a/nest/a-path_test.c b/nest/a-path_test.c
new file mode 100644
index 00000000..2dc46dbe
--- /dev/null
+++ b/nest/a-path_test.c
@@ -0,0 +1,214 @@
+/*
+ * BIRD -- Path Operations Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "test/bt-utils.h"
+
+#include "nest/route.h"
+#include "nest/attrs.h"
+#include "lib/resource.h"
+
+#define TESTS_NUM 30
+#define AS_PATH_LENGTH 1000
+
+#if AS_PATH_LENGTH > AS_PATH_MAXLEN
+#warning "AS_PATH_LENGTH should be <= AS_PATH_MAXLEN"
+#endif
+
+static int
+t_as_path_match(void)
+{
+ resource_init();
+
+ int round;
+ for (round = 0; round < TESTS_NUM; round++)
+ {
+ struct adata empty_as_path = {};
+ struct adata *as_path = &empty_as_path;
+ u32 first_prepended, last_prepended;
+ first_prepended = last_prepended = 0;
+ struct linpool *lp = lp_new(&root_pool, 0);
+
+ struct f_path_mask mask[AS_PATH_LENGTH] = {};
+ int i;
+ for (i = 0; i < AS_PATH_LENGTH; i++)
+ {
+ u32 val = bt_random();
+ as_path = as_path_prepend(lp, as_path, val);
+ bt_debug("Prepending ASN: %10u \n", val);
+
+ if (i == 0)
+ first_prepended = val;
+ if (i == AS_PATH_LENGTH-1)
+ last_prepended = val;
+
+ mask[i].kind = PM_ASN;
+ mask[i].val = val;
+ if (i)
+ mask[i].next = &mask[i-1];
+ }
+
+ bt_assert_msg(as_path_match(as_path, &mask[AS_PATH_LENGTH-1]), "Mask should match with AS path");
+
+ u32 asn;
+
+ bt_assert(as_path_get_first(as_path, &asn));
+ bt_assert_msg(asn == last_prepended, "as_path_get_first() should return the last prepended ASN");
+
+ bt_assert(as_path_get_last(as_path, &asn));
+ bt_assert_msg(asn == first_prepended, "as_path_get_last() should return the first prepended ASN");
+
+ rfree(lp);
+ }
+
+ return BT_SUCCESS;
+}
+
+static int
+t_path_format(void)
+{
+ resource_init();
+
+ struct adata empty_as_path = {};
+ struct adata *as_path = &empty_as_path;
+ struct linpool *lp = lp_new(&root_pool, 0);
+
+ uint i;
+ for (i = 4294967285; i <= 4294967294; i++)
+ {
+ as_path = as_path_prepend(lp, as_path, i);
+ bt_debug("Prepending ASN: %10u \n", i);
+ }
+
+#define BUFFER_SIZE 26
+ byte buf[BUFFER_SIZE] = {};
+ as_path_format(as_path, buf, BUFFER_SIZE);
+ bt_assert_msg(strcmp(buf, "4294967294 4294967293 ...") == 0, "Buffer(%zu): '%s'", strlen(buf), buf);
+
+#define SMALL_BUFFER_SIZE 25
+ byte buf2[SMALL_BUFFER_SIZE] = {};
+ as_path_format(as_path, buf2, SMALL_BUFFER_SIZE);
+ bt_assert_msg(strcmp(buf2, "4294967294 ...") == 0, "Small Buffer(%zu): '%s'", strlen(buf2), buf2);
+
+ rfree(lp);
+
+ return BT_SUCCESS;
+}
+
+static int
+count_asn_in_array(const u32 *array, u32 asn)
+{
+ int counts_of_contains = 0;
+ int u;
+ for (u = 0; u < AS_PATH_LENGTH; u++)
+ if (array[u] == asn)
+ counts_of_contains++;
+ return counts_of_contains;
+}
+
+static int
+t_path_include(void)
+{
+ resource_init();
+
+ struct adata empty_as_path = {};
+ struct adata *as_path = &empty_as_path;
+ struct linpool *lp = lp_new(&root_pool, 0);
+
+ u32 as_nums[AS_PATH_LENGTH] = {};
+ int i;
+ for (i = 0; i < AS_PATH_LENGTH; i++)
+ {
+ u32 val = bt_random();
+ as_nums[i] = val;
+ as_path = as_path_prepend(lp, as_path, val);
+ }
+
+ for (i = 0; i < AS_PATH_LENGTH; i++)
+ {
+ int counts_of_contains = count_asn_in_array(as_nums, as_nums[i]);
+ bt_assert_msg(as_path_contains(as_path, as_nums[i], counts_of_contains), "AS Path should contains %d-times number %d", counts_of_contains, as_nums[i]);
+
+ bt_assert(as_path_filter(lp, as_path, NULL, as_nums[i], 0) != NULL);
+ bt_assert(as_path_filter(lp, as_path, NULL, as_nums[i], 1) != NULL);
+ }
+
+ for (i = 0; i < 10000; i++)
+ {
+ u32 test_val = bt_random();
+ int counts_of_contains = count_asn_in_array(as_nums, test_val);
+ int result = as_path_contains(as_path, test_val, (counts_of_contains == 0 ? 1 : counts_of_contains));
+
+ if (counts_of_contains)
+ bt_assert_msg(result, "As path should contain %d-times the number %u", counts_of_contains, test_val);
+ else
+ bt_assert_msg(result == 0, "As path should not contain the number %u", test_val);
+ }
+
+ rfree(lp);
+
+ return BT_SUCCESS;
+}
+
+static int
+t_as_path_converting(void)
+{
+ resource_init();
+
+ struct adata empty_as_path = {};
+ struct adata *as_path = &empty_as_path;
+ struct linpool *lp = lp_new(&root_pool, 0);
+#define AS_PATH_LENGTH_FOR_CONVERTING_TEST 10
+
+ int i;
+ for (i = 0; i < AS_PATH_LENGTH_FOR_CONVERTING_TEST; i++)
+ as_path = as_path_prepend(lp, as_path, i);
+
+ bt_debug("data length: %u \n", as_path->length);
+
+ byte buffer[100] = {};
+ int used_size = as_path_convert_to_new(as_path, buffer, AS_PATH_LENGTH_FOR_CONVERTING_TEST-1);
+ bt_debug("as_path_convert_to_new: len %d \n%s\n", used_size, buffer);
+ for (i = 0; i < used_size; i++)
+ {
+ bt_debug("\\03%d", buffer[i]);
+ }
+ bt_debug("\n");
+ bt_assert(memcmp(buffer,
+ "\032\039\030\030\030\030\030\030\030\039\030\030\030\030\030\030\030\038\030\030\030\030\030\030"
+ "\030\037\030\030\030\030\030\030\030\036\030\030\030\030",
+ 38));
+
+ bzero(buffer, sizeof(buffer));
+ int new_used;
+ used_size = as_path_convert_to_old(as_path, buffer, &new_used);
+ bt_debug("as_path_convert_to_old: len %d, new_used: %d \n", used_size, new_used);
+ for (i = 0; i < used_size; i++)
+ {
+ bt_debug("\\03%d", buffer[i]);
+ }
+ bt_debug("\n");
+ bt_assert(memcmp(buffer,
+ "\032\0310\030\039\030\038\030\037\030\036\030\035\030\034\030\033\030\032\030\031\030\030",
+ 22));
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_as_path_match, "Testing AS path matching and some a-path utilities.");
+ bt_test_suite(t_path_format, "Testing formating as path into byte buffer");
+ bt_test_suite(t_path_include, "Testing including a AS number in AS path");
+ bt_test_suite(t_as_path_converting, "Testing as_path_convert_to_*() output constancy");
+
+ return bt_exit_value();
+}
diff --git a/nest/a-set_test.c b/nest/a-set_test.c
new file mode 100644
index 00000000..763b6b9f
--- /dev/null
+++ b/nest/a-set_test.c
@@ -0,0 +1,260 @@
+/*
+ * BIRD -- Set/Community-list Operations Tests
+ *
+ * (c) 2015 CZ.NIC z.s.p.o.
+ *
+ * Can be freely distributed and used under the terms of the GNU GPL.
+ */
+
+#include "test/birdtest.h"
+#include "test/bt-utils.h"
+
+#include "lib/net.h"
+#include "nest/route.h"
+#include "nest/attrs.h"
+#include "lib/resource.h"
+
+#define SET_SIZE 10
+static struct adata *set_sequence; /* <0; SET_SIZE) */
+static struct adata *set_sequence_same; /* <0; SET_SIZE) */
+static struct adata *set_sequence_higher; /* <SET_SIZE; 2*SET_SIZE) */
+static struct adata *set_random;
+
+#define BUFFER_SIZE 1000
+static byte buf[BUFFER_SIZE] = {};
+
+#define SET_SIZE_FOR_FORMAT_OUTPUT 10
+
+struct linpool *lp;
+
+enum set_type
+{
+ SET_TYPE_INT,
+ SET_TYPE_EC
+};
+
+static void
+generate_set_sequence(enum set_type type)
+{
+ struct adata empty_as_path = {};
+ set_sequence = set_sequence_same = set_sequence_higher = set_random = &empty_as_path;
+ lp = lp_new(&root_pool, 0);
+
+ int i;
+ for (i = 0; i < SET_SIZE; i++)
+ {
+ if (type == SET_TYPE_INT)
+ {
+ set_sequence = int_set_add(lp, set_sequence, i);
+ set_sequence_same = int_set_add(lp, set_sequence_same, i);
+ set_sequence_higher = int_set_add(lp, set_sequence_higher, i + SET_SIZE);
+ set_random = int_set_add(lp, set_random, bt_random());
+ }
+ else if (type == SET_TYPE_EC)
+ {
+ set_sequence = ec_set_add(lp, set_sequence, i);
+ set_sequence_same = ec_set_add(lp, set_sequence_same, i);
+ set_sequence_higher = ec_set_add(lp, set_sequence_higher, i + SET_SIZE);
+ set_random = ec_set_add(lp, set_random, (bt_random() << 32 | bt_random()));
+ }
+ else
+ bt_abort_msg("This should be unreachable");
+ }
+}
+
+/*
+ * SET INT TESTS
+ */
+
+static int
+t_set_int_contains(void)
+{
+ int i;
+
+ resource_init();
+ generate_set_sequence(SET_TYPE_INT);
+
+ bt_assert(int_set_get_size(set_sequence) == SET_SIZE);
+
+ for (i = 0; i < SET_SIZE; i++)
+ bt_assert(int_set_contains(set_sequence, i));
+ bt_assert(int_set_contains(set_sequence, -1) == 0);
+ bt_assert(int_set_contains(set_sequence, SET_SIZE) == 0);
+
+ int *data = int_set_get_data(set_sequence);
+ for (i = 0; i < SET_SIZE; i++)
+ bt_assert_msg(data[i] == i, "(data[i] = %d) == i = %d)", data[i], i);
+
+ rfree(lp);
+ return BT_SUCCESS;
+}
+
+static int
+t_set_int_union(void)
+{
+ resource_init();
+ generate_set_sequence(SET_TYPE_INT);
+
+ struct adata *set_union;
+ set_union = int_set_union(lp, set_sequence, set_sequence_same);
+ bt_assert(int_set_get_size(set_union) == SET_SIZE);
+ bt_assert(int_set_format(set_union, 0, 2, buf, BUFFER_SIZE) == 0);
+
+ set_union = int_set_union(lp, set_sequence, set_sequence_higher);
+ bt_assert_msg(int_set_get_size(set_union) == SET_SIZE*2, "int_set_get_size(set_union) %d, SET_SIZE*2 %d", int_set_get_size(set_union), SET_SIZE*2);
+ bt_assert(int_set_format(set_union, 0, 2, buf, BUFFER_SIZE) == 0);
+
+ rfree(lp);
+ return BT_SUCCESS;
+}
+
+static int
+t_set_int_format(void)
+{
+ resource_init();
+ generate_set_sequence(SET_TYPE_INT);
+
+ set_sequence->length = 4 * SET_SIZE_FOR_FORMAT_OUTPUT; /* dirty */
+ bt_assert(int_set_format(set_sequence, 0, 0, buf, BUFFER_SIZE) == 0);
+ bt_assert(strcmp(buf, "0.0.0.0 0.0.0.1 0.0.0.2 0.0.0.3 0.0.0.4 0.0.0.5 0.0.0.6 0.0.0.7 0.0.0.8 0.0.0.9") == 0);
+
+ bzero(buf, BUFFER_SIZE);
+ bt_assert(int_set_format(set_sequence, 0, 2, buf, BUFFER_SIZE) == 0);
+ bt_assert(strcmp(buf, "0.0.0.2 0.0.0.3 0.0.0.4 0.0.0.5 0.0.0.6 0.0.0.7 0.0.0.8 0.0.0.9") == 0);
+
+ bzero(buf, BUFFER_SIZE);
+ bt_assert(int_set_format(set_sequence, 1, 0, buf, BUFFER_SIZE) == 0);
+ bt_assert(strcmp(buf, "(0,0) (0,1) (0,2) (0,3) (0,4) (0,5) (0,6) (0,7) (0,8) (0,9)") == 0);
+
+ rfree(lp);
+ return BT_SUCCESS;
+}
+
+static int
+t_set_int_delete(void)
+{
+ resource_init();
+ generate_set_sequence(SET_TYPE_INT);
+
+ struct adata *deleting_sequence = set_sequence;
+ u32 i;
+ for (i = 0; i < SET_SIZE; i++)
+ {
+ deleting_sequence = int_set_del(lp, deleting_sequence, i);
+ bt_assert_msg(int_set_get_size(deleting_sequence) == (int) (SET_SIZE-1-i),
+ "int_set_get_size(deleting_sequence) %d == SET_SIZE-1-i %d",
+ int_set_get_size(deleting_sequence),
+ SET_SIZE-1-i);
+ }
+
+ bt_assert(int_set_get_size(set_sequence) == SET_SIZE);
+
+ return BT_SUCCESS;
+}
+
+/*
+ * SET EC TESTS
+ */
+
+static int
+t_set_ec_contains(void)
+{
+ u32 i;
+
+ resource_init();
+ generate_set_sequence(SET_TYPE_EC);
+
+ bt_assert(ec_set_get_size(set_sequence) == SET_SIZE);
+
+ for (i = 0; i < SET_SIZE; i++)
+ bt_assert(ec_set_contains(set_sequence, i));
+ bt_assert(ec_set_contains(set_sequence, -1) == 0);
+ bt_assert(ec_set_contains(set_sequence, SET_SIZE) == 0);
+
+// int *data = ec_set_get_data(set_sequence);
+// for (i = 0; i < SET_SIZE; i++)
+// bt_assert_msg(data[i] == (SET_SIZE-1-i), "(data[i] = %d) == ((SET_SIZE-1-i) = %d)", data[i], SET_SIZE-1-i);
+
+ rfree(lp);
+ return BT_SUCCESS;
+}
+
+static int
+t_set_ec_union(void)
+{
+ resource_init();
+ generate_set_sequence(SET_TYPE_EC);
+
+ struct adata *set_union;
+ set_union = ec_set_union(lp, set_sequence, set_sequence_same);
+ bt_assert(ec_set_get_size(set_union) == SET_SIZE);
+ bt_assert(ec_set_format(set_union, 0, buf, BUFFER_SIZE) == 0);
+
+ set_union = ec_set_union(lp, set_sequence, set_sequence_higher);
+ bt_assert_msg(ec_set_get_size(set_union) == SET_SIZE*2, "ec_set_get_size(set_union) %d, SET_SIZE*2 %d", ec_set_get_size(set_union), SET_SIZE*2);
+ bt_assert(ec_set_format(set_union, 0, buf, BUFFER_SIZE) == 0);
+
+ rfree(lp);
+ return BT_SUCCESS;
+}
+
+static int
+t_set_ec_format(void)
+{
+ resource_init();
+
+ struct adata empty_as_path = {};
+ set_sequence = set_sequence_same = set_sequence_higher = set_random = &empty_as_path;
+ lp = lp_new(&root_pool, 0);
+
+ u64 i = 0;
+ set_sequence = ec_set_add(lp, set_sequence, i);
+ for (i = 1; i < SET_SIZE_FOR_FORMAT_OUTPUT; i++)
+ set_sequence = ec_set_add(lp, set_sequence, i + ((i%2) ? ((u64)EC_RO << 48) : ((u64)EC_RT << 48)));
+
+ bt_assert(ec_set_format(set_sequence, 0, buf, BUFFER_SIZE) == 0);
+ bt_assert_msg(strcmp(buf, "(unknown 0x0, 0, 0) (ro, 0, 1) (rt, 0, 2) (ro, 0, 3) (rt, 0, 4) (ro, 0, 5) (rt, 0, 6) (ro, 0, 7) (rt, 0, 8) (ro, 0, 9)") == 0,
+ "ec_set_format() returns '%s'", buf);
+
+ rfree(lp);
+ return BT_SUCCESS;
+}
+
+static int
+t_set_ec_delete(void)
+{
+ resource_init();
+ generate_set_sequence(SET_TYPE_EC);
+
+ struct adata *deleting_sequence = set_sequence;
+ u32 i;
+ for (i = 0; i < SET_SIZE; i++)
+ {
+ deleting_sequence = ec_set_del(lp, deleting_sequence, i);
+ bt_assert_msg(ec_set_get_size(deleting_sequence) == (int) (SET_SIZE-1-i),
+ "ec_set_get_size(deleting_sequence) %d == SET_SIZE-1-i %d",
+ ec_set_get_size(deleting_sequence), SET_SIZE-1-i);
+ }
+
+ bt_assert(ec_set_get_size(set_sequence) == SET_SIZE);
+
+ return BT_SUCCESS;
+}
+
+int
+main(int argc, char *argv[])
+{
+ bt_init(argc, argv);
+
+ bt_test_suite(t_set_int_contains, "Testing sets of integers: contains, get_data");
+ bt_test_suite(t_set_int_format, "Testing sets of integers: format");
+ bt_test_suite(t_set_int_union, "Testing sets of integers: union");
+ bt_test_suite(t_set_int_delete, "Testing sets of integers: delete");
+
+ bt_test_suite(t_set_ec_contains, "Testing sets of Extended Community values: contains, get_data");
+ bt_test_suite(t_set_ec_format, "Testing sets of Extended Community values: format");
+ bt_test_suite(t_set_ec_union, "Testing sets of Extended Community values: union");
+ bt_test_suite(t_set_ec_delete, "Testing sets of Extended Community values: delete");
+
+ return bt_exit_value();
+}
diff --git a/nest/iface.h b/nest/iface.h
index c4f414ec..d960b859 100644
--- a/nest/iface.h
+++ b/nest/iface.h
@@ -10,6 +10,7 @@
#define _BIRD_IFACE_H_
#include "lib/lists.h"
+#include "lib/ip.h"
extern list iface_list;
diff --git a/nest/route.h b/nest/route.h
index f2e883b6..5104d8f1 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -12,7 +12,7 @@
#include "lib/lists.h"
#include "lib/resource.h"
#include "sysdep/unix/timer.h"
-//#include "nest/protocol.h"
+#include "lib/net.h"
struct ea_list;
struct protocol;