9ad81f81755674e61dbbf07b511d433514ce4f38
[oonf.git] / src-plugins / subsystems / oonf_layer2.h
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 #ifndef OONF_LAYER2_H_
47 #define OONF_LAYER2_H_
48
49 #include "common/avl.h"
50 #include "common/common_types.h"
51 #include "core/oonf_subsystem.h"
52 #include "subsystems/os_interface.h"
53
54 /*! subsystem identifier */
55 #define OONF_LAYER2_SUBSYSTEM "layer2"
56
57 /*! memory class for layer2 neighbor */
58 #define LAYER2_CLASS_NEIGHBOR "layer2_neighbor"
59
60 /*! memory class for layer2 network */
61 #define LAYER2_CLASS_NETWORK "layer2_network"
62
63 /*! memory class for layer2 destination */
64 #define LAYER2_CLASS_DESTINATION "layer2_destination"
65
66 /*! memory class for layer2 network address */
67 #define LAYER2_CLASS_NETWORK_ADDRESS "layer2_network_address"
68
69 /*! memory class for layer2 neighbor address */
70 #define LAYER2_CLASS_NEIGHBOR_ADDRESS "layer2_neighbor_address"
71
72 /* configuration Macros for Layer2 keys */
73
74 /**
75  * Creates a cfg_schema_entry for a parameter that can be choosen
76  * from the layer2 interface keys
77  * @param p_name parameter name
78  * @param p_def parameter default value
79  * @param p_help help text for configuration entry
80  * @param args variable list of additional arguments
81  */
82 #define CFG_VALIDATE_LAYER2_NET_KEY(p_name, p_def, p_help, args...)                                                    \
83   CFG_VALIDATE_CHOICE_CB_ARG(p_name, p_def, p_help, oonf_layer2_cfg_get_l2net_key, OONF_LAYER2_NET_COUNT, NULL, ##args)
84
85 /**
86  * Creates a cfg_schema_entry for a parameter that can be choosen
87  * from the layer2 interface keys
88  * @param p_name parameter name
89  * @param p_def parameter default value
90  * @param p_help help text for configuration entry
91  * @param args variable list of additional arguments
92  */
93 #define CFG_VALIDATE_LAYER2_NEIGH_KEY(p_name, p_def, p_help, args...)                                                  \
94   CFG_VALIDATE_CHOICE_CB_ARG(                                                                                          \
95     p_name, p_def, p_help, oonf_layer2_cfg_get_l2neigh_key, OONF_LAYER2_NEIGH_COUNT, NULL, ##args)
96
97 /**
98  * Creates a cfg_schema_entry for a parameter that can be choosen
99  * from the layer2 data comparators
100  * @param p_name parameter name
101  * @param p_def parameter default value
102  * @param p_help help text for configuration entry
103  * @param args variable list of additional arguments
104  */
105 #define CFG_VALIDATE_LAYER2_COMP(p_name, p_def, p_help, args...)                                                       \
106   CFG_VALIDATE_CHOICE_CB_ARG(                                                                                          \
107     p_name, p_def, p_help, oonf_layer2_cfg_get_l2comp, OONF_LAYER2_DATA_CMP_COUNT, NULL, ##args)
108
109 /**
110  * Creates a cfg_schema_entry for a parameter that can be choosen
111  * from the layer2 interface keys
112  * @param p_name parameter name
113  * @param p_def parameter default value
114  * @param p_help help text for configuration entry
115  * @param args variable list of additional arguments
116  */
117 #define CFG_MAP_CHOICE_L2NET(p_reference, p_field, p_name, p_def, p_help, args...)                                     \
118   CFG_MAP_CHOICE_CB_ARG(                                                                                               \
119     p_reference, p_field, p_name, p_def, p_help, oonf_layer2_cfg_get_l2net_key, OONF_LAYER2_NET_COUNT, NULL, ##args)
120
121 /**
122  * Creates a cfg_schema_entry for a parameter that can be choosen
123  * from the layer2 interface keys
124  * @param p_name parameter name
125  * @param p_def parameter default value
126  * @param p_help help text for configuration entry
127  * @param args variable list of additional arguments
128  */
129 #define CFG_MAP_CHOICE_L2NEIGH(p_reference, p_field, p_name, p_def, p_help, args...)                                   \
130   CFG_MAP_CHOICE_CB_ARG(p_reference, p_field, p_name, p_def, p_help, oonf_layer2_cfg_get_l2neigh_key,                  \
131     OONF_LAYER2_NEIGH_COUNT, NULL, ##args)
132
133 /**
134  * Creates a cfg_schema_entry for a parameter that can be choosen
135  * from the layer2 data comparators
136  * @param p_name parameter name
137  * @param p_def parameter default value
138  * @param p_help help text for configuration entry
139  * @param args variable list of additional arguments
140  */
141 #define CFG_MAP_CHOICE_L2COMP(p_reference, p_field, p_name, p_def, p_help, args...)                                    \
142   CFG_MAP_CHOICE_CB_ARG(                                                                                               \
143     p_reference, p_field, p_name, p_def, p_help, oonf_layer2_cfg_get_l2comp, OONF_LAYER2_DATA_CMP_COUNT, NULL, ##args)
144
145 /**
146  * priorities of layer2 originators
147  */
148 enum oonf_layer2_origin_priority
149 {
150   OONF_LAYER2_ORIGIN_UNKNOWN = 0,
151   OONF_LAYER2_ORIGIN_UNRELIABLE = 10,
152   OONF_LAYER2_ORIGIN_CONFIGURED = 20,
153   OONF_LAYER2_ORIGIN_RELIABLE = 30,
154 };
155
156 /**
157  * Origin for layer2 data
158  */
159 struct oonf_layer2_origin {
160   const char *name;
161
162   /*! true if data will be constantly updated by a plugin */
163   bool proactive;
164
165   /*! priority of this originator */
166   enum oonf_layer2_origin_priority priority;
167
168   /*! node for tree of originators */
169   struct avl_node _node;
170 };
171
172 enum oonf_layer2_data_type
173 {
174   OONF_LAYER2_NO_DATA,
175   OONF_LAYER2_INTEGER_DATA,
176   OONF_LAYER2_BOOLEAN_DATA,
177   OONF_LAYER2_NETWORK_DATA,
178
179   OONF_LAYER2_DATA_TYPE_COUNT,
180 };
181
182 union oonf_layer2_value {
183   int64_t integer;
184   bool boolean;
185   struct netaddr addr;
186 };
187
188 /**
189  * Single data entry of layer2 network or neighbor
190  */
191 struct oonf_layer2_data {
192   /*! data value */
193   union oonf_layer2_value _value;
194
195   /*! type of data contained in this element */
196   enum oonf_layer2_data_type _type;
197
198   /*! layer2 originator id */
199   const struct oonf_layer2_origin *_origin;
200 };
201
202 /**
203  * Metadata of layer2 data entry for automatic processing
204  */
205 struct oonf_layer2_metadata {
206   /*! type of data */
207   const char key[16];
208
209   /*! data type */
210   enum oonf_layer2_data_type type;
211
212   /*! unit (bit/s, byte, ...) */
213   const char unit[8];
214
215   /*! number of fractional digits of the data */
216   const int fraction;
217 };
218
219 /**
220  * Comparator options for layer2 data
221  */
222 enum oonf_layer2_data_comparator_type
223 {
224   OONF_LAYER2_DATA_CMP_EQUALS,
225   OONF_LAYER2_DATA_CMP_NOT_EQUALS,
226   OONF_LAYER2_DATA_CMP_LESSER,
227   OONF_LAYER2_DATA_CMP_LESSER_OR_EQUALS,
228   OONF_LAYER2_DATA_CMP_GREATER,
229   OONF_LAYER2_DATA_CMP_GREATER_OR_EQUALS,
230
231   OONF_LAYER2_DATA_CMP_COUNT,
232
233   OONF_LAYER2_DATA_CMP_ILLEGAL = -1,
234 };
235
236 /**
237  * list of layer2 network metrics
238  */
239 enum oonf_layer2_network_index
240 {
241   /*! primary center frequency */
242   OONF_LAYER2_NET_FREQUENCY_1,
243
244   /*! optional secondary center frequency */
245   OONF_LAYER2_NET_FREQUENCY_2,
246
247   /*! primary bandwidth */
248   OONF_LAYER2_NET_BANDWIDTH_1,
249
250   /*! optional secondary bandwidth */
251   OONF_LAYER2_NET_BANDWIDTH_2,
252
253   /*! noise level in dBm */
254   OONF_LAYER2_NET_NOISE,
255
256   /*! total time in ns the channel was active */
257   OONF_LAYER2_NET_CHANNEL_ACTIVE,
258
259   /*! total time in ns the channel was busy */
260   OONF_LAYER2_NET_CHANNEL_BUSY,
261
262   /*! total time in ns the channel was receiving */
263   OONF_LAYER2_NET_CHANNEL_RX,
264
265   /*! total time in ns the channel was transmitting */
266   OONF_LAYER2_NET_CHANNEL_TX,
267
268   /*! maixmum size of an IP packet for this interface */
269   OONF_LAYER2_NET_MTU,
270
271   /*! true if unicast traffic is necessary for ratecontrol */
272   OONF_LAYER2_NET_MCS_BY_PROBING,
273
274   /*! true if interface does not support incoming broadcast/multicast */
275   OONF_LAYER2_NET_RX_ONLY_UNICAST,
276
277   /*! true if interface does not support incoming broadcast/multicast */
278   OONF_LAYER2_NET_TX_ONLY_UNICAST,
279
280   /*! number of layer2 network metrics */
281   OONF_LAYER2_NET_COUNT,
282 };
283
284 /**
285  * list with types of layer2 networks
286  */
287 enum oonf_layer2_network_type
288 {
289   OONF_LAYER2_TYPE_UNDEFINED,
290   OONF_LAYER2_TYPE_WIRELESS,
291   OONF_LAYER2_TYPE_ETHERNET,
292   OONF_LAYER2_TYPE_TUNNEL,
293
294   OONF_LAYER2_TYPE_COUNT,
295 };
296
297 /**
298  * list of layer2 neighbor metrics
299  */
300 enum oonf_layer2_neighbor_index
301 {
302   /*! outgoing signal in milli dBm */
303   OONF_LAYER2_NEIGH_TX_SIGNAL,
304
305   /*! incoming signal in milli dBm */
306   OONF_LAYER2_NEIGH_RX_SIGNAL,
307
308   /*! outgoing bitrate in bit/s */
309   OONF_LAYER2_NEIGH_TX_BITRATE,
310
311   /*! incoming bitrate in bit/s */
312   OONF_LAYER2_NEIGH_RX_BITRATE,
313
314   /*! incoming broadcast bitrate in bit/s */
315   OONF_LAYER2_NEIGH_RX_BC_BITRATE,
316
317   /*! maximum possible outgoing bitrate in bit/s */
318   OONF_LAYER2_NEIGH_TX_MAX_BITRATE,
319
320   /*! maximum possible incoming bitrate in bit/s */
321   OONF_LAYER2_NEIGH_RX_MAX_BITRATE,
322
323   /*! total number of transmitted bytes */
324   OONF_LAYER2_NEIGH_TX_BYTES,
325
326   /*! total number of received bytes */
327   OONF_LAYER2_NEIGH_RX_BYTES,
328
329   /*! total number of transmitted frames */
330   OONF_LAYER2_NEIGH_TX_FRAMES,
331
332   /*! total number of received frames */
333   OONF_LAYER2_NEIGH_RX_FRAMES,
334
335   /*! average outgoing throughput in bit/s */
336   OONF_LAYER2_NEIGH_TX_THROUGHPUT,
337
338   /*! total number of frame retransmission */
339   OONF_LAYER2_NEIGH_TX_RETRIES,
340
341   /*! total number of failed frame transmissions */
342   OONF_LAYER2_NEIGH_TX_FAILED,
343
344   /*! latency to neighbor in microseconds */
345   OONF_LAYER2_NEIGH_LATENCY,
346
347   /*! available resources of radio (0-100) */
348   OONF_LAYER2_NEIGH_RESOURCES,
349
350   /*! relative transmission link quality (0-100) */
351   OONF_LAYER2_NEIGH_TX_RLQ,
352
353   /*! relative receiver link quality (0-100) */
354   OONF_LAYER2_NEIGH_RX_RLQ,
355
356   /*! number of neighbor metrics */
357   OONF_LAYER2_NEIGH_COUNT,
358 };
359
360 /**
361  * representation of a layer2 interface
362  */
363 struct oonf_layer2_net {
364   /*! name of local interface */
365   char name[IF_NAMESIZE];
366
367   /*! optional identification string */
368   char if_ident[64];
369
370   /*! interface type */
371   enum oonf_layer2_network_type if_type;
372
373   /*! interface data is delivered by DLEP */
374   bool if_dlep;
375
376   /*! interface listener to keep track of events and local mac address */
377   struct os_interface_listener if_listener;
378
379   /*! tree of remote neighbors */
380   struct avl_tree neighbors;
381
382   /*! tree of IP addresses/prefixes of local radio/modem */
383   struct avl_tree local_peer_ips;
384
385   /*! global tree of all remote neighbor IPs */
386   struct avl_tree remote_neighbor_ips;
387
388   /*! absolute timestamp when network has been active last */
389   uint64_t last_seen;
390
391   /*! network wide layer 2 data */
392   struct oonf_layer2_data data[OONF_LAYER2_NET_COUNT];
393
394   /*! default values of neighbor layer2 data */
395   struct oonf_layer2_data neighdata[OONF_LAYER2_NEIGH_COUNT];
396
397   /*! node to hook into global l2network tree */
398   struct avl_node _node;
399 };
400
401 /**
402  * IP addresses that are attached to a local radio/modem
403  */
404 struct oonf_layer2_peer_address {
405   /*! ip address attached to a local radio/modem */
406   struct netaddr ip;
407
408   /*! backlink to layer2 network */
409   struct oonf_layer2_net *l2net;
410
411   /*! origin of this address */
412   const struct oonf_layer2_origin *origin;
413
414   /*! node for global tree of network IP addresses */
415   struct avl_node _global_node;
416
417   /*! node for tree of ip addresses in network */
418   struct avl_node _net_node;
419 };
420
421 /**
422  * representation of a remote layer2 neighbor
423  */
424 struct oonf_layer2_neigh {
425   /*! remote mac address of neighbor */
426   struct netaddr addr;
427
428   /*! back pointer to layer2 network */
429   struct oonf_layer2_net *network;
430
431   /*! tree of proxied destinations */
432   struct avl_tree destinations;
433
434   /*! tree of IP addresses/prefixes of remote neighbor router */
435   struct avl_tree remote_neighbor_ips;
436
437   /*! absolute timestamp when neighbor has been active last */
438   uint64_t last_seen;
439
440   /*! neigbor layer 2 data */
441   struct oonf_layer2_data data[OONF_LAYER2_NEIGH_COUNT];
442
443   /*! node to hook into tree of layer2 network */
444   struct avl_node _node;
445 };
446
447 /**
448  * IP addresses that are attached to a remote router
449  */
450 struct oonf_layer2_neighbor_address {
451   /*! ip address attached to a remote router */
452   struct netaddr ip;
453
454   /*! backlink to layer2 neighbor*/
455   struct oonf_layer2_neigh *l2neigh;
456
457   /*! origin of this address */
458   const struct oonf_layer2_origin *origin;
459
460   /*! (interface) global tree of neighbor IP addresses */
461   struct avl_node _net_node;
462
463   /*! node for tree of ip addresses */
464   struct avl_node _neigh_node;
465 };
466
467 /**
468  * representation of a bridged MAC address behind a layer2 neighbor
469  */
470 struct oonf_layer2_destination {
471   /*! proxied mac address behind a layer2 neighbor */
472   struct netaddr destination;
473
474   /*! back pointer to layer2 neighbor */
475   struct oonf_layer2_neigh *neighbor;
476
477   /*! origin of this proxied address */
478   const struct oonf_layer2_origin *origin;
479
480   /*! node to hook into tree of layer2 neighbor */
481   struct avl_node _node;
482 };
483
484 EXPORT void oonf_layer2_origin_add(struct oonf_layer2_origin *origin);
485 EXPORT void oonf_layer2_origin_remove(struct oonf_layer2_origin *origin);
486
487 EXPORT int oonf_layer2_data_parse_string(
488   union oonf_layer2_value *value, const struct oonf_layer2_metadata *meta, const char *input);
489 EXPORT const char *oonf_layer2_data_to_string(
490   char *buffer, size_t length, const struct oonf_layer2_data *data, const struct oonf_layer2_metadata *meta, bool raw);
491 EXPORT bool oonf_layer2_data_set(struct oonf_layer2_data *data, const struct oonf_layer2_origin *origin,
492   enum oonf_layer2_data_type type, const union oonf_layer2_value *input);
493 EXPORT bool oonf_layer2_data_compare(const union oonf_layer2_value *left, const union oonf_layer2_value *right,
494   enum oonf_layer2_data_comparator_type comparator, enum oonf_layer2_data_type data_type);
495 EXPORT enum oonf_layer2_data_comparator_type oonf_layer2_data_get_comparator(const char *);
496 EXPORT const char *oonf_layer2_data_get_comparator_string(enum oonf_layer2_data_comparator_type type);
497 EXPORT const char *oonf_layer2_data_get_type_string(enum oonf_layer2_data_type type);
498
499 EXPORT struct oonf_layer2_net *oonf_layer2_net_add(const char *ifname);
500 EXPORT bool oonf_layer2_net_remove(struct oonf_layer2_net *, const struct oonf_layer2_origin *origin);
501 EXPORT bool oonf_layer2_net_cleanup(
502   struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin, bool cleanup_neigh);
503 EXPORT bool oonf_layer2_net_commit(struct oonf_layer2_net *);
504 EXPORT void oonf_layer2_net_relabel(struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *new_origin,
505   const struct oonf_layer2_origin *old_origin);
506 EXPORT struct oonf_layer2_peer_address *oonf_layer2_net_add_ip(
507   struct oonf_layer2_net *l2net, const struct oonf_layer2_origin *origin, const struct netaddr *ip);
508 EXPORT int oonf_layer2_net_remove_ip(struct oonf_layer2_peer_address *ip, const struct oonf_layer2_origin *origin);
509 EXPORT struct oonf_layer2_neighbor_address *oonf_layer2_net_get_best_neighbor_match(const struct netaddr *addr);
510 EXPORT struct avl_tree *oonf_layer2_net_get_remote_ip_tree(void);
511
512 EXPORT struct oonf_layer2_neigh *oonf_layer2_neigh_add(struct oonf_layer2_net *, const struct netaddr *l2neigh);
513 EXPORT bool oonf_layer2_neigh_cleanup(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin);
514 EXPORT bool oonf_layer2_neigh_remove(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin);
515 EXPORT bool oonf_layer2_neigh_commit(struct oonf_layer2_neigh *l2neigh);
516 EXPORT void oonf_layer2_neigh_relabel(struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *new_origin,
517   const struct oonf_layer2_origin *old_origin);
518 EXPORT struct oonf_layer2_neighbor_address *oonf_layer2_neigh_add_ip(
519   struct oonf_layer2_neigh *l2neigh, const struct oonf_layer2_origin *origin, const struct netaddr *ip);
520 EXPORT int oonf_layer2_neigh_remove_ip(
521   struct oonf_layer2_neighbor_address *ip, const struct oonf_layer2_origin *origin);
522
523 EXPORT struct oonf_layer2_destination *oonf_layer2_destination_add(
524   struct oonf_layer2_neigh *l2neigh, const struct netaddr *destination, const struct oonf_layer2_origin *origin);
525 EXPORT void oonf_layer2_destination_remove(struct oonf_layer2_destination *);
526
527 EXPORT const struct oonf_layer2_data *oonf_layer2_neigh_query(
528   const char *ifname, const struct netaddr *l2neigh, enum oonf_layer2_neighbor_index idx);
529 EXPORT const struct oonf_layer2_data *oonf_layer2_neigh_get_data(
530   const struct oonf_layer2_neigh *l2neigh, enum oonf_layer2_neighbor_index idx);
531
532 EXPORT const struct oonf_layer2_metadata *oonf_layer2_neigh_metadata_get(enum oonf_layer2_neighbor_index);
533 EXPORT const struct oonf_layer2_metadata *oonf_layer2_net_metadata_get(enum oonf_layer2_network_index);
534 EXPORT const char *oonf_layer2_cfg_get_l2net_key(size_t index, const void *unused);
535 EXPORT const char *oonf_layer2_cfg_get_l2neigh_key(size_t index, const void *unused);
536 EXPORT const char *oonf_layer2_cfg_get_l2comp(size_t index, const void *unused);
537
538 EXPORT const char *oonf_layer2_net_get_type_name(enum oonf_layer2_network_type);
539
540 EXPORT struct avl_tree *oonf_layer2_get_net_tree(void);
541 EXPORT struct avl_tree *oonf_layer2_get_origin_tree(void);
542
543 /**
544  * Checks if a layer2 originator is registered
545  * @param origin originator
546  * @return true if registered, false otherwise
547  */
548 static INLINE bool
549 oonf_layer2_origin_is_added(const struct oonf_layer2_origin *origin) {
550   return avl_is_node_added(&origin->_node);
551 }
552
553 /**
554  * Get a layer-2 interface object from the database
555  * @param ifname name of interface
556  * @return layer-2 addr object, NULL if not found
557  */
558 static INLINE struct oonf_layer2_net *
559 oonf_layer2_net_get(const char *ifname) {
560   struct oonf_layer2_net *l2net;
561   return avl_find_element(oonf_layer2_get_net_tree(), ifname, l2net, _node);
562 }
563
564 /**
565  * Get a layer-2 local peer ip address object from the database
566  * @param l2net layer-2 network/interface object
567  * @param ip ip address of local radio/modem
568  * @return layer-2 ip address object, NULL if not found
569  */
570 static INLINE struct oonf_layer2_peer_address *
571 oonf_layer2_net_get_local_ip(const struct oonf_layer2_net *l2net, const struct netaddr *addr) {
572   struct oonf_layer2_peer_address *l2ip;
573   return avl_find_element(&l2net->local_peer_ips, addr, l2ip, _net_node);
574 }
575
576 /**
577  * Get a layer-2 ip address object from the database
578  * @param l2net layer-2 network object
579  * @param ip ip address of remote router
580  * @return layer-2 ip address object, NULL if not found
581  */
582 static INLINE struct oonf_layer2_neighbor_address *
583 oonf_layer2_net_get_remote_ip(const struct oonf_layer2_net *l2net, const struct netaddr *addr) {
584   struct oonf_layer2_neighbor_address *l2ip;
585   return avl_find_element(&l2net->remote_neighbor_ips, addr, l2ip, _net_node);
586 }
587
588 /**
589  * Get a layer-2 neighbor object from the database
590  * @param l2net layer-2 network/interface object
591  * @param addr remote mac address of neighbor
592  * @return layer-2 neighbor object, NULL if not found
593  */
594 static INLINE struct oonf_layer2_neigh *
595 oonf_layer2_neigh_get(const struct oonf_layer2_net *l2net, const struct netaddr *addr) {
596   struct oonf_layer2_neigh *l2neigh;
597   return avl_find_element(&l2net->neighbors, addr, l2neigh, _node);
598 }
599
600 /**
601  * Get a layer-2 ip address object from the database
602  * @param l2neigh layer-2 neighbor object
603  * @param ip ip address of remote router
604  * @return layer-2 ip address object, NULL if not found
605  */
606 static INLINE struct oonf_layer2_neighbor_address *
607 oonf_layer2_neigh_get_remote_ip(const struct oonf_layer2_neigh *l2neigh, const struct netaddr *addr) {
608   struct oonf_layer2_neighbor_address *l2ip;
609   return avl_find_element(&l2neigh->remote_neighbor_ips, addr, l2ip, _neigh_node);
610 }
611
612 /**
613  * Get a layer-2 destination (secondary MAC) for a neighbor
614  * @param l2neigh layer-2 neighbor object
615  * @param destination mac address of destination
616  * @return layer-2 destination object, NULL if not found
617  */
618 static INLINE struct oonf_layer2_destination *
619 oonf_layer2_destination_get(const struct oonf_layer2_neigh *l2neigh, const struct netaddr *destination) {
620   struct oonf_layer2_destination *l2dst;
621   return avl_find_element(&l2neigh->destinations, destination, l2dst, _node);
622 }
623
624 /**
625  * @param l2data layer-2 data object
626  * @return true if object contains a value, false otherwise
627  */
628 static INLINE bool
629 oonf_layer2_data_has_value(const struct oonf_layer2_data *l2data) {
630   return l2data->_type != OONF_LAYER2_NO_DATA;
631 }
632
633 /**
634  * @param l2data layer-2 data object
635  * @return type of data in object
636  */
637 static INLINE enum oonf_layer2_data_type
638 oonf_layer2_data_get_type(const struct oonf_layer2_data *l2data) {
639   return l2data->_type;
640 }
641
642 /**
643  * @param l2data layer-2 data object
644  * @param def default value to return
645  * @return value of data object, default value if not net
646  */
647 static INLINE int64_t
648 oonf_layer2_data_get_int64(const struct oonf_layer2_data *l2data, int64_t def) {
649   if (l2data->_type != OONF_LAYER2_INTEGER_DATA) {
650     return def;
651   }
652   return l2data->_value.integer;
653 }
654
655 /**
656  * @param l2data layer-2 data object
657  * @param def default value to return
658  * @return value of data object, default value if not net
659  */
660 static INLINE bool
661 oonf_layer2_data_get_boolean(const struct oonf_layer2_data *l2data, bool def) {
662   if (l2data->_type != OONF_LAYER2_BOOLEAN_DATA) {
663     return def;
664   }
665   return l2data->_value.boolean;
666 }
667
668 /**
669  * @param buffer pointer to int64 data storage
670  * @param l2data layer-2 data object
671  * @return 0 if value was read, -1 if it was the wrong type
672  */
673 static INLINE int
674 oonf_layer2_data_read_int64(int64_t *buffer, const struct oonf_layer2_data *l2data) {
675   if (l2data->_type != OONF_LAYER2_INTEGER_DATA) {
676     return -1;
677   }
678   *buffer = l2data->_value.integer;
679   return 0;
680 }
681
682 /**
683  * @param buffer pointer to boolean data storage
684  * @param l2data layer-2 data object
685  * @return 0 if value was read, -1 if it was the wrong type
686  */
687 static INLINE int
688 oonf_layer2_data_read_boolean(bool *buffer, const struct oonf_layer2_data *l2data) {
689   if (l2data->_type != OONF_LAYER2_BOOLEAN_DATA) {
690     return -1;
691   }
692   *buffer = l2data->_value.boolean;
693   return 0;
694 }
695
696 /**
697  * @param l2data layer-2 data object
698  * @return originator of data value
699  */
700 static INLINE const struct oonf_layer2_origin *
701 oonf_layer2_data_get_origin(const struct oonf_layer2_data *l2data) {
702   return l2data->_origin;
703 }
704
705 /**
706  * Sets the originator of a layer-2 data object
707  * @param l2data layer-2 data object
708  * @param origin originator of data value
709  */
710 static INLINE void
711 oonf_layer2_data_set_origin(struct oonf_layer2_data *l2data, const struct oonf_layer2_origin *origin) {
712   l2data->_origin = origin;
713 }
714
715 static INLINE bool
716 oonf_layer2_data_from_string(struct oonf_layer2_data *data, const struct oonf_layer2_origin *origin,
717   const struct oonf_layer2_metadata *meta, const char *input) {
718   union oonf_layer2_value value;
719
720   if (oonf_layer2_data_parse_string(&value, meta, input)) {
721     return false;
722   }
723   return oonf_layer2_data_set(data, origin, meta->type, &value);
724 }
725
726 static INLINE const char *
727 oonf_layer2_net_data_to_string(
728   char *buffer, size_t length, const struct oonf_layer2_data *data, enum oonf_layer2_network_index idx, bool raw) {
729   return oonf_layer2_data_to_string(buffer, length, data, oonf_layer2_net_metadata_get(idx), raw);
730 }
731
732 static INLINE const char *
733 oonf_layer2_neigh_data_to_string(
734   char *buffer, size_t length, const struct oonf_layer2_data *data, enum oonf_layer2_neighbor_index idx, bool raw) {
735   return oonf_layer2_data_to_string(buffer, length, data, oonf_layer2_neigh_metadata_get(idx), raw);
736 }
737
738 /**
739  * Set the value of a layer-2 data object
740  * @param l2data layer-2 data object
741  * @param origin originator of value
742  * @param integer new value for data object
743  * @return true if value was overwrite, false otherwise
744  */
745 static INLINE bool
746 oonf_layer2_data_set_int64(struct oonf_layer2_data *l2data, const struct oonf_layer2_origin *origin, int64_t integer) {
747   union oonf_layer2_value value = { 0 };
748   value.integer = integer;
749
750   return oonf_layer2_data_set(l2data, origin, OONF_LAYER2_INTEGER_DATA, &value);
751 }
752
753 /**
754  * Set the value of a layer-2 data object
755  * @param l2data layer-2 data object
756  * @param origin originator of value
757  * @param boolean new value for data object
758  * @return true if value was overwrite, false otherwise
759  */
760 static INLINE bool
761 oonf_layer2_data_set_bool(struct oonf_layer2_data *l2data, const struct oonf_layer2_origin *origin, bool boolean) {
762   union oonf_layer2_value value = { 0 };
763   value.boolean = boolean;
764   return oonf_layer2_data_set(l2data, origin, OONF_LAYER2_BOOLEAN_DATA, &value);
765 }
766
767 static INLINE int
768 oonf_layer2_net_data_from_string(struct oonf_layer2_data *data, enum oonf_layer2_network_index idx,
769   struct oonf_layer2_origin *origin, const char *input) {
770   return oonf_layer2_data_from_string(data, origin, oonf_layer2_net_metadata_get(idx), input);
771 }
772
773 static INLINE int
774 oonf_layer2_neigh_data_from_string(struct oonf_layer2_data *data, enum oonf_layer2_neighbor_index idx,
775   struct oonf_layer2_origin *origin, const char *input) {
776   return oonf_layer2_data_from_string(data, origin, oonf_layer2_neigh_metadata_get(idx), input);
777 }
778
779 /**
780  * Removes the value of a layer-2 data object
781  * @param l2data layer-2 data object
782  */
783 static INLINE void
784 oonf_layer2_data_reset(struct oonf_layer2_data *l2data) {
785   l2data->_type = OONF_LAYER2_NO_DATA;
786   l2data->_origin = NULL;
787 }
788
789 #endif /* OONF_LAYER2_H_ */