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