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