blob: 6155ab8625fbfa8ca56178cf44e8cd6eb21e7790 [file] [log] [blame]
Harald Welte1d8ffc62017-10-12 19:30:49 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <unistd.h>
5#include <time.h>
6
7#include <osmocom/core/utils.h>
8#include <osmocom/core/application.h>
9#include <osmocom/core/logging.h>
Pau Espin Pedrol042a4452018-04-17 14:31:42 +020010#include <osmocom/core/msgb.h>
Harald Welte1d8ffc62017-10-12 19:30:49 +080011
12#include "../../lib/in46_addr.h"
13#include "../../lib/ippool.h"
14#include "../../lib/syserr.h"
15
16
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020017static struct ippool_t *create_pool(const char *prefix_str, unsigned int flags, char **blacklist, size_t blacklist_size)
Harald Welte1d8ffc62017-10-12 19:30:49 +080018{
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020019 struct in46_prefix *blacklist_pfx;
Harald Welte1d8ffc62017-10-12 19:30:49 +080020 struct ippool_t *pool;
21 struct in46_prefix pfx;
22 size_t t;
23 int rc;
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020024 int i;
25
26 blacklist_pfx = calloc(blacklist_size, sizeof(struct in46_prefix));
27 for (i = 0; i < blacklist_size; i++) {
28 rc = ippool_aton(&blacklist_pfx[i].addr, &t, blacklist[i], 0);
29 OSMO_ASSERT(rc == 0);
30 pfx.prefixlen = t;
31 }
Harald Welte1d8ffc62017-10-12 19:30:49 +080032
33 /* dynamic-only v4 */
34
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020035 rc = ippool_aton(&pfx.addr, &t, prefix_str, 0);
Harald Welte1d8ffc62017-10-12 19:30:49 +080036 OSMO_ASSERT(rc == 0);
37 pfx.prefixlen = t;
38
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020039 rc = ippool_new(&pool, &pfx, NULL, flags, blacklist_pfx, blacklist_size);
Harald Welte1d8ffc62017-10-12 19:30:49 +080040 OSMO_ASSERT(rc == 0);
41
42 //ippool_printaddr(pool);
43
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020044 free(blacklist_pfx);
45
Harald Welte1d8ffc62017-10-12 19:30:49 +080046 return pool;
47}
48
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020049static void test_pool_size(const char *pfx, unsigned int flags, char **blacklist, size_t blacklist_size, unsigned int expected_size)
Harald Welte1d8ffc62017-10-12 19:30:49 +080050{
51 struct ippool_t *pool;
52 struct ippoolm_t *member;
53 struct in46_addr addr;
54 int i, rc, n;
55
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +020056 printf("testing pool for prefix %s, flags=0x%x, blacklist_size=%lu, expected_size=%u\n", pfx, flags, blacklist_size, expected_size);
57 pool = create_pool(pfx, flags, blacklist, blacklist_size);
Harald Welte1d8ffc62017-10-12 19:30:49 +080058 OSMO_ASSERT(pool->listsize == expected_size);
59
60 memset(&addr, 0, sizeof(addr));
61 addr.len = pool->member[0].addr.len;
62
63 /* allocate all addresses */
64 for (i = 0; i < expected_size; i++) {
65 member = NULL;
66 rc = ippool_newip(pool, &member, &addr, 0);
67 OSMO_ASSERT(rc == 0);
68 OSMO_ASSERT(member);
69 printf("allocated address %s\n", in46a_ntoa(&member->addr));
70 }
71 /* allocate one more, expect that to fail */
72 rc = ippool_newip(pool, &member, &addr, 0);
73 OSMO_ASSERT(rc < 0);
74
75 /* release a (random) number N of (random) member address */
76 n = rand() % pool->listsize;
77 for (i = 0; i < n; i++) {
78 int r;
79 /* chose a random index that is in use */
80 do {
81 r = rand() % pool->listsize;
82 } while (!pool->member[r].inuse);
83 /* and free it... */
84 rc = ippool_freeip(pool, &pool->member[r]);
85 OSMO_ASSERT(rc == 0);
86 }
87
88 /* allocate all N previously released addresses */
89 for (i = 0; i < n; i++) {
90 member = NULL;
91 rc = ippool_newip(pool, &member, &addr, 0);
92 OSMO_ASSERT(rc == 0);
93 OSMO_ASSERT(member);
94 }
95
96 /* allocate one more, expect that to fail */
97 rc = ippool_newip(pool, &member, &addr, 0);
98 OSMO_ASSERT(rc < 0);
99
100 ippool_free(pool);
101}
102
103static void test_pool_sizes(void)
104{
Pau Espin Pedrol361cb9e2017-10-13 11:56:16 +0200105 /* 256 addresses [0..255] */
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +0200106 test_pool_size("192.168.23.0/24", 0, NULL, 0, 256);
Pau Espin Pedrol361cb9e2017-10-13 11:56:16 +0200107
108 /* 255 addresses [1..255] */
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +0200109 test_pool_size("192.168.23.0/24", IPPOOL_NONETWORK, NULL, 0, 255);
Harald Welte1d8ffc62017-10-12 19:30:49 +0800110
111 /* 254 addresses [1..254] */
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +0200112 test_pool_size("192.168.23.0/24", IPPOOL_NONETWORK | IPPOOL_NOBROADCAST, NULL, 0, 254);
Harald Welte1d8ffc62017-10-12 19:30:49 +0800113
Pau Espin Pedrol361cb9e2017-10-13 11:56:16 +0200114 /* 65534 addresses [0.1..255.254] */
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +0200115 test_pool_size("192.168.0.0/16", IPPOOL_NONETWORK | IPPOOL_NOBROADCAST, NULL, 0, 65534);
Harald Welte1d8ffc62017-10-12 19:30:49 +0800116
Pau Espin Pedrol859f9b02017-10-16 14:52:25 +0200117 /* 253 addresses [1..254] & exclude 192.168.23.1/24 */
118 char *blacklist[] = {"176.16.222.10/24", "192.168.23.1/24", "192.168.38.2/24"};
119 test_pool_size("192.168.23.0/24", IPPOOL_NONETWORK | IPPOOL_NOBROADCAST, blacklist, 3, 253);
Harald Welte1d8ffc62017-10-12 19:30:49 +0800120}
121
Pau Espin Pedrol9c0f4f42017-12-04 12:52:23 +0100122static void test_pool_sizes_v6(void)
123{
124 /* 256 prefixes of /64 each */
125 test_pool_size("2001:DB8::/56", 0, NULL, 0, 256);
126}
127
Harald Welte1d8ffc62017-10-12 19:30:49 +0800128int main(int argc, char **argv)
129{
Pau Espin Pedrol042a4452018-04-17 14:31:42 +0200130 void *tall_ctx = talloc_named_const(NULL, 1, "Root context");
131 msgb_talloc_ctx_init(tall_ctx, 0);
132 osmo_init_logging2(tall_ctx, &log_info);
Harald Welte1d8ffc62017-10-12 19:30:49 +0800133 log_set_use_color(osmo_stderr_target, 0);
134 log_set_print_filename(osmo_stderr_target, 0);
135
136 srand(time(NULL));
137
Pau Espin Pedrol9c0f4f42017-12-04 12:52:23 +0100138 if (argc < 2 || strcmp(argv[1], "-v6")) {
139 test_pool_sizes();
140 } else {
141 test_pool_sizes_v6();
142 }
Neels Hofmeyrdabb8b42017-10-29 01:53:50 +0200143 return 0;
Harald Welte1d8ffc62017-10-12 19:30:49 +0800144}