diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:54:46 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 09:54:46 +0000 |
commit | cd7b005519ade8ab6c97fcb21590b71b7d1be6e3 (patch) | |
tree | c611a8d0cd5e8f68f41b8c2d16ba580e0f40a38d /tests/test_pfx_locks.c | |
parent | Initial commit. (diff) | |
download | librtr-cd7b005519ade8ab6c97fcb21590b71b7d1be6e3.tar.xz librtr-cd7b005519ade8ab6c97fcb21590b71b7d1be6e3.zip |
Adding upstream version 0.8.0.upstream/0.8.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/test_pfx_locks.c')
-rw-r--r-- | tests/test_pfx_locks.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/tests/test_pfx_locks.c b/tests/test_pfx_locks.c new file mode 100644 index 0000000..1decf91 --- /dev/null +++ b/tests/test_pfx_locks.c @@ -0,0 +1,171 @@ +/* + * This file is part of RTRlib. + * + * This file is subject to the terms and conditions of the MIT license. + * See the file LICENSE in the top level directory for more details. + * + * Website: http://rtrlib.realmv6.org/ + */ + +#include "rtrlib/lib/ip.h" +#include "rtrlib/pfx/pfx.h" +#include "rtrlib/pfx/trie/trie-pfx.h" + +#include <arpa/inet.h> +#include <pthread.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <time.h> +#include <unistd.h> + +uint32_t min_i = 0xFF000000; +uint32_t max_i = 0xFFFFFFF0; + +/** + * @brief Add records to prefix table + */ +static void *rec_add(struct pfx_table *pfxt) +{ + const int tid = getpid(); + struct pfx_record rec; + + rec.min_len = 32; + rec.max_len = 32; + rec.prefix.ver = LRTR_IPV4; + rec.prefix.u.addr4.addr = 0; + + printf("Inserting %u records\n", (max_i - min_i) * 3); + for (uint32_t i = max_i; i >= min_i; i--) { + rec.min_len = 32; + rec.max_len = 32; + rec.socket = NULL; + rec.asn = tid % 2; + rec.prefix.u.addr4.addr = htonl(i); + rec.prefix.ver = LRTR_IPV4; + pfx_table_add(pfxt, &rec); + rec.asn = (tid % 2) + 1; + pfx_table_add(pfxt, &rec); + + rec.min_len = 128; + rec.max_len = 128; + rec.prefix.ver = LRTR_IPV6; + rec.prefix.u.addr6.addr[1] = min_i + 0xFFFFFFFF; + rec.prefix.u.addr6.addr[0] = htonl(i) + 0xFFFFFFFF; + pfx_table_add(pfxt, &rec); + usleep(rand() / (RAND_MAX / 20)); + } + + return NULL; +} + +/** + * @brief Validate records in prefix table + */ +static void *rec_val(struct pfx_table *pfxt) +{ + const int tid = getpid(); + struct pfx_record rec; + enum pfxv_state res; + + rec.min_len = 32; + rec.max_len = 32; + rec.prefix.ver = LRTR_IPV4; + rec.prefix.u.addr4.addr = 0; + printf("validating..\n"); + for (uint32_t i = max_i; i >= min_i; i--) { + rec.min_len = 32; + rec.max_len = 32; + rec.prefix.ver = LRTR_IPV4; + rec.prefix.u.addr4.addr = htonl(i); + pfx_table_validate(pfxt, (tid % 2), &rec.prefix, rec.min_len, &res); + pfx_table_validate(pfxt, (tid % 2) + 1, &rec.prefix, rec.min_len, &res); + + rec.min_len = 128; + rec.max_len = 128; + rec.prefix.ver = LRTR_IPV6; + rec.prefix.u.addr6.addr[1] = min_i + 0xFFFFFFFF; + rec.prefix.u.addr6.addr[0] = htonl(i) + 0xFFFFFFFF; + + pfx_table_validate(pfxt, (tid % 2) + 1, &rec.prefix, rec.min_len, &res); + usleep(rand() / (RAND_MAX / 20)); + } + + return NULL; +} + +/** + * @brief Delete records from prefix table + */ +static void *rec_del(struct pfx_table *pfxt) +{ + const int tid = getpid(); + struct pfx_record rec; + + rec.min_len = 32; + rec.max_len = 32; + rec.prefix.ver = LRTR_IPV4; + rec.prefix.u.addr4.addr = 0; + printf("removing records\n"); + for (uint32_t i = max_i; i >= min_i; i--) { + rec.socket = NULL; + rec.min_len = 32; + rec.max_len = 32; + rec.asn = tid % 2; + rec.prefix.ver = LRTR_IPV4; + rec.prefix.u.addr4.addr = htonl(i); + pfx_table_remove(pfxt, &rec); + rec.asn = (tid % 2) + 1; + pfx_table_remove(pfxt, &rec); + + rec.prefix.ver = LRTR_IPV6; + rec.min_len = 128; + rec.max_len = 128; + rec.prefix.u.addr6.addr[1] = min_i + 0xFFFFFFFF; + rec.prefix.u.addr6.addr[0] = htonl(i) + 0xFFFFFFFF; + + pfx_table_remove(pfxt, &rec); + usleep(rand() / (RAND_MAX / 20)); + } + printf("Done\n"); + + return NULL; +} + +/** + * @brief Test concurrent operations on pfx_table + * This test creates 15 (random) threads that add, delete, or validate huge + * numbers of entries in/to/from a pfx_table. + * + * NOTE: this test takes a (very) long time to complete, use with care! + */ +int main(void) +{ + unsigned int max_threads = 15; + struct pfx_table pfxt; + pthread_t threads[max_threads]; + + pfx_table_init(&pfxt, NULL); + srand(time(NULL)); + + for (unsigned int i = 0; i < max_threads; i++) { + int r = rand() / (RAND_MAX / 3); + + if (r == 0) + pthread_create(&threads[i], NULL, (void *(*)(void *))rec_add, &pfxt); + else if (r == 1) + pthread_create(&threads[i], NULL, (void *(*)(void *))rec_del, &pfxt); + else if (r == 2) + pthread_create(&threads[i], NULL, (void *(*)(void *))rec_val, &pfxt); + printf("Started Thread %d\n", i); + usleep(200); + } + for (unsigned int i = 0; i < max_threads; i++) { + pthread_join(threads[i], NULL); + printf("Thread %i returned\n", i); + } + + return EXIT_SUCCESS; +} |