635d1167a96132de7ee446394eadb3800cc15df7
[oonf.git] / src-plugins / subsystems / oonf_layer2.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon version 2 (olsrd2)
4  * Copyright (c) 2004-2015, the olsr.org team - see HISTORY file
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * * Redistributions of source code must retain the above copyright
12  *   notice, this list of conditions and the following disclaimer.
13  * * Redistributions in binary form must reproduce the above copyright
14  *   notice, this list of conditions and the following disclaimer in
15  *   the documentation and/or other materials provided with the
16  *   distribution.
17  * * Neither the name of olsr.org, olsrd nor the names of its
18  *   contributors may be used to endorse or promote products derived
19  *   from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32  * POSSIBILITY OF SUCH DAMAGE.
33  *
34  * Visit http://www.olsr.org for more information.
35  *
36  * If you find this software useful feel free to make a donation
37  * to the project. For more information see the website or contact
38  * the copyright holders.
39  *
40  */
41
42 /**
43  * @file
44  */
45
46 #include "common/avl.h"
47 #include "common/avl_comp.h"
48 #include "common/common_types.h"
49 #include "common/json.h"
50 #include "common/netaddr.h"
51 #include "config/cfg_schema.h"
52 #include "core/oonf_subsystem.h"
53 #include "subsystems/oonf_class.h"
54 #include "subsystems/os_interface.h"
55
56 #include "subsystems/oonf_layer2.h"
57
58 /* Definitions */
59 #define LOG_LAYER2 _oonf_layer2_subsystem.logging
60
61 /* prototypes */
62 static int _init(void);
63 static void _cleanup(void);
64
65 static void _net_remove(struct oonf_layer2_net *l2net);
66 static void _neigh_remove(struct oonf_layer2_neigh *l2neigh);
67
68 /* subsystem definition */
69 static const char *_dependencies[] = {
70   OONF_CLASS_SUBSYSTEM,
71   OONF_OS_INTERFACE_SUBSYSTEM,
72 };
73
74 static struct oonf_subsystem _oonf_layer2_subsystem = {
75   .name = OONF_LAYER2_SUBSYSTEM,
76   .dependencies = _dependencies,
77   .dependencies_count = ARRAYSIZE(_dependencies),
78   .init = _init,
79   .cleanup = _cleanup,
80 };
81 DECLARE_OONF_PLUGIN(_oonf_layer2_subsystem);
82
83 /* layer2 neighbor metadata */
84 static const struct oonf_layer2_metadata _metadata_neigh[OONF_LAYER2_NEIGH_COUNT] = {
85   [OONF_LAYER2_NEIGH_TX_SIGNAL] = { .key = "tx_signal",
86     .type = OONF_LAYER2_INTEGER_DATA,
87     .unit = "dBm",
88     .fraction = 3 },
89   [OONF_LAYER2_NEIGH_RX_SIGNAL] = { .key = "rx_signal",
90     .type = OONF_LAYER2_INTEGER_DATA,
91     .unit = "dBm",
92     .fraction = 3 },
93   [OONF_LAYER2_NEIGH_TX_BITRATE] = { .key = "tx_bitrate", .type = OONF_LAYER2_INTEGER_DATA, .unit = "bit/s" },
94   [OONF_LAYER2_NEIGH_RX_BITRATE] = { .key = "rx_bitrate", .type = OONF_LAYER2_INTEGER_DATA, .unit = "bit/s" },
95   [OONF_LAYER2_NEIGH_RX_BC_BITRATE] = { .key = "rx_bc_bitrate", .type = OONF_LAYER2_INTEGER_DATA, .unit = "bit/s" },
96   [OONF_LAYER2_NEIGH_TX_MAX_BITRATE] = { .key = "tx_max_bitrate", .type = OONF_LAYER2_INTEGER_DATA, .unit = "bit/s" },
97   [OONF_LAYER2_NEIGH_RX_MAX_BITRATE] = { .key = "rx_max_bitrate", .type = OONF_LAYER2_INTEGER_DATA, .unit = "bit/s" },
98   [OONF_LAYER2_NEIGH_TX_BYTES] = { .key = "tx_bytes", .type = OONF_LAYER2_INTEGER_DATA, .unit = "byte" },
99   [OONF_LAYER2_NEIGH_RX_BYTES] = { .key = "rx_bytes", .type = OONF_LAYER2_INTEGER_DATA, .unit = "byte" },
100   [OONF_LAYER2_NEIGH_TX_FRAMES] = { .key = "tx_frames", .type = OONF_LAYER2_INTEGER_DATA },
101   [OONF_LAYER2_NEIGH_RX_FRAMES] = { .key = "rx_frames", .type = OONF_LAYER2_INTEGER_DATA },
102   [OONF_LAYER2_NEIGH_TX_THROUGHPUT] = { .key = "tx_throughput", .type = OONF_LAYER2_INTEGER_DATA, .unit = "bit/s" },
103   [OONF_LAYER2_NEIGH_TX_RETRIES] = { .key = "tx_retries", .type = OONF_LAYER2_INTEGER_DATA },
104   [OONF_LAYER2_NEIGH_TX_FAILED] = { .key = "tx_failed", .type = OONF_LAYER2_INTEGER_DATA },
105   [OONF_LAYER2_NEIGH_LATENCY] = { .key = "latency", .type = OONF_LAYER2_INTEGER_DATA, .unit = "s", .fraction = 6 },
106   [OONF_LAYER2_NEIGH_RESOURCES] = { .key = "resources", .type = OONF_LAYER2_INTEGER_DATA },
107   [OONF_LAYER2_NEIGH_TX_RLQ] = { .key = "tx_rlq", .type = OONF_LAYER2_INTEGER_DATA },
108   [OONF_LAYER2_NEIGH_RX_RLQ] = { .key = "rx_rlq", .type = OONF_LAYER2_INTEGER_DATA },
109 };
110
111 /* layer2 network metadata */
112 static const struct oonf_layer2_metadata _metadata_net[OONF_LAYER2_NET_COUNT] = {
113   [OONF_LAYER2_NET_FREQUENCY_1] = { .key = "frequency1", .type = OONF_LAYER2_INTEGER_DATA, .unit = "Hz" },
114   [OONF_LAYER2_NET_FREQUENCY_2] = { .key = "frequency2", .type = OONF_LAYER2_INTEGER_DATA, .unit = "Hz" },
115   [OONF_LAYER2_NET_BANDWIDTH_1] = { .key = "bandwidth1", .type = OONF_LAYER2_INTEGER_DATA, .unit = "Hz" },
116   [OONF_LAYER2_NET_BANDWIDTH_2] = { .key = "bandwidth2", .type = OONF_LAYER2_INTEGER_DATA, .unit = "Hz" },
117   [OONF_LAYER2_NET_NOISE] = { .key = "noise", .type = OONF_LAYER2_INTEGER_DATA, .unit = "dBm", .fraction = 3 },
118   [OONF_LAYER2_NET_CHANNEL_ACTIVE] = { .key = "ch_active",
119     .type = OONF_LAYER2_INTEGER_DATA,
120     .unit = "s",
121     .fraction = 9 },
122   [OONF_LAYER2_NET_CHANNEL_BUSY] = { .key = "ch_busy", .type = OONF_LAYER2_INTEGER_DATA, .unit = "s", .fraction = 9 },
123   [OONF_LAYER2_NET_CHANNEL_RX] = { .key = "ch_rx", .type = OONF_LAYER2_INTEGER_DATA, .unit = "s", .fraction = 9 },
124   [OONF_LAYER2_NET_CHANNEL_TX] = { .key = "ch_tx", .type = OONF_LAYER2_INTEGER_DATA, .unit = "s", .fraction = 9 },
125   [OONF_LAYER2_NET_MTU] = { .key = "mtu", .type = OONF_LAYER2_INTEGER_DATA, .unit = "byte" },
126   [OONF_LAYER2_NET_MCS_BY_PROBING] = { .key = "mcs_by_probing", .type = OONF_LAYER2_BOOLEAN_DATA },
127   [OONF_LAYER2_NET_RX_ONLY_UNICAST] = { .key = "rx_only_unicast", .type = OONF_LAYER2_BOOLEAN_DATA },
128   [OONF_LAYER2_NET_TX_ONLY_UNICAST] = { .key = "tx_only_unicast", .type = OONF_LAYER2_BOOLEAN_DATA },
129 };
130
131 static const char *_network_type[OONF_LAYER2_TYPE_COUNT] = {
132   [OONF_LAYER2_TYPE_UNDEFINED] = "undefined",
133   [OONF_LAYER2_TYPE_WIRELESS] = "wireless",
134   [OONF_LAYER2_TYPE_ETHERNET] = "ethernet",
135   [OONF_LAYER2_TYPE_TUNNEL] = "tunnel",
136 };
137
138 static const char *_data_comparators[OONF_LAYER2_DATA_CMP_COUNT] = {
139   [OONF_LAYER2_DATA_CMP_EQUALS] = "==",
140   [OONF_LAYER2_DATA_CMP_NOT_EQUALS] = "!=",
141   [OONF_LAYER2_DATA_CMP_LESSER] = "<",
142   [OONF_LAYER2_DATA_CMP_LESSER_OR_EQUALS] = "<=",
143   [OONF_LAYER2_DATA_CMP_GREATER] = ">",
144   [OONF_LAYER2_DATA_CMP_GREATER_OR_EQUALS] = ">=",
145 };
146
147 static const char *_data_types[OONF_LAYER2_DATA_TYPE_COUNT] = {
148   [OONF_LAYER2_NO_DATA] = "none",
149   [OONF_LAYER2_INTEGER_DATA] = "integer",
150   [OONF_LAYER2_BOOLEAN_DATA] = "boolean",
151   [OONF_LAYER2_NETWORK_DATA] = "network",
152 };
153
154 /* infrastructure for l2net/l2neigh tree */
155 static struct oonf_class _l2network_class = {
156   .name = LAYER2_CLASS_NETWORK,
157   .size = sizeof(struct oonf_layer2_net),
158 };
159 static struct oonf_class _l2neighbor_class = {
160   .name = LAYER2_CLASS_NEIGHBOR,
161   .size = sizeof(struct oonf_layer2_neigh),
162 };
163 static struct oonf_class _l2dst_class = {
164   .name = LAYER2_CLASS_DESTINATION,
165   .size = sizeof(struct oonf_layer2_destination),
166 };
167 static struct oonf_class _l2net_addr_class = {
168   .name = LAYER2_CLASS_NETWORK_ADDRESS,
169   .size = sizeof(struct oonf_layer2_peer_address),
170 };
171 static struct oonf_class _l2neigh_addr_class = {
172   .name = LAYER2_CLASS_NEIGHBOR_ADDRESS,
173   .size = sizeof(struct oonf_layer2_neighbor_address),
174 };
175
176 static struct avl_tree _oonf_layer2_net_tree;
177
178 static struct avl_tree _oonf_originator_tree;
179
180 static struct avl_tree _local_peer_ips_tree;
181
182 /**
183  * Subsystem constructor
184  * @return always returns 0
185  */
186 static int
187 _init(void) {
188   oonf_class_add(&_l2network_class);
189   oonf_class_add(&_l2neighbor_class);
190   oonf_class_add(&_l2dst_class);
191   oonf_class_add(&_l2net_addr_class);
192   oonf_class_add(&_l2neigh_addr_class);
193
194   avl_init(&_oonf_layer2_net_tree, avl_comp_strcasecmp, false);
195   avl_init(&_oonf_originator_tree, avl_comp_strcasecmp, false);
196   avl_init(&_local_peer_ips_tree, avl_comp_netaddr, true);
197   return 0;
198 }
199
200 /**
201  * Subsystem destructor
202  */
203 static void
204 _cleanup(void) {
205   struct oonf_layer2_net *l2net, *l2n_it;
206
207   avl_for_each_element_safe(&_oonf_layer2_net_tree, l2net, _node, l2n_it) {
208     _net_remove(l2net);
209   }
210
211   oonf_class_remove(&_l2neigh_addr_class);
212   oonf_class_remove(&_l2net_addr_class);
213   oonf_class_remove(&_l2dst_class);
214   oonf_class_remove(&_l2neighbor_class);
215   oonf_class_remove(&_l2network_class);
216 }
217
218 /**
219  * Register a new data originator number for layer2 data
220  * @param origin layer2 originator
221  */
222 void
223 oonf_layer2_origin_add(struct oonf_layer2_origin *origin) {
224   origin->_node.key = origin->name;
225   avl_insert(&_oonf_originator_tree, &origin->_node);
226 }
227
228 /**
229  * Removes all layer2 data associated with this data originator
230  * @param origin originator
231  */
232 void
233 oonf_layer2_origin_remove(struct oonf_layer2_origin *origin) {
234   struct oonf_layer2_net *l2net, *l2net_it;
235
236   if (!avl_is_node_added(&origin->_node)) {
237     return;
238   }
239
240   avl_for_each_element_safe(&_oonf_layer2_net_tree, l2net, _node, l2net_it) {
241     oonf_layer2_net_remove(l2net, origin);
242   }
243
244   avl_remove(&_oonf_originator_tree, &origin->_node);
245 }
246
247 /**
248  * Parse a string into a layer2 data object
249  * @param value target buffer for layer2 data
250  * @param meta metadata for layer2 data
251  * @param input input string
252  * @return -1 if an error happened, 0 otherwise
253  */
254 int
255 oonf_layer2_data_parse_string(
256   union oonf_layer2_value *value, const struct oonf_layer2_metadata *meta, const char *input) {
257   memset(value, 0, sizeof(*value));
258
259   switch (meta->type) {
260     case OONF_LAYER2_INTEGER_DATA:
261       return isonumber_to_s64(&value->integer, input, meta->fraction);
262
263     case OONF_LAYER2_BOOLEAN_DATA:
264       if (!cfg_is_bool(input)) {
265         return -1;
266       }
267       value->boolean = cfg_get_bool(input);
268       return 0;
269
270     default:
271       return -1;
272   }
273 }
274
275 /**
276  * Convert a layer2 data object into a string representation
277  * @param buffer destination string buffer
278  * @param length length of string buffer
279  * @param data layer2 data
280  * @param meta layer2 metadata
281  * @param raw true for raw conversion (switch of isoprefix conversion)
282  * @return pointer to output buffer, NULL if an error happened
283  */
284 const char *
285 oonf_layer2_data_to_string(
286   char *buffer, size_t length, const struct oonf_layer2_data *data, const struct oonf_layer2_metadata *meta, bool raw) {
287   struct isonumber_str iso_str;
288
289   switch (meta->type) {
290     case OONF_LAYER2_INTEGER_DATA:
291       if (!isonumber_from_s64(&iso_str, data->_value.integer, meta->unit, meta->fraction, raw)) {
292         return NULL;
293       }
294       return strscpy(buffer, iso_str.buf, length);
295
296     case OONF_LAYER2_BOOLEAN_DATA:
297       return strscpy(buffer, json_getbool(data->_value.boolean), length);
298
299     default:
300       return NULL;
301   }
302 }
303
304 /**
305  * (Over)write the value of a layer2 data object
306  * @param l2data layer2 data object
307  * @param origin origin of new data
308  * @param type type of new data
309  * @param input new data value
310  * @return true if data changed, false otherwise
311  */
312 bool
313 oonf_layer2_data_set(struct oonf_layer2_data *l2data, const struct oonf_layer2_origin *origin,
314   enum oonf_layer2_data_type type, const union oonf_layer2_value *input) {
315   bool changed = false;
316
317   if (l2data->_type == OONF_LAYER2_NO_DATA || l2data->_origin == NULL || l2data->_origin == origin ||
318       l2data->_origin->priority < origin->priority) {
319     changed = l2data->_type != type || memcmp(&l2data->_value, input, sizeof(*input)) != 0;
320     memcpy(&l2data->_value, input, sizeof(*input));
321     l2data->_type = type;
322     l2data->_origin = origin;
323   }
324   return changed;
325 }
326
327 /**
328  * Compare two layer2 data objects
329  * @param left left parameter for comparator
330  * @param right right parameter for comparator
331  * @param cmp comparator
332  * @return comparator result, false if not valid
333  *   (e.g. comparing different types of data)
334  */
335 bool
336 oonf_layer2_data_compare(const union oonf_layer2_value *left, const union oonf_layer2_value *right,
337   enum oonf_layer2_data_comparator_type comparator, enum oonf_layer2_data_type data_type) {
338   int result;
339
340   switch (data_type) {
341     case OONF_LAYER2_INTEGER_DATA:
342       if (left->integer > right->integer) {
343         result = 1;
344       }
345       else if (left->integer < right->integer) {
346         result = -1;
347       }
348       else {
349         result = 0;
350       }
351       break;
352     case OONF_LAYER2_BOOLEAN_DATA:
353       result = memcmp(&left->boolean, &right->boolean, sizeof(left->boolean));
354       break;
355     case OONF_LAYER2_NETWORK_DATA:
356       result = memcmp(&left->addr, &right->addr, sizeof(left->addr));
357       break;
358     default:
359       return false;
360   }
361
362   switch (comparator) {
363     case OONF_LAYER2_DATA_CMP_EQUALS:
364       return result == 0;
365     case OONF_LAYER2_DATA_CMP_NOT_EQUALS:
366       return result != 0;
367     case OONF_LAYER2_DATA_CMP_LESSER:
368       return result < 0;
369     case OONF_LAYER2_DATA_CMP_LESSER_OR_EQUALS:
370       return result <= 0;
371     case OONF_LAYER2_DATA_CMP_GREATER:
372       return result > 0;
373     case OONF_LAYER2_DATA_CMP_GREATER_OR_EQUALS:
374       return result >= 0;
375     default:
376       return false;
377   }
378 }
379
380 /**
381  * Get comparator type from string
382  * @param string string (C) representation of comparator
383  * @return comparator type
384  */
385 enum oonf_layer2_data_comparator_type
386 oonf_layer2_data_get_comparator(const char *string)
387 {
388   enum oonf_layer2_data_comparator_type i;
389
390   for (i = 0; i < OONF_LAYER2_DATA_CMP_COUNT; i++) {
391     if (strcmp(string, _data_comparators[i]) == 0) {
392       return i;
393     }
394   }
395   return OONF_LAYER2_DATA_CMP_ILLEGAL;
396 }
397
398 /**
399  * @param type layer2 comparator type
400  * @return string representation of comparator
401  */
402 const char *
403 oonf_layer2_data_get_comparator_string(enum oonf_layer2_data_comparator_type type) {
404   return _data_comparators[type];
405 }
406
407 /**
408  * @param type type index of layer2 data
409  * @return the string name of a layer2 data type
410  */
411 const char *
412 oonf_layer2_data_get_type_string(enum oonf_layer2_data_type type) {
413   return _data_types[type];
414 }
415
416 /**
417  * Add a layer-2 network to the database
418  * @param ifname name of interface
419  * @return layer-2 network object
420  */
421 struct oonf_layer2_net *
422 oonf_layer2_net_add(const char *ifname) {
423   struct oonf_layer2_net *l2net;
424
425   if (!ifname) {
426     return NULL;
427   }
428
429   l2net = avl_find_element(&_oonf_layer2_net_tree, ifname, l2net, _node);
430   if (l2net) {
431     return l2net;
432   }
433
434   l2net = oonf_class_malloc(&_l2network_class);
435   if (!l2net) {
436     return NULL;
437   }
438
439   /* initialize key */
440   strscpy(l2net->name, ifname, sizeof(l2net->name));
441
442   /* add to global l2net tree */
443   l2net->_node.key = l2net->name;
444   avl_insert(&_oonf_layer2_net_tree, &l2net->_node);
445
446   /* initialize tree of neighbors, ips and proxies */
447   avl_init(&l2net->neighbors, avl_comp_netaddr, false);
448   avl_init(&l2net->local_peer_ips, avl_comp_netaddr, false);
449   avl_init(&l2net->remote_neighbor_ips, avl_comp_netaddr, true);
450
451   /* initialize interface listener */
452   l2net->if_listener.name = l2net->name;
453   os_interface_add(&l2net->if_listener);
454
455   oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_ADDED);
456
457   return l2net;
458 }
459
460 /**
461  * Remove all data objects of a certain originator from a layer-2 network
462  * object.
463  * @param l2net layer-2 addr object
464  * @param origin originator number
465  * @param cleanup_neigh true to cleanup neighbor data too
466  * @return true if a value was removed, false otherwise
467  */
468 bool
469 oonf_layer2_net_cleanup(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin, bool cleanup_neigh) {
470   struct oonf_layer2_neigh *l2neigh;
471   bool changed = false;
472   int i;
473
474   for (i = 0; i < OONF_LAYER2_NET_COUNT; i++) {
475     if (l2net->data[i]._origin == origin) {
476       oonf_layer2_data_reset(&l2net->data[i]);
477       changed = true;
478     }
479   }
480   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
481     if (l2net->neighdata[i]._origin == origin) {
482       oonf_layer2_data_reset(&l2net->neighdata[i]);
483       changed = true;
484     }
485   }
486
487   if (cleanup_neigh) {
488     avl_for_each_element(&l2net->neighbors, l2neigh, _node) {
489       changed |= oonf_layer2_neigh_cleanup(l2neigh, origin);
490     }
491   }
492   return changed;
493 }
494
495 /**
496  * Remove all information of a certain originator from a layer-2 addr
497  * object. Remove the object if its empty and has no neighbors anymore.
498  * @param l2net layer-2 addr object
499  * @param origin originator identifier
500  * @return true if something changed, false otherwise
501  */
502 bool
503 oonf_layer2_net_remove(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin) {
504   struct oonf_layer2_neigh *l2neigh, *l2neigh_it;
505   bool changed = false;
506
507   if (!avl_is_node_added(&l2net->_node)) {
508     return false;
509   }
510
511   avl_for_each_element_safe(&l2net->neighbors, l2neigh, _node, l2neigh_it) {
512     if (oonf_layer2_neigh_remove(l2neigh, origin)) {
513       changed = true;
514     }
515   }
516
517   if (oonf_layer2_net_cleanup(l2net, origin, false)) {
518     changed = true;
519   }
520
521   if (changed) {
522     oonf_layer2_net_commit(l2net);
523   }
524   return changed;
525 }
526
527 /**
528  * Commit all changes to a layer-2 addr object. This might remove the
529  * object from the database if all data has been removed from the object.
530  * @param l2net layer-2 addr object
531  * @return true if the object has been removed, false otherwise
532  */
533 bool
534 oonf_layer2_net_commit(struct oonf_layer2_net *l2net) {
535   size_t i;
536
537   if (l2net->neighbors.count > 0) {
538     oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_CHANGED);
539     return false;
540   }
541
542   for (i = 0; i < OONF_LAYER2_NET_COUNT; i++) {
543     if (oonf_layer2_data_has_value(&l2net->data[i])) {
544       oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_CHANGED);
545       return false;
546     }
547   }
548
549   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
550     if (oonf_layer2_data_has_value(&l2net->neighdata[i])) {
551       oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_CHANGED);
552       return false;
553     }
554   }
555
556   _net_remove(l2net);
557   return true;
558 }
559
560 /**
561  * Relabel all network data (including neighbor data)
562  * of one origin to another one
563  * @param l2net layer2 network object
564  * @param new_origin new origin
565  * @param old_origin old origin to overwrite
566  */
567 void
568 oonf_layer2_net_relabel(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *new_origin,
569   const struct oonf_layer2_origin *old_origin) {
570   struct oonf_layer2_neigh *l2neigh;
571   struct oonf_layer2_peer_address *peer_ip;
572   size_t i;
573
574   for (i = 0; i < OONF_LAYER2_NET_COUNT; i++) {
575     if (oonf_layer2_data_get_origin(&l2net->data[i]) == old_origin) {
576       oonf_layer2_data_set_origin(&l2net->data[i], new_origin);
577     }
578   }
579
580   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
581     if (oonf_layer2_data_get_origin(&l2net->neighdata[i]) == old_origin) {
582       oonf_layer2_data_set_origin(&l2net->neighdata[i], new_origin);
583     }
584   }
585
586   avl_for_each_element(&l2net->local_peer_ips, peer_ip, _net_node) {
587     if (peer_ip->origin == old_origin) {
588       peer_ip->origin = new_origin;
589     }
590   }
591
592   avl_for_each_element(&l2net->neighbors, l2neigh, _node) {
593     oonf_layer2_neigh_relabel(l2neigh, new_origin, old_origin);
594   }
595 }
596
597 /**
598  * Add an IP address or prefix to a layer-2 interface. This represents
599  * an address of the local radio or modem.
600  * @param l2net layer-2 network object
601  * @param ip ip address or prefix
602  * @return layer2 ip address object, NULL if out of memory
603  */
604 struct oonf_layer2_peer_address *
605 oonf_layer2_net_add_ip(
606   struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin, const struct netaddr *ip) {
607   struct oonf_layer2_peer_address *l2addr;
608
609   l2addr = oonf_layer2_net_get_local_ip(l2net, ip);
610   if (!l2addr) {
611     l2addr = oonf_class_malloc(&_l2net_addr_class);
612     if (!l2addr) {
613       return NULL;
614     }
615
616     /* copy data */
617     memcpy(&l2addr->ip, ip, sizeof(*ip));
618
619     /* set back reference */
620     l2addr->l2net = l2net;
621
622     /* add to tree */
623     l2addr->_net_node.key = &l2addr->ip;
624     avl_insert(&l2net->local_peer_ips, &l2addr->_net_node);
625
626     l2addr->_global_node.key = &l2addr->ip;
627     avl_insert(&_local_peer_ips_tree, &l2addr->_global_node);
628
629     oonf_class_event(&_l2net_addr_class, l2addr, OONF_OBJECT_ADDED);
630   }
631
632   l2addr->origin = origin;
633   return l2addr;
634 }
635
636 /**
637  * Remove a peer IP address from a layer2 network
638  * @param ip ip address or prefix
639  * @param origin origin of IP address
640  * @return 0 if IP was removed, -1 if it was registered to a different origin
641  */
642 int
643 oonf_layer2_net_remove_ip(struct oonf_layer2_peer_address *ip, const struct oonf_layer2_origin *origin) {
644   if (ip->origin != origin) {
645     return -1;
646   }
647
648   oonf_class_event(&_l2net_addr_class, ip, OONF_OBJECT_REMOVED);
649
650   avl_remove(&ip->l2net->local_peer_ips, &ip->_net_node);
651   avl_remove(&_local_peer_ips_tree, &ip->_global_node);
652   oonf_class_free(&_l2net_addr_class, ip);
653   return 0;
654 }
655
656 /**
657  * Look for the best matching prefix in all layer2 neighbor addresses
658  * that contains a specific address
659  * @param addr ip address to look for
660  * @return layer2 neighbor address object, NULL if no match was found
661  */
662 struct oonf_layer2_neighbor_address *
663 oonf_layer2_net_get_best_neighbor_match(const struct netaddr *addr) {
664   struct oonf_layer2_neighbor_address *best_match, *l2addr;
665   struct oonf_layer2_neigh *l2neigh;
666   struct oonf_layer2_net *l2net;
667   int prefix_length;
668
669   prefix_length = 256;
670   best_match = NULL;
671
672   avl_for_each_element(&_oonf_layer2_net_tree, l2net, _node) {
673     avl_for_each_element(&l2net->neighbors, l2neigh, _node) {
674       avl_for_each_element(&l2neigh->remote_neighbor_ips, l2addr, _neigh_node) {
675         if (netaddr_is_in_subnet(&l2addr->ip, addr) && netaddr_get_prefix_length(&l2addr->ip) < prefix_length) {
676           best_match = l2addr;
677           prefix_length = netaddr_get_prefix_length(&l2addr->ip);
678         }
679       }
680     }
681   }
682   return best_match;
683 }
684
685 /**
686  * Add a layer-2 neighbor to a addr.
687  * @param l2net layer-2 addr object
688  * @param neigh mac address of layer-2 neighbor
689  * @return layer-2 neighbor object
690  */
691 struct oonf_layer2_neigh *
692 oonf_layer2_neigh_add(struct oonf_layer2_net *l2net, const struct netaddr *neigh) {
693   struct oonf_layer2_neigh *l2neigh;
694
695   if (netaddr_get_address_family(neigh) != AF_MAC48 && netaddr_get_address_family(neigh) != AF_EUI64) {
696     return NULL;
697   }
698
699   l2neigh = oonf_layer2_neigh_get(l2net, neigh);
700   if (l2neigh) {
701     return l2neigh;
702   }
703
704   l2neigh = oonf_class_malloc(&_l2neighbor_class);
705   if (!l2neigh) {
706     return NULL;
707   }
708
709   memcpy(&l2neigh->addr, neigh, sizeof(*neigh));
710   l2neigh->_node.key = &l2neigh->addr;
711   l2neigh->network = l2net;
712
713   avl_insert(&l2net->neighbors, &l2neigh->_node);
714
715   avl_init(&l2neigh->destinations, avl_comp_netaddr, false);
716   avl_init(&l2neigh->remote_neighbor_ips, avl_comp_netaddr, false);
717
718   oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_ADDED);
719
720   return l2neigh;
721 }
722
723 /**
724  * Remove all data objects of a certain originator from a layer-2 neighbor
725  * object.
726  * @param l2neigh layer-2 neighbor
727  * @param origin originator number
728  * @return true if a value was resetted, false otherwise
729  */
730 bool
731 oonf_layer2_neigh_cleanup(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin) {
732   bool changed = false;
733   int i;
734
735   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
736     if (l2neigh->data[i]._origin == origin) {
737       oonf_layer2_data_reset(&l2neigh->data[i]);
738       changed = true;
739     }
740   }
741   return changed;
742 }
743
744 /**
745  * Remove all information of a certain originator from a layer-2 neighbor
746  * object. Remove the object if its empty.
747  * @param l2neigh layer-2 neighbor object
748  * @param origin originator number
749  * @return true if something was change, false otherwise
750  */
751 bool
752 oonf_layer2_neigh_remove(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin) {
753   struct oonf_layer2_destination *l2dst, *l2dst_it;
754   struct oonf_layer2_neighbor_address *l2ip, *l2ip_it;
755
756   bool changed = false;
757
758   if (!avl_is_node_added(&l2neigh->_node)) {
759     return false;
760   }
761
762   avl_for_each_element_safe(&l2neigh->destinations, l2dst, _node, l2dst_it) {
763     if (l2dst->origin == origin) {
764       oonf_layer2_destination_remove(l2dst);
765       changed = true;
766     }
767   }
768
769   avl_for_each_element_safe(&l2neigh->remote_neighbor_ips, l2ip, _neigh_node, l2ip_it) {
770     if (oonf_layer2_neigh_remove_ip(l2ip, origin) == 0) {
771       changed = true;
772     }
773   }
774
775   if (oonf_layer2_neigh_cleanup(l2neigh, origin)) {
776     changed = true;
777   }
778
779   if (changed) {
780     oonf_layer2_neigh_commit(l2neigh);
781   }
782   return changed;
783 }
784
785 /**
786  * Commit all changes to a layer-2 neighbor object. This might remove the
787  * object from the database if all data has been removed from the object.
788  * @param l2neigh layer-2 neighbor object
789  * @return true if the object has been removed, false otherwise
790  */
791 bool
792 oonf_layer2_neigh_commit(struct oonf_layer2_neigh *l2neigh) {
793   size_t i;
794
795   if (l2neigh->destinations.count > 0 || l2neigh->remote_neighbor_ips.count > 0) {
796     oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_CHANGED);
797     return false;
798   }
799
800   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
801     if (oonf_layer2_data_has_value(&l2neigh->data[i])) {
802       oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_CHANGED);
803       return false;
804     }
805   }
806
807   _neigh_remove(l2neigh);
808   return true;
809 }
810
811 /**
812  * Relabel all neighbor data of one origin to another one
813  * @param l2neigh layer2 neighbor object
814  * @param new_origin new origin
815  * @param old_origin old origin to overwrite
816  */
817 void
818 oonf_layer2_neigh_relabel(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *new_origin,
819   const struct oonf_layer2_origin *old_origin) {
820   struct oonf_layer2_neighbor_address *neigh_ip;
821   struct oonf_layer2_destination *l2dst;
822   size_t i;
823
824   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
825     if (oonf_layer2_data_get_origin(&l2neigh->data[i]) == old_origin) {
826       oonf_layer2_data_set_origin(&l2neigh->data[i], new_origin);
827     }
828   }
829
830   avl_for_each_element(&l2neigh->remote_neighbor_ips, neigh_ip, _neigh_node) {
831     if (neigh_ip->origin == old_origin) {
832       neigh_ip->origin = new_origin;
833     }
834   }
835
836   avl_for_each_element(&l2neigh->destinations, l2dst, _node) {
837     if (l2dst->origin == old_origin) {
838       l2dst->origin = new_origin;
839     }
840   }
841 }
842
843 /**
844  * Add an IP address or prefix to a layer-2 interface. This represents
845  * an address of the local radio or modem.
846  * @param l2net layer-2 network object
847  * @param ip ip address or prefix
848  * @return layer2 ip address object, NULL if out of memory
849  */
850 struct oonf_layer2_neighbor_address *
851 oonf_layer2_neigh_add_ip(
852   struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin, const struct netaddr *ip) {
853   struct oonf_layer2_neighbor_address *l2addr;
854
855   l2addr = oonf_layer2_neigh_get_remote_ip(l2neigh, ip);
856   if (!l2addr) {
857     l2addr = oonf_class_malloc(&_l2neigh_addr_class);
858     if (!l2addr) {
859       return NULL;
860     }
861
862     /* copy data */
863     memcpy(&l2addr->ip, ip, sizeof(*ip));
864
865     /* set back reference */
866     l2addr->l2neigh = l2neigh;
867
868     /* add to tree */
869     l2addr->_neigh_node.key = &l2addr->ip;
870     avl_insert(&l2neigh->remote_neighbor_ips, &l2addr->_neigh_node);
871     l2addr->_net_node.key = &l2addr->ip;
872     avl_insert(&l2neigh->network->remote_neighbor_ips, &l2addr->_net_node);
873
874     oonf_class_event(&_l2neigh_addr_class, l2addr, OONF_OBJECT_ADDED);
875   }
876
877   l2addr->origin = origin;
878   return l2addr;
879 }
880
881 /**
882  * Remove a neighbor IP address from a layer2 neighbor
883  * @param ip ip address or prefix
884  * @param origin origin of IP address
885  * @return 0 if IP was removed, -1 if it was registered to a different origin
886  */
887 int
888 oonf_layer2_neigh_remove_ip(struct oonf_layer2_neighbor_address *ip, const struct oonf_layer2_origin *origin) {
889   if (ip->origin != origin) {
890     return -1;
891   }
892
893   oonf_class_event(&_l2neigh_addr_class, ip, OONF_OBJECT_REMOVED);
894
895   avl_remove(&ip->l2neigh->remote_neighbor_ips, &ip->_neigh_node);
896   avl_remove(&ip->l2neigh->network->remote_neighbor_ips, &ip->_net_node);
897   oonf_class_free(&_l2neigh_addr_class, ip);
898   return 0;
899 }
900
901 /**
902  * add a layer2 destination (a MAC address behind a neighbor) to
903  * the layer2 database
904  * @param l2neigh layer2 neighbor of the destination
905  * @param destination destination address
906  * @param origin layer2 origin
907  * @return layer2 destination, NULL if out of memory
908  */
909 struct oonf_layer2_destination *
910 oonf_layer2_destination_add(
911   struct oonf_layer2_neigh *l2neigh, const struct netaddr *destination, const struct oonf_layer2_origin *origin) {
912   struct oonf_layer2_destination *l2dst;
913
914   l2dst = oonf_layer2_destination_get(l2neigh, destination);
915   if (l2dst) {
916     return l2dst;
917   }
918
919   l2dst = oonf_class_malloc(&_l2dst_class);
920   if (!l2dst) {
921     return NULL;
922   }
923
924   /* copy data into destination storage */
925   memcpy(&l2dst->destination, destination, sizeof(*destination));
926   l2dst->origin = origin;
927
928   /* add back-pointer */
929   l2dst->neighbor = l2neigh;
930
931   /* add to neighbor tree */
932   l2dst->_node.key = &l2dst->destination;
933   avl_insert(&l2neigh->destinations, &l2dst->_node);
934
935   oonf_class_event(&_l2dst_class, l2dst, OONF_OBJECT_ADDED);
936   return l2dst;
937 }
938
939 /**
940  * Remove a layer2 destination
941  * @param l2dst layer2 destination
942  */
943 void
944 oonf_layer2_destination_remove(struct oonf_layer2_destination *l2dst) {
945   if (!avl_is_node_added(&l2dst->_node)) {
946     return;
947   }
948   oonf_class_event(&_l2dst_class, l2dst, OONF_OBJECT_REMOVED);
949
950   avl_remove(&l2dst->neighbor->destinations, &l2dst->_node);
951   oonf_class_free(&_l2dst_class, l2dst);
952 }
953
954 /**
955  * Get neighbor specific data, either from neighbor or from the networks default
956  * @param ifname name of interface
957  * @param l2neigh_addr neighbor mac address
958  * @param idx data index
959  * @return pointer to linklayer data, NULL if no value available
960  */
961 const struct oonf_layer2_data *
962 oonf_layer2_neigh_query(const char *ifname, const struct netaddr *l2neigh_addr, enum oonf_layer2_neighbor_index idx) {
963   struct oonf_layer2_net *l2net;
964   struct oonf_layer2_neigh *l2neigh;
965   struct oonf_layer2_data *data;
966
967   /* query layer2 database about neighbor */
968   l2net = oonf_layer2_net_get(ifname);
969   if (l2net == NULL) {
970     return NULL;
971   }
972
973   /* look for neighbor specific data */
974   l2neigh = oonf_layer2_neigh_get(l2net, l2neigh_addr);
975   if (l2neigh != NULL) {
976     data = &l2neigh->data[idx];
977     if (oonf_layer2_data_has_value(data)) {
978       return data;
979     }
980   }
981
982   /* look for network specific default */
983   data = &l2net->neighdata[idx];
984   if (oonf_layer2_data_has_value(data)) {
985     return data;
986   }
987   return NULL;
988 }
989
990 /**
991  * Get neighbor specific data, either from neighbor or from the networks default
992  * @param l2neigh pointer to layer2 neighbor
993  * @param idx data index
994  * @return pointer to linklayer data, NULL if no value available
995  */
996 const struct oonf_layer2_data *
997 oonf_layer2_neigh_get_data(const struct oonf_layer2_neigh *l2neigh, enum oonf_layer2_neighbor_index idx) {
998   const struct oonf_layer2_data *data;
999
1000   data = &l2neigh->data[idx];
1001   if (oonf_layer2_data_has_value(data)) {
1002     return data;
1003   }
1004
1005   /* look for network specific default */
1006   data = &l2neigh->network->neighdata[idx];
1007   if (oonf_layer2_data_has_value(data)) {
1008     return data;
1009   }
1010   return NULL;
1011 }
1012
1013 /**
1014  * get neighbor metric metadata
1015  * @param idx neighbor metric index
1016  * @return metadata object
1017  */
1018 const struct oonf_layer2_metadata *
1019 oonf_layer2_neigh_metadata_get(enum oonf_layer2_neighbor_index idx) {
1020   return &_metadata_neigh[idx];
1021 }
1022
1023 /**
1024  * get network metric metadata
1025  * @param idx network metric index
1026  * @return metadata object
1027  */
1028 const struct oonf_layer2_metadata *
1029 oonf_layer2_net_metadata_get(enum oonf_layer2_network_index idx) {
1030   return &_metadata_net[idx];
1031 }
1032
1033 /**
1034  * Callback for configuration choice of layer2 network key
1035  * @param idx index
1036  * @param unused not used
1037  * @return pointer to network key
1038  */
1039 const char *
1040 oonf_layer2_cfg_get_l2net_key(size_t idx, const void *unused __attribute__((unused))) {
1041   return _metadata_net[idx].key;
1042 }
1043
1044 /**
1045  * Callback for configuration choice of layer2 neighbor key
1046  * @param idx index
1047  * @param unused not used
1048  * @return pointer to neighbor key
1049  */
1050 const char *
1051 oonf_layer2_cfg_get_l2neigh_key(size_t idx, const void *unused __attribute__((unused))) {
1052   return _metadata_neigh[idx].key;
1053 }
1054
1055 /**
1056  * Callback for configuration choice of layer2 neighbor key
1057  * @param idx index
1058  * @param unused not used
1059  * @return pointer to neighbor key
1060  */
1061 const char *
1062 oonf_layer2_cfg_get_l2comp(size_t idx, const void *unused __attribute__((unused))) {
1063   return _data_comparators[idx];
1064 }
1065
1066 /**
1067  * get text representation of network type
1068  * @param type network type
1069  * @return text representation
1070  */
1071 const char *
1072 oonf_layer2_net_get_type_name(enum oonf_layer2_network_type type) {
1073   return _network_type[type];
1074 }
1075
1076 /**
1077  * get tree of layer2 networks
1078  * @return network tree
1079  */
1080 struct avl_tree *
1081 oonf_layer2_get_net_tree(void) {
1082   return &_oonf_layer2_net_tree;
1083 }
1084
1085 /**
1086  * get tree of layer2 originators
1087  * @return originator tree
1088  */
1089 struct avl_tree *
1090 oonf_layer2_get_origin_tree(void) {
1091   return &_oonf_originator_tree;
1092 }
1093
1094 /**
1095  * Removes a layer-2 addr object from the database.
1096  * @param l2net layer-2 addr object
1097  */
1098 static void
1099 _net_remove(struct oonf_layer2_net *l2net) {
1100   struct oonf_layer2_neigh *l2neigh, *l2n_it;
1101   struct oonf_layer2_peer_address *l2peer, *l2peer_it;
1102
1103   /* free all embedded neighbors */
1104   avl_for_each_element_safe(&l2net->neighbors, l2neigh, _node, l2n_it) {
1105     _neigh_remove(l2neigh);
1106   }
1107
1108   /* free all attached peer addresses */
1109   avl_for_each_element_safe(&l2net->local_peer_ips, l2peer, _net_node, l2peer_it) {
1110     oonf_layer2_net_remove_ip(l2peer, l2peer->origin);
1111   }
1112
1113   oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_REMOVED);
1114
1115   /* remove interface listener */
1116   os_interface_remove(&l2net->if_listener);
1117
1118   /* free addr */
1119   avl_remove(&_oonf_layer2_net_tree, &l2net->_node);
1120   oonf_class_free(&_l2network_class, l2net);
1121 }
1122
1123 /**
1124  * Removes a layer-2 neighbor object from the database
1125  * @param l2neigh layer-2 neighbor object
1126  */
1127 static void
1128 _neigh_remove(struct oonf_layer2_neigh *l2neigh) {
1129   struct oonf_layer2_destination *l2dst, *l2dst_it;
1130   struct oonf_layer2_neighbor_address *l2addr, *l2addr_it;
1131
1132   /* free all embedded destinations */
1133   avl_for_each_element_safe(&l2neigh->destinations, l2dst, _node, l2dst_it) {
1134     oonf_layer2_destination_remove(l2dst);
1135   }
1136
1137   /* free all attached neighbor addresses */
1138   avl_for_each_element_safe(&l2neigh->remote_neighbor_ips, l2addr, _neigh_node, l2addr_it) {
1139     oonf_layer2_neigh_remove_ip(l2addr, l2addr->origin);
1140   }
1141
1142   /* inform user that mac entry will be removed */
1143   oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_REMOVED);
1144
1145   /* free resources for mac entry */
1146   avl_remove(&l2neigh->network->neighbors, &l2neigh->_node);
1147   oonf_class_free(&_l2neighbor_class, l2neigh);
1148 }