Keep statistics of logged warnings
[oonf.git] / src-plugins / nhdp / nhdp / nhdp_db.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 NHDP_DB_H_
47 #define NHDP_DB_H_
48
49 struct nhdp_neighbor;
50 struct nhdp_link;
51 struct nhdp_l2hop;
52 struct nhdp_laddr;
53
54 #include "common/common_types.h"
55 #include "common/avl.h"
56 #include "common/list.h"
57 #include "common/netaddr.h"
58 #include "subsystems/oonf_rfc5444.h"
59 #include "subsystems/oonf_timer.h"
60
61 #include "nhdp/nhdp.h"
62
63 /*! memory class for NHDP links */
64 #define NHDP_CLASS_LINK             "nhdp_link"
65
66 /*! memory class for NHDP link address */
67 #define NHDP_CLASS_LINK_ADDRESS     "nhdp_laddr"
68
69 /*! memory class for NHDP 2hop link */
70 #define NHDP_CLASS_LINK_2HOP        "nhdp_l2hop"
71
72 /*! memory class for NHDP neighbor */
73 #define NHDP_CLASS_NEIGHBOR         "nhdp_neighbor"
74
75 /*! memory class for NHDP neighbor address */
76 #define NHDP_CLASS_NEIGHBOR_ADDRESS "nhdp_naddr"
77
78 /**
79  * link status of NHDP neighbors
80  */
81 enum nhdp_link_status {
82   /*! link is pending */
83   NHDP_LINK_PENDING   = -1,
84
85   /*! link is lost */
86   NHDP_LINK_LOST      = RFC6130_LINKSTATUS_LOST,
87
88   /*! link is symmetric */
89   NHDP_LINK_SYMMETRIC = RFC6130_LINKSTATUS_SYMMETRIC,
90
91   /*! link has been heard */
92   NHDP_LINK_HEARD     = RFC6130_LINKSTATUS_HEARD,
93 };
94
95 /**
96  * NHDP db constants
97  */
98 enum {
99   /*! maximum text length of link status */
100   NHDP_LINK_STATUS_TXTLENGTH = 10
101 };
102
103 /**
104  * Represents a NHDP link metric pair
105  */
106 struct nhdp_metric {
107   /*! incoming link metric cost */
108   uint32_t in;
109
110   /*! outgoing link metric cost */
111   uint32_t out;
112 };
113
114 /**
115  * Data for one NHDP domain of a link
116  */
117 struct nhdp_link_domaindata {
118   /*! incoming and outgoing metric cost */
119   struct nhdp_metric metric;
120
121   /*! time when this metric value was changed */
122   uint64_t last_metric_change;
123 };
124
125 /**
126  * Data for one NHDP domain of a neighbor
127  */
128 struct nhdp_neighbor_domaindata {
129   /*! incoming and outgoing metric cost */
130   struct nhdp_metric metric;
131
132   /*! pointer to the best link available to the neighbor */
133   struct nhdp_link *best_link;
134
135   /*! interface index for the best link available to the neighbor */
136   unsigned best_link_ifindex;
137
138   /*! true if the local router has been selected as a MPR by the neighbor */
139   bool local_is_mpr;
140
141   /*! true if the neighbor has been selected as a MPR by this router */
142   bool neigh_is_mpr;
143
144   /*! Routing willingness of neighbor */
145   uint8_t willingness;
146 };
147
148 /**
149  * Data for one NHDP domain of a 2-hop neighbor
150  */
151 struct nhdp_l2hop_domaindata {
152   /*! incoming and outgoing metric */
153   struct nhdp_metric metric;
154 };
155
156 /**
157  * nhdl_link represents a link by a specific local interface to one interface
158  * of a one-hop neighbor.
159  */
160 struct nhdp_link {
161   /*! last received validity time */
162   uint64_t vtime_value;
163
164   /*! last received interval time */
165   uint64_t itime_value;
166
167   /*! timer that fires if this link is not symmetric anymore */
168   struct oonf_timer_instance sym_time;
169
170   /*! timer that fires if the last received neighbor HELLO timed out */
171   struct oonf_timer_instance heard_time;
172
173   /*! timer that fires when the link has to be removed from the database */
174   struct oonf_timer_instance vtime;
175
176   /*! cached status of the linked */
177   enum nhdp_link_status status;
178
179   /*! pointer to local interface for this link */
180   struct nhdp_interface *local_if;
181
182   /*! pointer to other (dualstack) representation of this link */
183   struct nhdp_link *dualstack_partner;
184
185   /*! pointer to neighbor entry of the other side of the link */
186   struct nhdp_neighbor *neigh;
187
188   /*! interface address used for NHDP of remote link end */
189   struct netaddr if_addr;
190
191   /*! mac address of remote link end */
192   struct netaddr remote_mac;
193
194   /*! timestamp when the current link status was set */
195   uint64_t last_status_change;
196
197   /*! internal field for NHDP processing */
198   int _process_count;
199
200   /*! tree of local addresses of the other side of the link */
201   struct avl_tree _addresses;
202
203   /*! tree of two-hop addresses reachable through the other side of the link */
204   struct avl_tree _2hop;
205
206   /*! member entry for global list of nhdp links */
207   struct list_entity _global_node;
208
209   /*! member entry for nhdp links of local interface */
210   struct list_entity _if_node;
211
212   /*! member entry for nhdp links of neighbor node */
213   struct list_entity _neigh_node;
214
215   /*! optional member node for interface tree of originators */
216   struct avl_node _originator_node;
217
218   /*! Array of link metrics */
219   struct nhdp_link_domaindata _domaindata[NHDP_MAXIMUM_DOMAINS];
220 };
221
222 /**
223  * nhdp_laddr represents an interface address of a link
224  */
225 struct nhdp_laddr {
226   /*! links interface address */
227   struct netaddr link_addr;
228
229   /*! link entry for address */
230   struct nhdp_link *link;
231
232   /*! internal variable for NHDP processing */
233   bool _might_be_removed;
234
235   /*! member entry for addresses of neighbor link */
236   struct avl_node _link_node;
237
238   /*! member entry for addresss of neighbor */
239   struct avl_node _neigh_node;
240
241   /*! member entry for interface tree of link addresses */
242   struct avl_node _if_node;
243 };
244
245 /**
246  * nhdp_l2hop represents an address of a two-hop neighbor
247  */
248 struct nhdp_l2hop {
249   /*! address of two-hop neighbor */
250   struct netaddr twohop_addr;
251
252   /*! true if neighbor is on the same interface as the link */
253   bool same_interface;
254
255   /*! link entry for two-hop address */
256   struct nhdp_link *link;
257
258   /*! validity time for this address */
259   struct oonf_timer_instance _vtime;
260
261   /*! member entry for two-hop addresses of neighbor link */
262   struct avl_node _link_node;
263
264   /*! member entry for interface list of two-hop addresses */
265   struct avl_node _if_node;
266
267   /*! Array of link metrics */
268   struct nhdp_l2hop_domaindata _domaindata[NHDP_MAXIMUM_DOMAINS];
269 };
270
271 /**
272  * nhdp_neighbor represents a neighbor node (with one or multiple interfaces
273  */
274 struct nhdp_neighbor {
275   /*! originator address of this node, might by type AF_UNSPEC */
276   struct netaddr originator;
277
278   /*! number of links to this neighbor which are symmetric */
279   int symmetric;
280
281   /*! pointer to other (dualstack) representation of this neighbor */
282   struct nhdp_neighbor *dualstack_partner;
283
284   /*! true if the local router has been selected as a MPR by the neighbor */
285   bool local_is_flooding_mpr;
286
287   /*! true if the neighbor has been selected as a MPR by this router */
288   bool neigh_is_flooding_mpr;
289   
290   /* ! true if the neighbor has been selected as an MPR during selection algorithm */
291   bool selection_is_mpr;
292
293   /*! Willingness of neighbor for flooding data */
294   uint8_t flooding_willingness;
295
296   /*! internal field for NHDP processing */
297   int _process_count;
298
299   /*!
300    * originator address of this node before it was changed.
301    * Mostly used in CHANGE events
302    */
303   struct netaddr _old_originator;
304
305   /*! list of links for this neighbor */
306   struct list_entity _links;
307
308   /*! tree of addresses of this neighbor */
309   struct avl_tree _neigh_addresses;
310
311   /*! tree of addresses of this neighbors links */
312   struct avl_tree _link_addresses;
313
314   /*! member entry for global list of neighbors */
315   struct list_entity _global_node;
316
317   /*! optional member node for global tree of originators */
318   struct avl_node _originator_node;
319
320   /*! Array of link metrics */
321   struct nhdp_neighbor_domaindata _domaindata[NHDP_MAXIMUM_DOMAINS];
322 };
323
324 /**
325  * nhdp_naddr represents an address of a known 1-hop neighbor
326  * or a former (lost) address which will be removed soon
327  */
328 struct nhdp_naddr {
329   /*! neighbor interface address */
330   struct netaddr neigh_addr;
331
332   /*! backlink to neighbor */
333   struct nhdp_neighbor *neigh;
334
335   /*! link address usage counter */
336   int laddr_count;
337
338   /*! validity time for this address when its lost */
339   struct oonf_timer_instance _lost_vtime;
340
341   /*! member entry for neighbor address tree */
342   struct avl_node _neigh_node;
343
344   /*! member entry for global neighbor address tree */
345   struct avl_node _global_node;
346
347   /**
348    * temporary variables for NHDP Hello processing
349    * true if address is part of the local interface
350    */
351   bool _this_if;
352
353   /**
354    * temporary variables for NHDP Hello processing
355    * true if address is considered for removal
356    */
357   bool _might_be_removed;
358 };
359
360 void nhdp_db_init(void);
361 void nhdp_db_cleanup(void);
362
363 EXPORT struct nhdp_neighbor *nhdp_db_neighbor_add(void);
364 EXPORT void nhdp_db_neighbor_remove(struct nhdp_neighbor *);
365 EXPORT void nhdp_db_neighbor_set_unsymmetric(struct nhdp_neighbor *neigh);
366 EXPORT void nhdp_db_neighbor_join(struct nhdp_neighbor *, struct nhdp_neighbor *);
367 EXPORT struct nhdp_naddr *nhdp_db_neighbor_addr_add(struct nhdp_neighbor *, const struct netaddr *);
368 EXPORT void nhdp_db_neighbor_addr_remove(struct nhdp_naddr *);
369 EXPORT void nhdp_db_neighbor_addr_move(struct nhdp_neighbor *, struct nhdp_naddr *);
370 EXPORT void nhdp_db_neighbor_set_originator(struct nhdp_neighbor *, const struct netaddr *);
371 EXPORT void nhdp_db_neighbor_connect_dualstack(struct nhdp_neighbor *, struct nhdp_neighbor *);
372 EXPORT void nhdp_db_neigbor_disconnect_dualstack(struct nhdp_neighbor *neigh);
373 EXPORT uint32_t nhdp_db_neighbor_get_set_id(void);
374
375 EXPORT struct nhdp_link *nhdp_db_link_add(struct nhdp_neighbor *ipv4, struct nhdp_interface *ipv6);
376 EXPORT void nhdp_db_link_remove(struct nhdp_link *);
377 EXPORT void nhdp_db_link_set_unsymmetric(struct nhdp_link *lnk);
378 EXPORT struct nhdp_laddr *nhdp_db_link_addr_add(struct nhdp_link *, const struct netaddr*);
379 EXPORT void nhdp_db_link_addr_remove(struct nhdp_laddr *);
380 EXPORT void nhdp_db_link_addr_move(struct nhdp_link *, struct nhdp_laddr *);
381 EXPORT struct nhdp_l2hop *nhdp_db_link_2hop_add(
382     struct nhdp_link *, const struct netaddr *);
383 EXPORT void nhdp_db_link_2hop_remove(struct nhdp_l2hop *);
384 EXPORT void nhdp_db_link_connect_dualstack(struct nhdp_link *ipv4, struct nhdp_link *ipv6);
385 EXPORT void nhdp_db_link_disconnect_dualstack(struct nhdp_link *lnk);
386
387 EXPORT int _nhdp_db_link_calculate_status(struct nhdp_link *lnk);
388 EXPORT void nhdp_db_link_update_status(struct nhdp_link *);
389
390 EXPORT const char *nhdp_db_link_status_to_string(struct nhdp_link *);
391
392 EXPORT struct list_entity *nhdp_db_get_neigh_list(void);
393 EXPORT struct list_entity *nhdp_db_get_link_list(void);
394 EXPORT struct avl_tree *nhdp_db_get_naddr_tree(void);
395 EXPORT struct avl_tree *nhdp_db_get_neigh_originator_tree(void);
396
397 /**
398  * @param addr network address
399  * @return corresponding neighbor address object, NULL if not found
400  */
401 static INLINE struct nhdp_naddr *
402 nhdp_db_neighbor_addr_get(const struct netaddr *addr) {
403   struct nhdp_naddr *naddr;
404   return avl_find_element(nhdp_db_get_naddr_tree(), addr, naddr, _global_node);
405 }
406
407 /**
408  * @param originator originator address
409  * @return corresponding nhdp neighbor, NULL if not found
410  */
411 static INLINE struct nhdp_neighbor *
412 nhdp_db_neighbor_get_by_originator(const struct netaddr *originator) {
413   struct nhdp_neighbor *neigh;
414   return avl_find_element(nhdp_db_get_neigh_originator_tree(), originator, neigh, _originator_node);
415 }
416
417 /**
418  * @param lnk nhdp link
419  * @param addr network address
420  * @return corresponding link address object, NULL if not found
421  */
422 static INLINE struct nhdp_laddr *
423 nhdp_db_link_addr_get(const struct nhdp_link *lnk, const struct netaddr *addr) {
424   struct nhdp_laddr *laddr;
425   return avl_find_element(&lnk->_addresses, addr, laddr, _link_node);
426 }
427
428 /**
429  * @param lnk nhdp link
430  * @param addr network address
431  * @return corresponding link two-hop neighbor address, NULL If not found
432  */
433 static INLINE struct nhdp_l2hop *
434 ndhp_db_link_2hop_get(const struct nhdp_link *lnk, const struct netaddr *addr) {
435   struct nhdp_l2hop *l2hop;
436   return avl_find_element(&lnk->_2hop, addr, l2hop, _link_node);
437 }
438
439 /**
440  * Sets the validity time of a nhdp link
441  * @param lnk pointer to nhdp link
442  * @param vtime validity time in milliseconds
443  */
444 static INLINE void
445 nhdp_db_link_set_vtime(
446     struct nhdp_link *lnk, uint64_t vtime) {
447   oonf_timer_set(&lnk->vtime, vtime);
448 }
449
450 /**
451  * Sets the time until a NHDP link is not considered heard anymore
452  * @param lnk pointer to nhdp link
453  * @param htime heard time in milliseconds
454  */
455 static INLINE void
456 nhdp_db_link_set_heardtime(
457     struct nhdp_link *lnk, uint64_t htime) {
458   oonf_timer_set(&lnk->heard_time, htime);
459 }
460
461 /**
462  * Sets the time until a NHDP link is not considered symmetric anymore
463  * @param lnk pointer to nhdp link
464  * @param stime symmetric time in milliseconds
465  */
466 static INLINE void
467 nhdp_db_link_set_symtime(
468     struct nhdp_link *lnk, uint64_t stime) {
469   oonf_timer_set(&lnk->sym_time, stime);
470   nhdp_db_link_update_status(lnk);
471 }
472
473 /**
474  * Set the validity time of a two-hop neighbor
475  * @param l2hop nhdp link two-hop neighbor
476  * @param vtime new validity time
477  */
478 static INLINE void
479 nhdp_db_link_2hop_set_vtime(
480     struct nhdp_l2hop *l2hop, uint64_t vtime) {
481   oonf_timer_set(&l2hop->_vtime, vtime);
482 }
483
484 /**
485  * Define a neighbor address as lost
486  * @param naddr nhdp neighbor address
487  * @param vtime time until lost address gets purged from the database
488  */
489 static INLINE void
490 nhdp_db_neighbor_addr_set_lost(struct nhdp_naddr *naddr, uint64_t vtime) {
491   oonf_timer_set(&naddr->_lost_vtime, vtime);
492 }
493
494 /**
495  * Define a neighbor address as not lost anymore
496  * @param naddr nhdp neighbor address
497  */
498 static INLINE void
499 nhdp_db_neighbor_addr_not_lost(struct nhdp_naddr *naddr) {
500   oonf_timer_stop(&naddr->_lost_vtime);
501 }
502
503 /**
504  * @param naddr nhdp neighbor address
505  * @return true if address is lost, false otherwise
506  */
507 static INLINE bool
508 nhdp_db_neighbor_addr_is_lost(const struct nhdp_naddr *naddr) {
509   return oonf_timer_is_active(&naddr->_lost_vtime);
510 }
511
512 /**
513  * @param lnk pointer to NHDP link
514  * @return true if link is part of a dualstack link
515  */
516 static INLINE bool
517 nhdp_db_link_is_dualstack(const struct nhdp_link *lnk) {
518   return lnk->dualstack_partner != NULL;
519 }
520
521 /**
522  * @param lnk pointer to NHDP link
523  * @param af_type address family type
524  * @return true if link is part of a dualstack link with the specified
525  *   address family
526  */
527 static INLINE bool
528 nhdp_db_link_is_dualstack_type(const struct nhdp_link *lnk, int af_type) {
529   return nhdp_db_link_is_dualstack(lnk)
530       && netaddr_get_address_family(&lnk->neigh->originator) == af_type;
531 }
532
533 /**
534  * @param lnk pointer to NHDP link
535  * @return true if link is the IPv4 part of a dualstack link
536  */
537 static INLINE bool
538 nhdp_db_link_is_ipv4_dualstack(const struct nhdp_link *lnk) {
539   return nhdp_db_link_is_dualstack_type(lnk, AF_INET);
540 }
541
542 /**
543  * @param lnk pointer to NHDP link
544  * @return true if link is the IPv6 part of a dualstack link
545  */
546 static INLINE bool
547 nhdp_db_link_is_ipv6_dualstack(const struct nhdp_link *lnk) {
548   return nhdp_db_link_is_dualstack_type(lnk, AF_INET6);
549 }
550
551 /**
552  * @param neigh pointer to NHDP neighbor
553  * @param af_type address family type
554  * @return true if neighbor is part of a dualstack neighbor with the
555  *   specified address family
556  */
557 static INLINE bool
558 nhdp_db_neighbor_is_dualstack_type(const struct nhdp_neighbor *neigh, int af_type) {
559   return neigh->dualstack_partner != NULL
560       && netaddr_get_address_family(&neigh->originator) == af_type;
561 }
562
563 /**
564  * @param neigh pointer to NHDP neighbor
565  * @return true if neighbor is the IPv4 part of a dualstack neighbor
566  */
567 static INLINE bool
568 nhdp_db_neighbor_is_ipv4_dualstack(const struct nhdp_neighbor *neigh) {
569   return nhdp_db_neighbor_is_dualstack_type(neigh, AF_INET);
570 }
571
572 /**
573  * @param neigh pointer to NHDP neighbor
574  * @return true if neighbor is the IPv6 part of a dualstack neighbor
575  */
576 static INLINE bool
577 nhdp_db_neighbor_is_ipv6_dualstack(const struct nhdp_neighbor *neigh) {
578   return nhdp_db_neighbor_is_dualstack_type(neigh, AF_INET6);
579 }
580
581 static INLINE bool
582 nhdp_db_2hop_is_lost(const struct nhdp_l2hop *l2hop) {
583   return oonf_timer_is_active(&l2hop->_vtime);
584 }
585 #endif /* NHDP_DB_H_ */