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