1 #include "rtr/db/db_table.h"
2 
3 #include <sys/types.h> /* AF_INET, AF_INET6 (needed in OpenBSD) */
4 #include <sys/socket.h> /* AF_INET, AF_INET6 (needed in OpenBSD) */
5 
6 #include "log.h"
7 #include "data_structure/uthash_nonfatal.h"
8 
9 struct hashable_roa {
10 	struct vrp data;
11 	UT_hash_handle hh;
12 };
13 
14 struct hashable_key {
15 	struct router_key data;
16 	UT_hash_handle hh;
17 };
18 
19 struct db_table {
20 	struct hashable_roa *roas;
21 	struct hashable_key *router_keys;
22 };
23 
24 struct db_table *
db_table_create(void)25 db_table_create(void)
26 {
27 	struct db_table *table;
28 
29 	table = malloc(sizeof(struct db_table));
30 	if (table == NULL)
31 		return NULL;
32 
33 	table->roas = NULL;
34 	table->router_keys = NULL;
35 	return table;
36 }
37 
38 void
db_table_destroy(struct db_table * table)39 db_table_destroy(struct db_table *table)
40 {
41 	struct hashable_roa *node;
42 	struct hashable_roa *tmp;
43 	struct hashable_key *node_key;
44 	struct hashable_key *tmp_key;
45 
46 	HASH_ITER(hh, table->roas, node, tmp) {
47 		HASH_DEL(table->roas, node);
48 		free(node);
49 	}
50 
51 	HASH_ITER(hh, table->router_keys, node_key, tmp_key) {
52 		HASH_DEL(table->router_keys, node_key);
53 		free(node_key);
54 	}
55 
56 	free(table);
57 }
58 
59 int
db_table_foreach_roa(struct db_table * table,vrp_foreach_cb cb,void * arg)60 db_table_foreach_roa(struct db_table *table, vrp_foreach_cb cb, void *arg)
61 {
62 	struct hashable_roa *node, *tmp;
63 	int error;
64 
65 	HASH_ITER(hh, table->roas, node, tmp) {
66 		error = cb(&node->data, arg);
67 		if (error)
68 			return error;
69 	}
70 
71 	return 0;
72 }
73 
74 int
db_table_foreach_router_key(struct db_table * table,router_key_foreach_cb cb,void * arg)75 db_table_foreach_router_key(struct db_table *table, router_key_foreach_cb cb,
76     void *arg)
77 {
78 	struct hashable_key *node, *tmp;
79 	int error;
80 
81 	HASH_ITER(hh, table->router_keys, node, tmp) {
82 		error = cb(&node->data, arg);
83 		if (error)
84 			return error;
85 	}
86 
87 	return 0;
88 }
89 
90 static struct hashable_roa *
create_roa(uint32_t asn,uint8_t max_length)91 create_roa(uint32_t asn, uint8_t max_length)
92 {
93 	struct hashable_roa *roa;
94 
95 	roa = malloc(sizeof(struct hashable_roa));
96 	if (roa == NULL)
97 		return NULL;
98 	/* Needed by uthash */
99 	memset(roa, 0, sizeof(struct hashable_roa));
100 
101 	roa->data.asn = asn;
102 	roa->data.max_prefix_length = max_length;
103 
104 	return roa;
105 }
106 
107 static int
add_roa(struct db_table * table,struct hashable_roa * new)108 add_roa(struct db_table *table, struct hashable_roa *new)
109 {
110 	struct hashable_roa *old;
111 
112 	errno = 0;
113 	HASH_REPLACE(hh, table->roas, data, sizeof(new->data), new, old);
114 	if (errno)
115 		return -pr_val_errno(errno, "ROA couldn't be added to hash table");
116 	if (old != NULL)
117 		free(old);
118 
119 	return 0;
120 }
121 
122 static int
add_router_key(struct db_table * table,struct hashable_key * new)123 add_router_key(struct db_table *table, struct hashable_key *new)
124 {
125 	struct hashable_key *old;
126 
127 	errno = 0;
128 	HASH_REPLACE(hh, table->router_keys, data, sizeof(new->data), new, old);
129 	if (errno)
130 		return -pr_val_errno(errno, "Router Key couldn't be added to hash table");
131 	if (old != NULL)
132 		free(old);
133 
134 	return 0;
135 }
136 
137 unsigned int
db_table_roa_count(struct db_table * table)138 db_table_roa_count(struct db_table *table)
139 {
140 	return HASH_COUNT(table->roas);
141 }
142 
143 unsigned int
db_table_router_key_count(struct db_table * table)144 db_table_router_key_count(struct db_table *table)
145 {
146 	return HASH_COUNT(table->router_keys);
147 }
148 
149 void
db_table_remove_roa(struct db_table * table,struct vrp const * del)150 db_table_remove_roa(struct db_table *table, struct vrp const *del)
151 {
152 	struct hashable_roa *ptr;
153 
154 	HASH_FIND(hh, table->roas, del, sizeof(*del), ptr);
155 	if (ptr != NULL) {
156 		HASH_DELETE(hh, table->roas, ptr);
157 		free(ptr);
158 	}
159 }
160 
161 void
db_table_remove_router_key(struct db_table * table,struct router_key const * del)162 db_table_remove_router_key(struct db_table *table,
163     struct router_key const *del)
164 {
165 	struct hashable_key *ptr;
166 
167 	HASH_FIND(hh, table->router_keys, del, sizeof(*del), ptr);
168 	if (ptr != NULL) {
169 		HASH_DELETE(hh, table->router_keys, ptr);
170 		free(ptr);
171 	}
172 }
173 
174 int
rtrhandler_handle_roa_v4(struct db_table * table,uint32_t asn,struct ipv4_prefix const * prefix4,uint8_t max_length)175 rtrhandler_handle_roa_v4(struct db_table *table, uint32_t asn,
176     struct ipv4_prefix const *prefix4, uint8_t max_length)
177 {
178 	struct hashable_roa *roa;
179 	int error;
180 
181 	roa = create_roa(asn, max_length);
182 	if (roa == NULL)
183 		return pr_enomem();
184 	roa->data.prefix.v4 = prefix4->addr;
185 	roa->data.prefix_length = prefix4->len;
186 	roa->data.addr_fam = AF_INET;
187 
188 	error = add_roa(table, roa);
189 	if (error)
190 		free(roa);
191 	return error;
192 }
193 
194 int
rtrhandler_handle_roa_v6(struct db_table * table,uint32_t asn,struct ipv6_prefix const * prefix6,uint8_t max_length)195 rtrhandler_handle_roa_v6(struct db_table *table, uint32_t asn,
196     struct ipv6_prefix const *prefix6, uint8_t max_length)
197 {
198 	struct hashable_roa *roa;
199 	int error;
200 
201 	roa = create_roa(asn, max_length);
202 	if (roa == NULL)
203 		return pr_enomem();
204 	roa->data.prefix.v6 = prefix6->addr;
205 	roa->data.prefix_length = prefix6->len;
206 	roa->data.addr_fam = AF_INET6;
207 
208 	error = add_roa(table, roa);
209 	if (error)
210 		free(roa);
211 	return error;
212 }
213 
214 int
rtrhandler_handle_router_key(struct db_table * table,unsigned char const * ski,uint32_t as,unsigned char const * spk)215 rtrhandler_handle_router_key(struct db_table *table,
216     unsigned char const *ski, uint32_t as, unsigned char const *spk)
217 {
218 	struct hashable_key *key;
219 	int error;
220 
221 	key = malloc(sizeof(struct hashable_key));
222 	if (key == NULL)
223 		return pr_enomem();
224 	/* Needed by uthash */
225 	memset(key, 0, sizeof(struct hashable_key));
226 
227 	router_key_init(&key->data, ski, as, spk);
228 
229 	error = add_router_key(table, key);
230 	if (error)
231 		free(key);
232 
233 	return error;
234 }
235 
236 /*
237  * Copies `@roas1 - roas2` into @deltas.
238  *
239  * (Places the ROAs that exist in @roas1 but not in @roas2 in @deltas.)
240  */
241 static int
add_roa_deltas(struct hashable_roa * roas1,struct hashable_roa * roas2,struct deltas * deltas,int op)242 add_roa_deltas(struct hashable_roa *roas1, struct hashable_roa *roas2,
243     struct deltas *deltas, int op)
244 {
245 	struct hashable_roa *n1; /* A node from @roas1 */
246 	struct hashable_roa *n2; /* A node from @roas2 */
247 	int error;
248 
249 	for (n1 = roas1; n1 != NULL; n1 = n1->hh.next) {
250 		HASH_FIND(hh, roas2, &n1->data, sizeof(n1->data), n2);
251 		if (n2 == NULL) {
252 			error = deltas_add_roa(deltas, &n1->data, op);
253 			if (error)
254 				return error;
255 		}
256 	}
257 
258 	return 0;
259 }
260 
261 static int
add_router_key_delta(struct deltas * deltas,struct hashable_key * key,int op)262 add_router_key_delta(struct deltas *deltas, struct hashable_key *key, int op)
263 {
264 	return deltas_add_router_key(deltas, &key->data, op);
265 }
266 
267 /*
268  * Copies `@keys1 - keys2` into @deltas.
269  *
270  * (Places the Router Keys that exist in @keys1 but not in @key2 in @deltas.)
271  */
272 static int
add_router_key_deltas(struct hashable_key * keys1,struct hashable_key * keys2,struct deltas * deltas,int op)273 add_router_key_deltas(struct hashable_key *keys1, struct hashable_key *keys2,
274     struct deltas *deltas, int op)
275 {
276 	struct hashable_key *n1; /* A node from @keys1 */
277 	struct hashable_key *n2; /* A node from @keys2 */
278 	int error;
279 
280 	for (n1 = keys1; n1 != NULL; n1 = n1->hh.next) {
281 		HASH_FIND(hh, keys2, &n1->data, sizeof(n1->data), n2);
282 		if (n2 == NULL) {
283 			error = add_router_key_delta(deltas, n1, op);
284 			if (error)
285 				return error;
286 		}
287 	}
288 
289 	return 0;
290 }
291 
292 int
compute_deltas(struct db_table * old,struct db_table * new,struct deltas ** result)293 compute_deltas(struct db_table *old, struct db_table *new,
294     struct deltas **result)
295 {
296 	struct deltas *deltas;
297 	int error;
298 
299 	error = deltas_create(&deltas);
300 	if (error)
301 		return error;
302 
303 	error = add_roa_deltas(new->roas, old->roas, deltas, FLAG_ANNOUNCEMENT);
304 	if (error)
305 		goto fail;
306 	error = add_roa_deltas(old->roas, new->roas, deltas, FLAG_WITHDRAWAL);
307 	if (error)
308 		goto fail;
309 	error = add_router_key_deltas(new->router_keys, old->router_keys,
310 	    deltas, FLAG_ANNOUNCEMENT);
311 	if (error)
312 		goto fail;
313 	error = add_router_key_deltas(old->router_keys, new->router_keys,
314 	    deltas, FLAG_WITHDRAWAL);
315 	if (error)
316 		goto fail;
317 
318 	*result = deltas;
319 	return 0;
320 
321 fail:
322 	deltas_refput(deltas);
323 	return error;
324 }
325