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