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