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