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