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