Simplify NIIT configuration to boolean
[olsrd.git] / src / lq_plugin.c
1
2 /*
3  * The olsr.org Optimized Link-State Routing daemon(olsrd)
4  * Copyright (c) 2008 Henning Rogge <rogge@fgan.de>
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 #include "tc_set.h"
43 #include "link_set.h"
44 #include "olsr_spf.h"
45 #include "lq_packet.h"
46 #include "packet.h"
47 #include "olsr.h"
48 #include "two_hop_neighbor_table.h"
49 #include "common/avl.h"
50
51 #include "lq_plugin_default_float.h"
52 #include "lq_plugin_default_fpm.h"
53 #include "lq_plugin_default_ff.h"
54
55 #include <assert.h>
56
57 struct avl_tree lq_handler_tree;
58 struct lq_handler *active_lq_handler = NULL;
59
60 int
61 avl_strcasecmp(const void *str1, const void *str2)
62 {
63   return strcasecmp(str1, str2);
64 }
65
66 void
67 init_lq_handler_tree(void)
68 {
69   avl_init(&lq_handler_tree, &avl_strcasecmp);
70   register_lq_handler(&lq_etx_float_handler, LQ_ALGORITHM_ETX_FLOAT_NAME);
71   register_lq_handler(&lq_etx_fpm_handler, LQ_ALGORITHM_ETX_FPM_NAME);
72   register_lq_handler(&lq_etx_ff_handler, LQ_ALGORITHM_ETX_FF_NAME);
73
74   if (olsr_cnf->lq_algorithm == NULL) {
75     activate_lq_handler(LQ_ALGORITHM_ETX_FF_NAME);
76   }
77   else {
78     activate_lq_handler(olsr_cnf->lq_algorithm);
79   }
80 }
81
82 /*
83  * set_lq_handler
84  *
85  * this function is used by routing metric plugins to activate their link
86  * quality handler
87  *
88  * The name parameter is marked as "unused" to squelch a compiler warning if debug
89  * output is not active
90  *
91  * @param pointer to lq_handler structure
92  * @param name of the link quality handler for debug output
93  */
94 void
95 register_lq_handler(struct lq_handler *handler, const char *name)
96 {
97   struct lq_handler_node *node;
98   size_t name_size = sizeof(*node) + strlen(name) + 1;
99
100   node = olsr_malloc(name_size, "olsr lq handler");
101
102   strscpy(node->name, name, name_size);
103   node->node.key = node->name;
104   node->handler = handler;
105
106   avl_insert(&lq_handler_tree, &node->node, false);
107 }
108
109 void
110 activate_lq_handler(const char *name)
111 {
112   struct lq_handler_node *node;
113
114   node = (struct lq_handler_node *)avl_find(&lq_handler_tree, name);
115   if (node == NULL) {
116     OLSR_PRINTF(1, "Error, unknown lq_handler '%s'\n", name);
117     olsr_exit("", 1);
118   }
119
120   OLSR_PRINTF(1, "Using '%s' algorithm for lq calculation.\n", name);
121   active_lq_handler = node->handler;
122   active_lq_handler->initialize();
123 }
124
125 /*
126  * olsr_calc_tc_cost
127  *
128  * this function calculates the linkcost of a tc_edge_entry
129  *
130  * @param pointer to the tc_edge_entry
131  * @return linkcost
132  */
133 olsr_linkcost
134 olsr_calc_tc_cost(const struct tc_edge_entry * tc_edge)
135 {
136   assert((const char *)tc_edge + sizeof(*tc_edge) >= (const char *)tc_edge->linkquality);
137   return active_lq_handler->calc_tc_cost(tc_edge->linkquality);
138 }
139
140 /*
141  * olsr_serialize_hello_lq_pair
142  *
143  * this function converts the lq information of a lq_hello_neighbor into binary package
144  * format
145  *
146  * @param pointer to binary buffer to write into
147  * @param pointer to lq_hello_neighbor
148  * @return number of bytes that have been written
149  */
150 int
151 olsr_serialize_hello_lq_pair(unsigned char *buff, struct lq_hello_neighbor *neigh)
152 {
153   assert((const char *)neigh + sizeof(*neigh) >= (const char *)neigh->linkquality);
154   return active_lq_handler->serialize_hello_lq(buff, neigh->linkquality);
155 }
156
157 /*
158  * olsr_deserialize_hello_lq_pair
159  *
160  * this function reads the lq information of a binary package into a hello_neighbor
161  * It also initialize the cost variable of the hello_neighbor
162  *
163  * @param pointer to the current buffer pointer
164  * @param pointer to hello_neighbor
165  */
166 void
167 olsr_deserialize_hello_lq_pair(const uint8_t ** curr, struct hello_neighbor *neigh)
168 {
169   assert((const char *)neigh + sizeof(*neigh) >= (const char *)neigh->linkquality);
170   active_lq_handler->deserialize_hello_lq(curr, neigh->linkquality);
171   neigh->cost = active_lq_handler->calc_hello_cost(neigh->linkquality);
172 }
173
174 /*
175  * olsr_serialize_tc_lq_pair
176  *
177  * this function converts the lq information of a olsr_serialize_tc_lq_pair
178  * into binary package format
179  *
180  * @param pointer to binary buffer to write into
181  * @param pointer to olsr_serialize_tc_lq_pair
182  * @return number of bytes that have been written
183  */
184 int
185 olsr_serialize_tc_lq_pair(unsigned char *buff, struct tc_mpr_addr *neigh)
186 {
187   assert((const char *)neigh + sizeof(*neigh) >= (const char *)neigh->linkquality);
188   return active_lq_handler->serialize_tc_lq(buff, neigh->linkquality);
189 }
190
191 /*
192  * olsr_deserialize_tc_lq_pair
193  *
194  * this function reads the lq information of a binary package into a tc_edge_entry
195  *
196  * @param pointer to the current buffer pointer
197  * @param pointer to tc_edge_entry
198  */
199 void
200 olsr_deserialize_tc_lq_pair(const uint8_t ** curr, struct tc_edge_entry *edge)
201 {
202   assert((const char *)edge + sizeof(*edge) >= (const char *)edge->linkquality);
203   active_lq_handler->deserialize_tc_lq(curr, edge->linkquality);
204 }
205
206 /*
207  * olsr_update_packet_loss_worker
208  *
209  * this function is called every times a hello package for a certain link_entry
210  * is lost (timeout) or received. This way the lq-plugin can update the links link
211  * quality value.
212  *
213  * @param pointer to link_entry
214  * @param true if hello package was lost
215  */
216 void
217 olsr_update_packet_loss_worker(struct link_entry *entry, bool lost)
218 {
219   assert((const char *)entry + sizeof(*entry) >= (const char *)entry->linkquality);
220   active_lq_handler->packet_loss_handler(entry, entry->linkquality, lost);
221 }
222
223 /*
224  * olsr_memorize_foreign_hello_lq
225  *
226  * this function is called to copy the link quality information from a received
227  * hello package into a link_entry.
228  *
229  * @param pointer to link_entry
230  * @param pointer to hello_neighbor, if NULL the neighbor link quality information
231  * of the link entry has to be reset to "zero"
232  */
233 void
234 olsr_memorize_foreign_hello_lq(struct link_entry *local, struct hello_neighbor *foreign)
235 {
236   assert((const char *)local + sizeof(*local) >= (const char *)local->linkquality);
237   if (foreign) {
238     assert((const char *)foreign + sizeof(*foreign) >= (const char *)foreign->linkquality);
239     active_lq_handler->memorize_foreign_hello(local->linkquality, foreign->linkquality);
240   } else {
241     active_lq_handler->memorize_foreign_hello(local->linkquality, NULL);
242   }
243 }
244
245 /*
246  * get_link_entry_text
247  *
248  * this function returns the text representation of a link_entry cost value.
249  * It's not thread save and should not be called twice with the same println
250  * value in the same context (a single printf command for example).
251  *
252  * @param pointer to link_entry
253  * @param char separator between LQ and NLQ
254  * @param buffer for output
255  * @return pointer to a buffer with the text representation
256  */
257 const char *
258 get_link_entry_text(struct link_entry *entry, char separator, struct lqtextbuffer *buffer)
259 {
260   assert((const char *)entry + sizeof(*entry) >= (const char *)entry->linkquality);
261   return active_lq_handler->print_hello_lq(entry->linkquality, separator, buffer);
262 }
263
264 /*
265  * get_tc_edge_entry_text
266  *
267  * this function returns the text representation of a tc_edge_entry cost value.
268  * It's not thread save and should not be called twice with the same println
269  * value in the same context (a single printf command for example).
270  *
271  * @param pointer to tc_edge_entry
272  * @param char separator between LQ and NLQ
273  * @param pointer to buffer
274  * @return pointer to the buffer with the text representation
275  */
276 const char *
277 get_tc_edge_entry_text(struct tc_edge_entry *entry, char separator, struct lqtextbuffer *buffer)
278 {
279   assert((const char *)entry + sizeof(*entry) >= (const char *)entry->linkquality);
280   return active_lq_handler->print_tc_lq(entry->linkquality, separator, buffer);
281 }
282
283 /*
284  * get_linkcost_text
285  *
286  * This function transforms an olsr_linkcost value into it's text representation and copies
287  * the result into a buffer.
288  *
289  * @param linkcost value
290  * @param true to transform the cost of a route, false for a link
291  * @param pointer to buffer
292  * @return pointer to buffer filled with text
293  */
294 const char *
295 get_linkcost_text(olsr_linkcost cost, bool route, struct lqtextbuffer *buffer)
296 {
297   static const char *infinite = "INFINITE";
298
299   if (route) {
300     if (cost == ROUTE_COST_BROKEN) {
301       return infinite;
302     }
303   } else {
304     if (cost >= LINK_COST_BROKEN) {
305       return infinite;
306     }
307   }
308   return active_lq_handler->print_cost(cost, buffer);
309 }
310
311 /*
312  * olsr_copy_hello_lq
313  *
314  * this function copies the link quality information from a link_entry to a
315  * lq_hello_neighbor.
316  *
317  * @param pointer to target lq_hello_neighbor
318  * @param pointer to source link_entry
319  */
320 void
321 olsr_copy_hello_lq(struct lq_hello_neighbor *target, struct link_entry *source)
322 {
323   assert((const char *)target + sizeof(*target) >= (const char *)target->linkquality);
324   assert((const char *)source + sizeof(*source) >= (const char *)source->linkquality);
325   active_lq_handler->copy_link_lq_into_neigh(target->linkquality, source->linkquality);
326 }
327
328 /*
329  * olsr_copylq_link_entry_2_tc_mpr_addr
330  *
331  * this function copies the link quality information from a link_entry to a
332  * tc_mpr_addr.
333  *
334  * @param pointer to tc_mpr_addr
335  * @param pointer to link_entry
336  */
337 void
338 olsr_copylq_link_entry_2_tc_mpr_addr(struct tc_mpr_addr *target, struct link_entry *source)
339 {
340   assert((const char *)target + sizeof(*target) >= (const char *)target->linkquality);
341   assert((const char *)source + sizeof(*source) >= (const char *)source->linkquality);
342   active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
343 }
344
345 /*
346  * olsr_copylq_link_entry_2_tc_edge_entry
347  *
348  * this function copies the link quality information from a link_entry to a
349  * tc_edge_entry.
350  *
351  * @param pointer to tc_edge_entry
352  * @param pointer to link_entry
353  */
354 void
355 olsr_copylq_link_entry_2_tc_edge_entry(struct tc_edge_entry *target, struct link_entry *source)
356 {
357   assert((const char *)target + sizeof(*target) >= (const char *)target->linkquality);
358   assert((const char *)source + sizeof(*source) >= (const char *)source->linkquality);
359   active_lq_handler->copy_link_lq_into_tc(target->linkquality, source->linkquality);
360 }
361
362 /* clear the lq of a link set entry */
363 void olsr_clear_hello_lq(struct link_entry *link) {
364   active_lq_handler->clear_hello(link->linkquality);
365 }
366
367 /*
368  * olsr_clear_tc_lq
369  *
370  * this function resets the linkquality value of a tc_mpr_addr
371  *
372  * @param pointer to tc_mpr_addr
373  */
374 void
375 olsr_clear_tc_lq(struct tc_mpr_addr *target)
376 {
377   assert((const char *)target + sizeof(*target) >= (const char *)target->linkquality);
378   active_lq_handler->clear_tc(target->linkquality);
379 }
380
381 /*
382  * olsr_malloc_hello_neighbor
383  *
384  * this function allocates memory for an hello_neighbor inclusive
385  * linkquality data.
386  *
387  * @param id string for memory debugging
388  *
389  * @return pointer to hello_neighbor
390  */
391 struct hello_neighbor *
392 olsr_malloc_hello_neighbor(const char *id)
393 {
394   struct hello_neighbor *h;
395
396   h = olsr_malloc(sizeof(struct hello_neighbor) + active_lq_handler->hello_lq_size, id);
397
398   assert((const char *)h + sizeof(*h) >= (const char *)h->linkquality);
399   active_lq_handler->clear_hello(h->linkquality);
400   return h;
401 }
402
403 /*
404  * olsr_malloc_tc_mpr_addr
405  *
406  * this function allocates memory for an tc_mpr_addr inclusive
407  * linkquality data.
408  *
409  * @param id string for memory debugging
410  *
411  * @return pointer to tc_mpr_addr
412  */
413 struct tc_mpr_addr *
414 olsr_malloc_tc_mpr_addr(const char *id)
415 {
416   struct tc_mpr_addr *t;
417
418   t = olsr_malloc(sizeof(struct tc_mpr_addr) + active_lq_handler->tc_lq_size, id);
419
420   assert((const char *)t + sizeof(*t) >= (const char *)t->linkquality);
421   active_lq_handler->clear_tc(t->linkquality);
422   return t;
423 }
424
425 /*
426  * olsr_malloc_lq_hello_neighbor
427  *
428  * this function allocates memory for an lq_hello_neighbor inclusive
429  * linkquality data.
430  *
431  * @param id string for memory debugging
432  *
433  * @return pointer to lq_hello_neighbor
434  */
435 struct lq_hello_neighbor *
436 olsr_malloc_lq_hello_neighbor(const char *id)
437 {
438   struct lq_hello_neighbor *h;
439
440   h = olsr_malloc(sizeof(struct lq_hello_neighbor) + active_lq_handler->hello_lq_size, id);
441
442   assert((const char *)h + sizeof(*h) >= (const char *)h->linkquality);
443   active_lq_handler->clear_hello(h->linkquality);
444   return h;
445 }
446
447 /*
448  * olsr_malloc_link_entry
449  *
450  * this function allocates memory for an link_entry inclusive
451  * linkquality data.
452  *
453  * @param id string for memory debugging
454  *
455  * @return pointer to link_entry
456  */
457 struct link_entry *
458 olsr_malloc_link_entry(const char *id)
459 {
460   struct link_entry *h;
461
462   h = olsr_malloc(sizeof(struct link_entry) + active_lq_handler->hello_lq_size, id);
463
464   assert((const char *)h + sizeof(*h) >= (const char *)h->linkquality);
465   active_lq_handler->clear_hello(h->linkquality);
466   return h;
467 }
468
469 /**
470  * This function should be called whenever the current linkcost
471  * value changed in a relevant way.
472  *
473  * @param link pointer to current link
474  * @param newcost new cost of this link
475  */
476 void olsr_relevant_linkcost_change(void) {
477   if (olsr_cnf->lq_dlimit > 0) {
478     changes_neighborhood = true;
479     changes_topology = true;
480   }
481   else {
482     OLSR_PRINTF(3, "Skipping Dijkstra (1)\n");
483   }
484
485   /* XXX - we should check whether we actually announce this neighbour */
486   signal_link_changes(true);
487 }
488
489 /*
490  * Local Variables:
491  * c-basic-offset: 2
492  * indent-tabs-mode: nil
493  * End:
494  */