Merge branch 'master' into mpr_rework
[oonf.git] / src-plugins / nhdp / nhdp / nhdp_domain.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_DOMAIN_H_
47 #define NHDP_DOMAIN_H_
48
49 #include "common/common_types.h"
50 #include "common/list.h"
51 #include "subsystems/oonf_rfc5444.h"
52
53 #include "nhdp/nhdp_interfaces.h"
54 #include "nhdp/nhdp_db.h"
55
56 /*! memory class for nhdp domain */
57 #define NHDP_CLASS_DOMAIN             "nhdp_domain"
58
59 /**
60  * NHDP domain constants
61  */
62 enum {
63   /*! maximum length of metric name */
64   NHDP_DOMAIN_METRIC_MAXLEN = 16,
65
66   /*! maximum length of mpr name */
67   NHDP_DOMAIN_MPR_MAXLEN = 16,
68 };
69
70 /**
71  * Buffer for string representation of a linkmetric value
72  */
73 struct nhdp_metric_str {
74   /*! buffer for maximum sized text link metric */
75   char buf[128];
76 };
77
78 /**
79  *  Metric handler for a NHDP domain.
80  */
81 struct nhdp_domain_metric {
82   /*! name of linkmetric */
83   const char *name;
84
85   /*! minimum metric value*/
86   uint32_t metric_minimum;
87
88   /*! maximum metric value */
89   uint32_t metric_maximum;
90
91   /*! default incoming link metric for "no default handling" metrics */
92   uint32_t incoming_link_start;
93
94   /*! default outgoing link metric for "no default handling" metrics */
95   uint32_t outgoing_link_start;
96
97   /*! default incoming 2-hop link metric for "no default handling" metrics */
98   uint32_t incoming_2hop_start;
99
100   /*! default outgoing 2-hop link metric for "no default handling" metrics */
101   uint32_t outgoing_2hop_start;
102
103   /*! true if metrics should not be handled by nhdp reader/writer */
104   bool no_default_handling;
105
106   /**
107    * callback to convert link metric into string representation
108    * @param buf buffer to put string into
109    * @param cost link metric
110    * @return pointer to buffer
111    */
112   const char *(*link_to_string)(struct nhdp_metric_str *buf, uint32_t cost);
113
114   /**
115    * callback to convert path metric into string representation
116    * @param buf buffer to put string into
117    * @param cost path metric
118    * @param hopcount hopcount of path
119    * @return pointer to buffer
120    */
121   const char *(*path_to_string)(struct nhdp_metric_str *buf,
122       uint32_t cost,  uint8_t hopcount);
123
124   /*! conversion of internal metric data into string */
125   /**
126    * callback to convert internal metric state into string
127    * @param buf buffer to put internal state into
128    * @param lnk nhdp link
129    * @return pointer to buffer
130    */
131   const char *(*internal_link_to_string)(
132       struct nhdp_metric_str *buf, struct nhdp_link *lnk);
133
134   /**
135    * callback to enable metric
136    */
137   void (*enable)(void);
138
139   /**
140    * callback to disable metric
141    */
142   void (*disable)(void);
143
144   /*! reference count */
145   int _refcount;
146
147   /*! node for tree of metrics */
148   struct avl_node _node;
149 };
150
151 struct nhdp_domain;
152
153 /**
154  * MPR handler for a NHDP domain
155  */
156 struct nhdp_domain_mpr {
157   /*! name of handler */
158   const char *name;
159
160   /**
161    * callback to calculate routing MPR set
162    * @param domain NHDP domain to update MPR set
163    */
164   void (*update_routing_mpr)(struct nhdp_domain *domain);
165
166   /**
167    * callback to calculate flooding MPR set
168    * @param domain NHDP domain used to update flooding MPR set
169    */
170   void (*update_flooding_mpr)(struct nhdp_domain *domain);
171
172   /**
173    * callback to enable mpr
174    */
175   void (*enable)(void);
176
177   /**
178    * callback to disable mpr
179    */
180   void (*disable)(void);
181
182   /*! reference count */
183   int _refcount;
184
185   /*! node for tree of MPR algorithms */
186   struct avl_node _node;
187 };
188
189 /**
190  * NHDP domain
191  *
192  * A domain is a topology on the mesh, including its own
193  * metric and routing MPR set. Both is transmitted over a
194  * specified TLV extension value on MPR and LQ TLVs.
195  */
196 struct nhdp_domain {
197   /*! name of metric */
198   char metric_name[NHDP_DOMAIN_METRIC_MAXLEN];
199
200   /*! name of MPR algorithm */
201   char mpr_name[NHDP_DOMAIN_MPR_MAXLEN];
202
203   /*! pointer to metric definition */
204   struct nhdp_domain_metric *metric;
205
206   /*! pointer to mpr definition */
207   struct nhdp_domain_mpr *mpr;
208
209   /*! flooding willingness */
210   uint8_t local_willingness;
211
212   /*! metric tlv extension */
213   uint8_t ext;
214
215   /*! index in the domain array */
216   int index;
217
218   /*! true if MPR should be recalculated */
219   bool _mpr_outdated;
220
221   /*! temporary storage for willingness processing */
222   uint8_t _tmp_willingness;
223
224   /*! storage for the up to four additional link metrics */
225   struct rfc5444_writer_tlvtype _metric_addrtlvs[4];
226
227   /*! list of nhdp domains */
228   struct list_entity _node;
229 };
230
231 /**
232  * listener for NHDP domain updates
233  */
234 struct nhdp_domain_listener {
235     /**
236      * Callback to inform about a NHDP neighbor MPR update
237      * @param domain NHDP domain of which the MPR set changed
238      */
239     void (*mpr_update)(struct nhdp_domain *domain);
240
241     /**
242      * Callback to inform about a NHDP neighbor metric update
243      * @param domain NHDP domain of which the metric changed
244      */
245     void (*metric_update)(struct nhdp_domain *domain);
246
247   /*! hook into global domain updater list */
248   struct list_entity _node;
249 };
250
251 /**
252  * Postprocessor for NHDP metric changes
253  */
254 struct nhdp_domain_metric_postprocessor {
255   /**
256    * Callback getting informed about a incoming metric change.
257    * @param domain domain the metric changed happened
258    * @param lnk nhdp link the metric change happened
259    * @param new_metric new metric value
260    * @return processed new metric value
261    */
262   uint32_t (*process_in_metric)(struct nhdp_domain *domain,
263       struct nhdp_link *lnk, uint32_t new_metric);
264
265   /*! hook into global domain metric postprocessor list */
266   struct list_entity _node;
267 };
268
269 void nhdp_domain_init(struct oonf_rfc5444_protocol *);
270 void nhdp_domain_cleanup(void);
271
272 EXPORT size_t nhdp_domain_get_count(void);
273 EXPORT struct nhdp_domain *nhdp_domain_add(uint8_t ext);
274 EXPORT struct nhdp_domain *nhdp_domain_configure(uint8_t ext,
275     const char *metric_name, const char *mpr_name, uint8_t willingness);
276
277 EXPORT int nhdp_domain_metric_add(struct nhdp_domain_metric *);
278 EXPORT void nhdp_domain_metric_remove(struct nhdp_domain_metric *);
279
280 EXPORT int nhdp_domain_mpr_add(struct nhdp_domain_mpr *);
281 EXPORT void nhdp_domain_mpr_remove(struct nhdp_domain_mpr *);
282
283 EXPORT void nhdp_domain_listener_add(struct nhdp_domain_listener *);
284 EXPORT void nhdp_domain_listener_remove(struct nhdp_domain_listener *);
285
286 EXPORT void nhdp_domain_metric_postprocessor_add(
287     struct nhdp_domain_metric_postprocessor *);
288 EXPORT void nhdp_domain_metric_postprocessor_remove(
289     struct nhdp_domain_metric_postprocessor *);
290 EXPORT struct nhdp_domain *nhdp_domain_get_by_ext(uint8_t);
291
292 EXPORT void nhdp_domain_init_link(struct nhdp_link *);
293 EXPORT void nhdp_domain_init_l2hop(struct nhdp_l2hop *);
294 EXPORT void nhdp_domain_init_neighbor(struct nhdp_neighbor *);
295
296 EXPORT void nhdp_domain_process_metric_linktlv(struct nhdp_domain *,
297     struct nhdp_link *lnk, const uint8_t *value);
298 EXPORT void nhdp_domain_process_metric_2hoptlv(struct nhdp_domain *d,
299     struct nhdp_l2hop *l2hop, const uint8_t *value);
300
301 EXPORT size_t nhdp_domain_process_mprtypes_tlv(
302     uint8_t *mprtypes, size_t mprtypes_size,
303     struct rfc5444_reader_tlvblock_entry *tlv);
304 EXPORT void nhdp_domain_process_mpr_tlv(uint8_t *mprtypes, size_t mprtypes_size,
305     struct nhdp_link *, struct rfc5444_reader_tlvblock_entry *tlv);
306 EXPORT void nhdp_domain_process_willingness_tlv(
307     uint8_t *mpr_types, size_t mprtypes_size,
308     struct rfc5444_reader_tlvblock_entry *tlv);
309 EXPORT void nhdp_domain_store_willingness(struct nhdp_link *);
310 EXPORT size_t nhdp_domain_encode_mprtypes_tlvvalue(
311     uint8_t *mprtypes, size_t mprtypes_size);
312 EXPORT size_t nhdp_domain_encode_mpr_tlvvalue(
313     uint8_t *tlvvalue, size_t tlvsize, struct nhdp_link *);
314 EXPORT size_t nhdp_domain_encode_willingness_tlvvalue(
315     uint8_t *tlvvalue, size_t tlvsize);
316
317 EXPORT bool nhdp_domain_set_incoming_metric(
318     struct nhdp_domain_metric *metric, struct nhdp_link *lnk, uint32_t metric_in);
319 EXPORT bool nhdp_domain_recalculate_metrics(
320     struct nhdp_domain *domain, struct nhdp_neighbor *neigh);
321
322 EXPORT bool nhdp_domain_node_is_mpr(void);
323 EXPORT void nhdp_domain_delayed_mpr_recalculation(
324     struct nhdp_domain *domain, struct nhdp_neighbor *neigh);
325 EXPORT void nhdp_domain_recalculate_mpr(void);
326
327 EXPORT struct list_entity *nhdp_domain_get_list(void);
328 EXPORT struct list_entity *nhdp_domain_get_listener_list(void);
329 EXPORT const struct nhdp_domain *nhdp_domain_get_flooding_domain(void);
330 EXPORT void nhdp_domain_set_flooding_mpr(const char *mpr_name, uint8_t willingness);
331 EXPORT const struct nhdp_domain *nhdp_domain_get_flooding_domain(void);
332
333 /**
334  * @param domain NHDP domain
335  * @param lnk NHDP link
336  * @return domain data of specified link
337  */
338 static INLINE struct nhdp_link_domaindata *
339 nhdp_domain_get_linkdata(const struct nhdp_domain *domain, struct nhdp_link *lnk) {
340   return &lnk->_domaindata[domain->index];
341 }
342
343 /**
344  * @param domain NHDP domain
345  * @param neigh NHDP neighbor
346  * @return domain data of specified neighbor
347  */
348 static INLINE struct nhdp_neighbor_domaindata *
349 nhdp_domain_get_neighbordata(
350     const struct nhdp_domain *domain, struct nhdp_neighbor *neigh) {
351   return &neigh->_domaindata[domain->index];
352 }
353
354 /**
355  * @param domain NHDP domain
356  * @param l2hop NHDP twohop neighbor
357  * @return domain data of specified twohop neighbor
358  */
359 static INLINE struct nhdp_l2hop_domaindata *
360 nhdp_domain_get_l2hopdata(
361     const struct nhdp_domain *domain, struct nhdp_l2hop *l2hop) {
362   return &l2hop->_domaindata[domain->index];
363 }
364
365
366 /**
367  * @param buf pointer to metric output buffer
368  * @param domain pointer to metric domain
369  * @param metric raw metric value
370  * @return pointer to string representation of metric
371  */
372 static INLINE const char *
373 nhdp_domain_get_link_metric_value(struct nhdp_metric_str *buf,
374     const struct nhdp_domain *domain, uint32_t metric) {
375   return domain->metric->link_to_string(buf, metric);
376 }
377
378 /**
379  * @param buf pointer to metric output buffer
380  * @param domain pointer to metric domain
381  * @param metric raw path metric value
382  * @param hopcount path hopcount
383  * @return pointer to string representation of metric
384  */
385 static INLINE const char *
386 nhdp_domain_get_path_metric_value(struct nhdp_metric_str *buf,
387     const struct nhdp_domain *domain, uint32_t metric, uint8_t hopcount) {
388   return domain->metric->path_to_string(buf, metric, hopcount);
389 }
390
391 /**
392  * @param buf pointer to metric output buffer
393  * @param metric pointer to metric
394  * @param lnk nhdp link
395  * @return pointer to string internal representation of metric
396  */
397 static INLINE const char *
398 nhdp_domain_get_internal_link_metric_value(struct nhdp_metric_str *buf,
399     const struct nhdp_domain_metric *metric, struct nhdp_link *lnk) {
400   return metric->internal_link_to_string(buf, lnk);
401 }
402
403 #endif /* NHDP_DOMAIN_H_ */