Fixes for doxygen comments
[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 comparator comparator type
332  * @param data_type data type for comparison
333  * @return comparator result, false if not valid
334  *   (e.g. comparing different types of data)
335  */
336 bool
337 oonf_layer2_data_compare(const union oonf_layer2_value *left, const union oonf_layer2_value *right,
338   enum oonf_layer2_data_comparator_type comparator, enum oonf_layer2_data_type data_type) {
339   int result;
340
341   switch (data_type) {
342     case OONF_LAYER2_INTEGER_DATA:
343       if (left->integer > right->integer) {
344         result = 1;
345       }
346       else if (left->integer < right->integer) {
347         result = -1;
348       }
349       else {
350         result = 0;
351       }
352       break;
353     case OONF_LAYER2_BOOLEAN_DATA:
354       result = memcmp(&left->boolean, &right->boolean, sizeof(left->boolean));
355       break;
356     case OONF_LAYER2_NETWORK_DATA:
357       result = memcmp(&left->addr, &right->addr, sizeof(left->addr));
358       break;
359     default:
360       return false;
361   }
362
363   switch (comparator) {
364     case OONF_LAYER2_DATA_CMP_EQUALS:
365       return result == 0;
366     case OONF_LAYER2_DATA_CMP_NOT_EQUALS:
367       return result != 0;
368     case OONF_LAYER2_DATA_CMP_LESSER:
369       return result < 0;
370     case OONF_LAYER2_DATA_CMP_LESSER_OR_EQUALS:
371       return result <= 0;
372     case OONF_LAYER2_DATA_CMP_GREATER:
373       return result > 0;
374     case OONF_LAYER2_DATA_CMP_GREATER_OR_EQUALS:
375       return result >= 0;
376     default:
377       return false;
378   }
379 }
380
381 /**
382  * Get comparator type from string
383  * @param string string (C) representation of comparator
384  * @return comparator type
385  */
386 enum oonf_layer2_data_comparator_type
387 oonf_layer2_data_get_comparator(const char *string)
388 {
389   enum oonf_layer2_data_comparator_type i;
390
391   for (i = 0; i < OONF_LAYER2_DATA_CMP_COUNT; i++) {
392     if (strcmp(string, _data_comparators[i]) == 0) {
393       return i;
394     }
395   }
396   return OONF_LAYER2_DATA_CMP_ILLEGAL;
397 }
398
399 /**
400  * @param type layer2 comparator type
401  * @return string representation of comparator
402  */
403 const char *
404 oonf_layer2_data_get_comparator_string(enum oonf_layer2_data_comparator_type type) {
405   return _data_comparators[type];
406 }
407
408 /**
409  * @param type type index of layer2 data
410  * @return the string name of a layer2 data type
411  */
412 const char *
413 oonf_layer2_data_get_type_string(enum oonf_layer2_data_type type) {
414   return _data_types[type];
415 }
416
417 /**
418  * Add a layer-2 network to the database
419  * @param ifname name of interface
420  * @return layer-2 network object
421  */
422 struct oonf_layer2_net *
423 oonf_layer2_net_add(const char *ifname) {
424   struct oonf_layer2_net *l2net;
425
426   if (!ifname) {
427     return NULL;
428   }
429
430   l2net = avl_find_element(&_oonf_layer2_net_tree, ifname, l2net, _node);
431   if (l2net) {
432     return l2net;
433   }
434
435   l2net = oonf_class_malloc(&_l2network_class);
436   if (!l2net) {
437     return NULL;
438   }
439
440   /* initialize key */
441   strscpy(l2net->name, ifname, sizeof(l2net->name));
442
443   /* add to global l2net tree */
444   l2net->_node.key = l2net->name;
445   avl_insert(&_oonf_layer2_net_tree, &l2net->_node);
446
447   /* initialize tree of neighbors, ips and proxies */
448   avl_init(&l2net->neighbors, avl_comp_netaddr, false);
449   avl_init(&l2net->local_peer_ips, avl_comp_netaddr, false);
450   avl_init(&l2net->remote_neighbor_ips, avl_comp_netaddr, true);
451
452   /* initialize interface listener */
453   l2net->if_listener.name = l2net->name;
454   os_interface_add(&l2net->if_listener);
455
456   oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_ADDED);
457
458   return l2net;
459 }
460
461 /**
462  * Remove all data objects of a certain originator from a layer-2 network
463  * object.
464  * @param l2net layer-2 addr object
465  * @param origin originator number
466  * @param cleanup_neigh true to cleanup neighbor data too
467  * @return true if a value was removed, false otherwise
468  */
469 bool
470 oonf_layer2_net_cleanup(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin, bool cleanup_neigh) {
471   struct oonf_layer2_neigh *l2neigh;
472   bool changed = false;
473   int i;
474
475   for (i = 0; i < OONF_LAYER2_NET_COUNT; i++) {
476     if (l2net->data[i]._origin == origin) {
477       oonf_layer2_data_reset(&l2net->data[i]);
478       changed = true;
479     }
480   }
481   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
482     if (l2net->neighdata[i]._origin == origin) {
483       oonf_layer2_data_reset(&l2net->neighdata[i]);
484       changed = true;
485     }
486   }
487
488   if (cleanup_neigh) {
489     avl_for_each_element(&l2net->neighbors, l2neigh, _node) {
490       changed |= oonf_layer2_neigh_cleanup(l2neigh, origin);
491     }
492   }
493   return changed;
494 }
495
496 /**
497  * Remove all information of a certain originator from a layer-2 addr
498  * object. Remove the object if its empty and has no neighbors anymore.
499  * @param l2net layer-2 addr object
500  * @param origin originator identifier
501  * @return true if something changed, false otherwise
502  */
503 bool
504 oonf_layer2_net_remove(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin) {
505   struct oonf_layer2_neigh *l2neigh, *l2neigh_it;
506   bool changed = false;
507
508   if (!avl_is_node_added(&l2net->_node)) {
509     return false;
510   }
511
512   avl_for_each_element_safe(&l2net->neighbors, l2neigh, _node, l2neigh_it) {
513     if (oonf_layer2_neigh_remove(l2neigh, origin)) {
514       changed = true;
515     }
516   }
517
518   if (oonf_layer2_net_cleanup(l2net, origin, false)) {
519     changed = true;
520   }
521
522   if (changed) {
523     oonf_layer2_net_commit(l2net);
524   }
525   return changed;
526 }
527
528 /**
529  * Commit all changes to a layer-2 addr object. This might remove the
530  * object from the database if all data has been removed from the object.
531  * @param l2net layer-2 addr object
532  * @return true if the object has been removed, false otherwise
533  */
534 bool
535 oonf_layer2_net_commit(struct oonf_layer2_net *l2net) {
536   size_t i;
537
538   if (l2net->neighbors.count > 0) {
539     oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_CHANGED);
540     return false;
541   }
542
543   for (i = 0; i < OONF_LAYER2_NET_COUNT; i++) {
544     if (oonf_layer2_data_has_value(&l2net->data[i])) {
545       oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_CHANGED);
546       return false;
547     }
548   }
549
550   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
551     if (oonf_layer2_data_has_value(&l2net->neighdata[i])) {
552       oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_CHANGED);
553       return false;
554     }
555   }
556
557   _net_remove(l2net);
558   return true;
559 }
560
561 /**
562  * Relabel all network data (including neighbor data)
563  * of one origin to another one
564  * @param l2net layer2 network object
565  * @param new_origin new origin
566  * @param old_origin old origin to overwrite
567  */
568 void
569 oonf_layer2_net_relabel(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *new_origin,
570   const struct oonf_layer2_origin *old_origin) {
571   struct oonf_layer2_neigh *l2neigh;
572   struct oonf_layer2_peer_address *peer_ip;
573   size_t i;
574
575   for (i = 0; i < OONF_LAYER2_NET_COUNT; i++) {
576     if (oonf_layer2_data_get_origin(&l2net->data[i]) == old_origin) {
577       oonf_layer2_data_set_origin(&l2net->data[i], new_origin);
578     }
579   }
580
581   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
582     if (oonf_layer2_data_get_origin(&l2net->neighdata[i]) == old_origin) {
583       oonf_layer2_data_set_origin(&l2net->neighdata[i], new_origin);
584     }
585   }
586
587   avl_for_each_element(&l2net->local_peer_ips, peer_ip, _net_node) {
588     if (peer_ip->origin == old_origin) {
589       peer_ip->origin = new_origin;
590     }
591   }
592
593   avl_for_each_element(&l2net->neighbors, l2neigh, _node) {
594     oonf_layer2_neigh_relabel(l2neigh, new_origin, old_origin);
595   }
596 }
597
598 /**
599  * Add an IP address or prefix to a layer-2 interface. This represents
600  * an address of the local radio or modem.
601  * @param l2net layer-2 network object
602  * @param ip ip address or prefix
603  * @return layer2 ip address object, NULL if out of memory
604  */
605 struct oonf_layer2_peer_address *
606 oonf_layer2_net_add_ip(
607   struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin, const struct netaddr *ip) {
608   struct oonf_layer2_peer_address *l2addr;
609
610   l2addr = oonf_layer2_net_get_local_ip(l2net, ip);
611   if (!l2addr) {
612     l2addr = oonf_class_malloc(&_l2net_addr_class);
613     if (!l2addr) {
614       return NULL;
615     }
616
617     /* copy data */
618     memcpy(&l2addr->ip, ip, sizeof(*ip));
619
620     /* set back reference */
621     l2addr->l2net = l2net;
622
623     /* add to tree */
624     l2addr->_net_node.key = &l2addr->ip;
625     avl_insert(&l2net->local_peer_ips, &l2addr->_net_node);
626
627     l2addr->_global_node.key = &l2addr->ip;
628     avl_insert(&_local_peer_ips_tree, &l2addr->_global_node);
629
630     oonf_class_event(&_l2net_addr_class, l2addr, OONF_OBJECT_ADDED);
631   }
632
633   l2addr->origin = origin;
634   return l2addr;
635 }
636
637 /**
638  * Remove a peer IP address from a layer2 network
639  * @param ip ip address or prefix
640  * @param origin origin of IP address
641  * @return 0 if IP was removed, -1 if it was registered to a different origin
642  */
643 int
644 oonf_layer2_net_remove_ip(struct oonf_layer2_peer_address *ip, const struct oonf_layer2_origin *origin) {
645   if (ip->origin != origin) {
646     return -1;
647   }
648
649   oonf_class_event(&_l2net_addr_class, ip, OONF_OBJECT_REMOVED);
650
651   avl_remove(&ip->l2net->local_peer_ips, &ip->_net_node);
652   avl_remove(&_local_peer_ips_tree, &ip->_global_node);
653   oonf_class_free(&_l2net_addr_class, ip);
654   return 0;
655 }
656
657 /**
658  * Look for the best matching prefix in all layer2 neighbor addresses
659  * that contains a specific address
660  * @param addr ip address to look for
661  * @return layer2 neighbor address object, NULL if no match was found
662  */
663 struct oonf_layer2_neighbor_address *
664 oonf_layer2_net_get_best_neighbor_match(const struct netaddr *addr) {
665   struct oonf_layer2_neighbor_address *best_match, *l2addr;
666   struct oonf_layer2_neigh *l2neigh;
667   struct oonf_layer2_net *l2net;
668   int prefix_length;
669
670   prefix_length = 256;
671   best_match = NULL;
672
673   avl_for_each_element(&_oonf_layer2_net_tree, l2net, _node) {
674     avl_for_each_element(&l2net->neighbors, l2neigh, _node) {
675       avl_for_each_element(&l2neigh->remote_neighbor_ips, l2addr, _neigh_node) {
676         if (netaddr_is_in_subnet(&l2addr->ip, addr) && netaddr_get_prefix_length(&l2addr->ip) < prefix_length) {
677           best_match = l2addr;
678           prefix_length = netaddr_get_prefix_length(&l2addr->ip);
679         }
680       }
681     }
682   }
683   return best_match;
684 }
685
686 /**
687  * Add a layer-2 neighbor to a addr.
688  * @param l2net layer-2 addr object
689  * @param neigh mac address of layer-2 neighbor
690  * @return layer-2 neighbor object
691  */
692 struct oonf_layer2_neigh *
693 oonf_layer2_neigh_add(struct oonf_layer2_net *l2net, const struct netaddr *neigh) {
694   struct oonf_layer2_neigh *l2neigh;
695
696   if (netaddr_get_address_family(neigh) != AF_MAC48 && netaddr_get_address_family(neigh) != AF_EUI64) {
697     return NULL;
698   }
699
700   l2neigh = oonf_layer2_neigh_get(l2net, neigh);
701   if (l2neigh) {
702     return l2neigh;
703   }
704
705   l2neigh = oonf_class_malloc(&_l2neighbor_class);
706   if (!l2neigh) {
707     return NULL;
708   }
709
710   memcpy(&l2neigh->addr, neigh, sizeof(*neigh));
711   l2neigh->_node.key = &l2neigh->addr;
712   l2neigh->network = l2net;
713
714   avl_insert(&l2net->neighbors, &l2neigh->_node);
715
716   avl_init(&l2neigh->destinations, avl_comp_netaddr, false);
717   avl_init(&l2neigh->remote_neighbor_ips, avl_comp_netaddr, false);
718
719   oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_ADDED);
720
721   return l2neigh;
722 }
723
724 /**
725  * Remove all data objects of a certain originator from a layer-2 neighbor
726  * object.
727  * @param l2neigh layer-2 neighbor
728  * @param origin originator number
729  * @return true if a value was resetted, false otherwise
730  */
731 bool
732 oonf_layer2_neigh_cleanup(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin) {
733   bool changed = false;
734   int i;
735
736   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
737     if (l2neigh->data[i]._origin == origin) {
738       oonf_layer2_data_reset(&l2neigh->data[i]);
739       changed = true;
740     }
741   }
742   return changed;
743 }
744
745 /**
746  * Remove all information of a certain originator from a layer-2 neighbor
747  * object. Remove the object if its empty.
748  * @param l2neigh layer-2 neighbor object
749  * @param origin originator number
750  * @return true if something was change, false otherwise
751  */
752 bool
753 oonf_layer2_neigh_remove(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin) {
754   struct oonf_layer2_destination *l2dst, *l2dst_it;
755   struct oonf_layer2_neighbor_address *l2ip, *l2ip_it;
756
757   bool changed = false;
758
759   if (!avl_is_node_added(&l2neigh->_node)) {
760     return false;
761   }
762
763   avl_for_each_element_safe(&l2neigh->destinations, l2dst, _node, l2dst_it) {
764     if (l2dst->origin == origin) {
765       oonf_layer2_destination_remove(l2dst);
766       changed = true;
767     }
768   }
769
770   avl_for_each_element_safe(&l2neigh->remote_neighbor_ips, l2ip, _neigh_node, l2ip_it) {
771     if (oonf_layer2_neigh_remove_ip(l2ip, origin) == 0) {
772       changed = true;
773     }
774   }
775
776   if (oonf_layer2_neigh_cleanup(l2neigh, origin)) {
777     changed = true;
778   }
779
780   if (changed) {
781     oonf_layer2_neigh_commit(l2neigh);
782   }
783   return changed;
784 }
785
786 /**
787  * Commit all changes to a layer-2 neighbor object. This might remove the
788  * object from the database if all data has been removed from the object.
789  * @param l2neigh layer-2 neighbor object
790  * @return true if the object has been removed, false otherwise
791  */
792 bool
793 oonf_layer2_neigh_commit(struct oonf_layer2_neigh *l2neigh) {
794   size_t i;
795
796   if (l2neigh->destinations.count > 0 || l2neigh->remote_neighbor_ips.count > 0) {
797     oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_CHANGED);
798     return false;
799   }
800
801   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
802     if (oonf_layer2_data_has_value(&l2neigh->data[i])) {
803       oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_CHANGED);
804       return false;
805     }
806   }
807
808   _neigh_remove(l2neigh);
809   return true;
810 }
811
812 /**
813  * Relabel all neighbor data of one origin to another one
814  * @param l2neigh layer2 neighbor object
815  * @param new_origin new origin
816  * @param old_origin old origin to overwrite
817  */
818 void
819 oonf_layer2_neigh_relabel(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *new_origin,
820   const struct oonf_layer2_origin *old_origin) {
821   struct oonf_layer2_neighbor_address *neigh_ip;
822   struct oonf_layer2_destination *l2dst;
823   size_t i;
824
825   for (i = 0; i < OONF_LAYER2_NEIGH_COUNT; i++) {
826     if (oonf_layer2_data_get_origin(&l2neigh->data[i]) == old_origin) {
827       oonf_layer2_data_set_origin(&l2neigh->data[i], new_origin);
828     }
829   }
830
831   avl_for_each_element(&l2neigh->remote_neighbor_ips, neigh_ip, _neigh_node) {
832     if (neigh_ip->origin == old_origin) {
833       neigh_ip->origin = new_origin;
834     }
835   }
836
837   avl_for_each_element(&l2neigh->destinations, l2dst, _node) {
838     if (l2dst->origin == old_origin) {
839       l2dst->origin = new_origin;
840     }
841   }
842 }
843
844 /**
845  * Add an IP address or prefix to a layer-2 interface. This represents
846  * an address of the local radio or modem.
847  * @param l2neigh layer-2 neighbor object
848  * @param origin layer2 data origin
849  * @param ip ip address or prefix
850  * @return layer2 ip address object, NULL if out of memory
851  */
852 struct oonf_layer2_neighbor_address *
853 oonf_layer2_neigh_add_ip(
854   struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin, const struct netaddr *ip) {
855   struct oonf_layer2_neighbor_address *l2addr;
856
857   l2addr = oonf_layer2_neigh_get_remote_ip(l2neigh, ip);
858   if (!l2addr) {
859     l2addr = oonf_class_malloc(&_l2neigh_addr_class);
860     if (!l2addr) {
861       return NULL;
862     }
863
864     /* copy data */
865     memcpy(&l2addr->ip, ip, sizeof(*ip));
866
867     /* set back reference */
868     l2addr->l2neigh = l2neigh;
869
870     /* add to tree */
871     l2addr->_neigh_node.key = &l2addr->ip;
872     avl_insert(&l2neigh->remote_neighbor_ips, &l2addr->_neigh_node);
873     l2addr->_net_node.key = &l2addr->ip;
874     avl_insert(&l2neigh->network->remote_neighbor_ips, &l2addr->_net_node);
875
876     oonf_class_event(&_l2neigh_addr_class, l2addr, OONF_OBJECT_ADDED);
877   }
878
879   l2addr->origin = origin;
880   return l2addr;
881 }
882
883 /**
884  * Remove a neighbor IP address from a layer2 neighbor
885  * @param ip ip address or prefix
886  * @param origin origin of IP address
887  * @return 0 if IP was removed, -1 if it was registered to a different origin
888  */
889 int
890 oonf_layer2_neigh_remove_ip(struct oonf_layer2_neighbor_address *ip, const struct oonf_layer2_origin *origin) {
891   if (ip->origin != origin) {
892     return -1;
893   }
894
895   oonf_class_event(&_l2neigh_addr_class, ip, OONF_OBJECT_REMOVED);
896
897   avl_remove(&ip->l2neigh->remote_neighbor_ips, &ip->_neigh_node);
898   avl_remove(&ip->l2neigh->network->remote_neighbor_ips, &ip->_net_node);
899   oonf_class_free(&_l2neigh_addr_class, ip);
900   return 0;
901 }
902
903 /**
904  * add a layer2 destination (a MAC address behind a neighbor) to
905  * the layer2 database
906  * @param l2neigh layer2 neighbor of the destination
907  * @param destination destination address
908  * @param origin layer2 origin
909  * @return layer2 destination, NULL if out of memory
910  */
911 struct oonf_layer2_destination *
912 oonf_layer2_destination_add(
913   struct oonf_layer2_neigh *l2neigh, const struct netaddr *destination, const struct oonf_layer2_origin *origin) {
914   struct oonf_layer2_destination *l2dst;
915
916   l2dst = oonf_layer2_destination_get(l2neigh, destination);
917   if (l2dst) {
918     return l2dst;
919   }
920
921   l2dst = oonf_class_malloc(&_l2dst_class);
922   if (!l2dst) {
923     return NULL;
924   }
925
926   /* copy data into destination storage */
927   memcpy(&l2dst->destination, destination, sizeof(*destination));
928   l2dst->origin = origin;
929
930   /* add back-pointer */
931   l2dst->neighbor = l2neigh;
932
933   /* add to neighbor tree */
934   l2dst->_node.key = &l2dst->destination;
935   avl_insert(&l2neigh->destinations, &l2dst->_node);
936
937   oonf_class_event(&_l2dst_class, l2dst, OONF_OBJECT_ADDED);
938   return l2dst;
939 }
940
941 /**
942  * Remove a layer2 destination
943  * @param l2dst layer2 destination
944  */
945 void
946 oonf_layer2_destination_remove(struct oonf_layer2_destination *l2dst) {
947   if (!avl_is_node_added(&l2dst->_node)) {
948     return;
949   }
950   oonf_class_event(&_l2dst_class, l2dst, OONF_OBJECT_REMOVED);
951
952   avl_remove(&l2dst->neighbor->destinations, &l2dst->_node);
953   oonf_class_free(&_l2dst_class, l2dst);
954 }
955
956 /**
957  * Get neighbor specific data, either from neighbor or from the networks default
958  * @param ifname name of interface
959  * @param l2neigh_addr neighbor mac address
960  * @param idx data index
961  * @return pointer to linklayer data, NULL if no value available
962  */
963 const struct oonf_layer2_data *
964 oonf_layer2_neigh_query(const char *ifname, const struct netaddr *l2neigh_addr, enum oonf_layer2_neighbor_index idx) {
965   struct oonf_layer2_net *l2net;
966   struct oonf_layer2_neigh *l2neigh;
967   struct oonf_layer2_data *data;
968
969   /* query layer2 database about neighbor */
970   l2net = oonf_layer2_net_get(ifname);
971   if (l2net == NULL) {
972     return NULL;
973   }
974
975   /* look for neighbor specific data */
976   l2neigh = oonf_layer2_neigh_get(l2net, l2neigh_addr);
977   if (l2neigh != NULL) {
978     data = &l2neigh->data[idx];
979     if (oonf_layer2_data_has_value(data)) {
980       return data;
981     }
982   }
983
984   /* look for network specific default */
985   data = &l2net->neighdata[idx];
986   if (oonf_layer2_data_has_value(data)) {
987     return data;
988   }
989   return NULL;
990 }
991
992 /**
993  * Get neighbor specific data, either from neighbor or from the networks default
994  * @param l2neigh pointer to layer2 neighbor
995  * @param idx data index
996  * @return pointer to linklayer data, NULL if no value available
997  */
998 const struct oonf_layer2_data *
999 oonf_layer2_neigh_get_data(const struct oonf_layer2_neigh *l2neigh, enum oonf_layer2_neighbor_index idx) {
1000   const struct oonf_layer2_data *data;
1001
1002   data = &l2neigh->data[idx];
1003   if (oonf_layer2_data_has_value(data)) {
1004     return data;
1005   }
1006
1007   /* look for network specific default */
1008   data = &l2neigh->network->neighdata[idx];
1009   if (oonf_layer2_data_has_value(data)) {
1010     return data;
1011   }
1012   return NULL;
1013 }
1014
1015 /**
1016  * get neighbor metric metadata
1017  * @param idx neighbor metric index
1018  * @return metadata object
1019  */
1020 const struct oonf_layer2_metadata *
1021 oonf_layer2_neigh_metadata_get(enum oonf_layer2_neighbor_index idx) {
1022   return &_metadata_neigh[idx];
1023 }
1024
1025 /**
1026  * get network metric metadata
1027  * @param idx network metric index
1028  * @return metadata object
1029  */
1030 const struct oonf_layer2_metadata *
1031 oonf_layer2_net_metadata_get(enum oonf_layer2_network_index idx) {
1032   return &_metadata_net[idx];
1033 }
1034
1035 /**
1036  * Callback for configuration choice of layer2 network key
1037  * @param idx index
1038  * @param unused not used
1039  * @return pointer to network key
1040  */
1041 const char *
1042 oonf_layer2_cfg_get_l2net_key(size_t idx, const void *unused __attribute__((unused))) {
1043   return _metadata_net[idx].key;
1044 }
1045
1046 /**
1047  * Callback for configuration choice of layer2 neighbor key
1048  * @param idx index
1049  * @param unused not used
1050  * @return pointer to neighbor key
1051  */
1052 const char *
1053 oonf_layer2_cfg_get_l2neigh_key(size_t idx, const void *unused __attribute__((unused))) {
1054   return _metadata_neigh[idx].key;
1055 }
1056
1057 /**
1058  * Callback for configuration choice of layer2 neighbor key
1059  * @param idx index
1060  * @param unused not used
1061  * @return pointer to neighbor key
1062  */
1063 const char *
1064 oonf_layer2_cfg_get_l2comp(size_t idx, const void *unused __attribute__((unused))) {
1065   return _data_comparators[idx];
1066 }
1067
1068 /**
1069  * get text representation of network type
1070  * @param type network type
1071  * @return text representation
1072  */
1073 const char *
1074 oonf_layer2_net_get_type_name(enum oonf_layer2_network_type type) {
1075   return _network_type[type];
1076 }
1077
1078 /**
1079  * get tree of layer2 networks
1080  * @return network tree
1081  */
1082 struct avl_tree *
1083 oonf_layer2_get_net_tree(void) {
1084   return &_oonf_layer2_net_tree;
1085 }
1086
1087 /**
1088  * get tree of layer2 originators
1089  * @return originator tree
1090  */
1091 struct avl_tree *
1092 oonf_layer2_get_origin_tree(void) {
1093   return &_oonf_originator_tree;
1094 }
1095
1096 /**
1097  * Removes a layer-2 addr object from the database.
1098  * @param l2net layer-2 addr object
1099  */
1100 static void
1101 _net_remove(struct oonf_layer2_net *l2net) {
1102   struct oonf_layer2_neigh *l2neigh, *l2n_it;
1103   struct oonf_layer2_peer_address *l2peer, *l2peer_it;
1104
1105   /* free all embedded neighbors */
1106   avl_for_each_element_safe(&l2net->neighbors, l2neigh, _node, l2n_it) {
1107     _neigh_remove(l2neigh);
1108   }
1109
1110   /* free all attached peer addresses */
1111   avl_for_each_element_safe(&l2net->local_peer_ips, l2peer, _net_node, l2peer_it) {
1112     oonf_layer2_net_remove_ip(l2peer, l2peer->origin);
1113   }
1114
1115   oonf_class_event(&_l2network_class, l2net, OONF_OBJECT_REMOVED);
1116
1117   /* remove interface listener */
1118   os_interface_remove(&l2net->if_listener);
1119
1120   /* free addr */
1121   avl_remove(&_oonf_layer2_net_tree, &l2net->_node);
1122   oonf_class_free(&_l2network_class, l2net);
1123 }
1124
1125 /**
1126  * Removes a layer-2 neighbor object from the database
1127  * @param l2neigh layer-2 neighbor object
1128  */
1129 static void
1130 _neigh_remove(struct oonf_layer2_neigh *l2neigh) {
1131   struct oonf_layer2_destination *l2dst, *l2dst_it;
1132   struct oonf_layer2_neighbor_address *l2addr, *l2addr_it;
1133
1134   /* free all embedded destinations */
1135   avl_for_each_element_safe(&l2neigh->destinations, l2dst, _node, l2dst_it) {
1136     oonf_layer2_destination_remove(l2dst);
1137   }
1138
1139   /* free all attached neighbor addresses */
1140   avl_for_each_element_safe(&l2neigh->remote_neighbor_ips, l2addr, _neigh_node, l2addr_it) {
1141     oonf_layer2_neigh_remove_ip(l2addr, l2addr->origin);
1142   }
1143
1144   /* inform user that mac entry will be removed */
1145   oonf_class_event(&_l2neighbor_class, l2neigh, OONF_OBJECT_REMOVED);
1146
1147   /* free resources for mac entry */
1148   avl_remove(&l2neigh->network->neighbors, &l2neigh->_node);
1149   oonf_class_free(&_l2neighbor_class, l2neigh);
1150 }