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