26609400d9bf8720a561f55f4630e924cd95c5b9
[olsrd.git] / src / lq_route.c
1 /*
2  * The olsr.org Optimized Link-State Routing daemon(olsrd)
3  * Copyright (c) 2004, Thomas Lopatic (thomas@lopatic.de)
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without 
7  * modification, are permitted provided that the following conditions 
8  * are met:
9  *
10  * * Redistributions of source code must retain the above copyright 
11  *   notice, this list of conditions and the following disclaimer.
12  * * Redistributions in binary form must reproduce the above copyright 
13  *   notice, this list of conditions and the following disclaimer in 
14  *   the documentation and/or other materials provided with the 
15  *   distribution.
16  * * Neither the name of olsr.org, olsrd nor the names of its 
17  *   contributors may be used to endorse or promote products derived 
18  *   from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
22  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 
23  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 
24  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 
26  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 
27  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
28  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 
30  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
31  * POSSIBILITY OF SUCH DAMAGE.
32  *
33  * Visit http://www.olsr.org for more information.
34  *
35  * If you find this software useful feel free to make a donation
36  * to the project. For more information see the website or contact
37  * the copyright holders.
38  *
39  * $Id: lq_route.c,v 1.38 2005/11/15 23:46:20 tlopatic Exp $
40  */
41
42 #include "defs.h"
43 #include "olsr.h"
44 #include "tc_set.h"
45 #include "neighbor_table.h"
46 #include "two_hop_neighbor_table.h"
47 #include "link_set.h"
48 #include "routing_table.h"
49 #include "mid_set.h"
50 #include "hna_set.h"
51 #include "lq_list.h"
52 #include "lq_avl.h"
53 #include "lq_route.h"
54
55 struct dijk_edge
56 {
57   struct avl_node tree_node;
58   struct list_node node;
59   struct dijk_vertex *dest;
60   float etx;
61 };
62
63 struct dijk_vertex
64 {
65   struct avl_node tree_node;
66   struct list_node node;
67   union olsr_ip_addr addr;
68   struct avl_tree edge_tree;
69   struct list edge_list;
70   float path_etx;
71   struct dijk_vertex *prev;
72   olsr_bool done;
73 };
74
75 static int avl_comp_ipv6(void *ip1, void *ip2)
76 {
77   return memcmp(ip1, ip2, ipsize);
78 }
79
80 static int avl_comp_ipv4(void *ip1, void *ip2)
81 {
82   if (*(unsigned int *)ip1 < *(unsigned int *)ip2)
83     return -1;
84
85   if (*(unsigned int *)ip1 == *(unsigned int *)ip2)
86     return 0;
87
88   return 1;
89 }
90
91 static int (*avl_comp)(void *, void *);
92
93 static void add_vertex(struct avl_tree *vertex_tree, union olsr_ip_addr *addr,
94                        float path_etx)
95 {
96   struct avl_node *node;
97   struct dijk_vertex *vert;
98
99   // see whether this destination is already in our list
100
101   node = avl_find(vertex_tree, addr);
102
103   // if it's not in our list, add it
104
105   if (node == NULL)
106   {
107     vert = olsr_malloc(sizeof (struct dijk_vertex), "Dijkstra vertex");
108
109     vert->tree_node.data = vert;
110     vert->tree_node.key = &vert->addr;
111
112     COPY_IP(&vert->addr, addr);
113     
114     vert->path_etx = path_etx;
115     vert->prev = NULL;
116     vert->done = OLSR_FALSE;
117
118     avl_init(&vert->edge_tree, avl_comp);
119     list_init(&vert->edge_list);
120
121     avl_insert(vertex_tree, &vert->tree_node);
122   }
123 }
124
125 static void add_edge(struct avl_tree *vertex_tree,
126                      union olsr_ip_addr *src, union olsr_ip_addr *dst,
127                      float etx)
128 {
129   struct avl_node *node;
130   struct dijk_vertex *svert;
131   struct dijk_vertex *dvert;
132   struct dijk_edge *edge;
133
134   // source lookup
135
136   node = avl_find(vertex_tree, src);
137
138   // source vertex does not exist
139
140   if (node == NULL)
141     return;
142
143   svert = node->data;
144
145   // destination lookup
146
147   node = avl_find(vertex_tree, dst);
148
149   // destination vertex does not exist
150
151   if (node == NULL)
152     return;
153
154   dvert = node->data;
155
156   // check for existing forward edge
157
158   if (avl_find(&svert->edge_tree, dst) == NULL)
159   {
160     // add forward edge
161
162     edge = olsr_malloc(sizeof (struct dijk_vertex), "Dijkstra edge 1");
163
164     edge->tree_node.data = edge;
165     edge->tree_node.key = &dvert->addr;
166
167     edge->node.data = edge;
168
169     edge->dest = dvert;
170     edge->etx = etx;
171
172     avl_insert(&svert->edge_tree, &edge->tree_node);
173     list_add_tail(&svert->edge_list, &edge->node);
174   }
175
176   // check for existing inverse edge
177
178   if (avl_find(&dvert->edge_tree, src) == NULL)
179   {
180     // add inverse edge
181
182     edge = olsr_malloc(sizeof (struct dijk_vertex), "Dijkstra edge 2");
183
184     edge->tree_node.data = edge;
185     edge->tree_node.key = &svert->addr;
186
187     edge->node.data = edge;
188
189     edge->dest = svert;
190     edge->etx = etx;
191
192     avl_insert(&dvert->edge_tree, &edge->tree_node);
193     list_add_tail(&dvert->edge_list, &edge->node);
194   }
195 }
196
197 static void create_vertex_list_rec(struct list *vertex_list,
198                                    struct avl_node *node,
199                                    int (*comp)(void *, void *))
200 {
201   struct dijk_vertex *vert = node->data;
202
203   if (node->left != NULL)
204     create_vertex_list_rec(vertex_list, node->left, comp);
205
206   // add the vertex to the list, if it's not us
207
208   if ((*comp)(&main_addr, node->key) != 0)
209   {
210     vert->node.data = vert;
211     list_add_tail(vertex_list, &vert->node);
212   }
213
214   if (node->right != NULL)
215     create_vertex_list_rec(vertex_list, node->right, comp);
216 }
217
218 static void create_vertex_list(struct avl_tree *vertex_tree,
219                                struct list *vertex_list)
220 {
221   struct avl_node *node;
222   struct dijk_vertex *vert;
223
224   // make ourselves the first vertex in the list
225
226   node = avl_find(vertex_tree, &main_addr);
227   vert = node->data;
228
229   vert->node.data = vert;
230   list_add_tail(vertex_list, &vert->node);
231
232   // add the remaining vertices ordered by their main address
233
234   create_vertex_list_rec(vertex_list, vertex_tree->root, vertex_tree->comp);
235 }
236
237 static void free_everything(struct list *vertex_list)
238 {
239   struct list_node *vnode, *enode;
240   struct dijk_vertex *vert;
241   struct dijk_edge *edge;
242
243   vnode = list_get_head(vertex_list);
244
245   // loop through all vertices
246
247   while (vnode != NULL)
248   {
249     vert = vnode->data;
250
251     enode = list_get_head(&vert->edge_list);
252
253     // loop through all edges of the current vertex
254
255     while (enode != NULL)
256     {
257       edge = enode->data;
258
259       enode = list_get_next(enode);
260       free(edge);
261     }
262
263     vnode = list_get_next(vnode);
264     free(vert);
265   }
266 }
267
268 // XXX - bad complexity
269
270 static struct dijk_vertex *extract_best(struct list *vertex_list)
271 {
272   float best_etx = INFINITE_ETX + 1.0;
273   struct list_node *node;
274   struct dijk_vertex *vert;
275   struct dijk_vertex *res = NULL;
276
277   node = list_get_head(vertex_list);
278
279   // loop through all vertices
280   
281   while (node != NULL)
282   {
283     vert = node->data;
284
285     // see whether the current vertex is better than what we have
286
287     if (!vert->done && vert->path_etx < best_etx)
288     {
289       best_etx = vert->path_etx;
290       res = vert;
291     }
292
293     node = list_get_next(node);
294   }
295
296   // if we've found a vertex, remove it from the set
297
298   if (res != NULL)
299     res->done = OLSR_TRUE;
300
301   return res;
302 }
303
304 static void relax(struct dijk_vertex *vert)
305 {
306   struct dijk_edge *edge;
307   float new_etx;
308   struct list_node *node;
309
310   node = list_get_head(&vert->edge_list);
311
312   // loop through all edges of this vertex
313
314   while (node != NULL)
315   {
316     edge = node->data;
317
318     // total quality of the path through this vertex to the
319     // destination of this edge
320
321     new_etx = vert->path_etx + edge->etx;
322
323     // if it's better than the current path quality of this
324     // edge's destination, then we've found a better path to
325     // this destination
326
327     if (new_etx < edge->dest->path_etx)
328     {
329       edge->dest->path_etx = new_etx;
330       edge->dest->prev = vert;
331     }
332
333     node = list_get_next(node);
334   }
335 }
336
337 static char *etx_to_string(float etx)
338 {
339   static char buff[20];
340
341   if (etx == INFINITE_ETX)
342     return "INF";
343
344   snprintf(buff, 20, "%.2f", etx);
345   return buff;
346 }
347
348 void olsr_calculate_lq_routing_table(void)
349 {
350   struct avl_tree vertex_tree;
351   struct list vertex_list;
352   int i;
353   struct tc_entry *tcsrc;
354   struct topo_dst *tcdst;
355   struct dijk_vertex *vert;
356   struct link_entry *link;
357   struct neighbor_entry *neigh;
358   struct list_node *node;
359   struct dijk_vertex *myself;
360   struct dijk_vertex *walker;
361   int hops;
362   struct mid_address *mid_walker;
363   float etx;
364   struct hna_entry *hna_gw;
365   struct hna_net *hna;
366   struct rt_entry *gw_rt, *hna_rt, *head_rt;
367   struct neighbor_2_entry *neigh2;
368 #if 0
369   struct neighbor_list_entry *neigh_walker;
370 #endif
371   struct interface *inter;
372
373   if (ipsize == 4)
374     avl_comp = avl_comp_ipv4;
375
376   else
377     avl_comp = avl_comp_ipv6;
378
379   // initialize the graph
380
381   avl_init(&vertex_tree, avl_comp);
382   list_init(&vertex_list);
383
384   // add ourselves to the vertex tree
385
386   add_vertex(&vertex_tree, &main_addr, 0.0);
387
388   // add our neighbours
389
390   for (i = 0; i < HASHSIZE; i++)
391     for (neigh = neighbortable[i].next; neigh != &neighbortable[i];
392          neigh = neigh->next)
393       if (neigh->status == SYM)
394         add_vertex(&vertex_tree, &neigh->neighbor_main_addr, INFINITE_ETX);
395
396   // add our two-hop neighbours
397
398   for (i = 0; i < HASHSIZE; i++)
399     for (neigh2 = two_hop_neighbortable[i].next;
400          neigh2 != &two_hop_neighbortable[i];
401          neigh2 = neigh2->next)
402       add_vertex(&vertex_tree, &neigh2->neighbor_2_addr, INFINITE_ETX);
403
404   // add remaining vertices
405
406   for (i = 0; i < HASHSIZE; i++)
407     for (tcsrc = tc_table[i].next; tcsrc != &tc_table[i]; tcsrc = tcsrc->next)
408     {
409       // add source
410
411       add_vertex(&vertex_tree, &tcsrc->T_last_addr, INFINITE_ETX);
412
413       // add destinations of this source
414
415       for (tcdst = tcsrc->destinations.next; tcdst != &tcsrc->destinations;
416            tcdst = tcdst->next)
417         add_vertex(&vertex_tree, &tcdst->T_dest_addr, INFINITE_ETX);
418     }
419
420   // add edges to and from our neighbours
421
422   for (i = 0; i < HASHSIZE; i++)
423     for (neigh = neighbortable[i].next; neigh != &neighbortable[i];
424          neigh = neigh->next)
425       if (neigh->status == SYM)
426       {
427         link = get_best_link_to_neighbor(&neigh->neighbor_main_addr);
428
429         if (link->loss_link_quality2 >= MIN_LINK_QUALITY &&
430             link->neigh_link_quality2 >= MIN_LINK_QUALITY)
431           {
432             etx = 1.0 / (link->loss_link_quality2 * link->neigh_link_quality2);
433
434             add_edge(&vertex_tree, &neigh->neighbor_main_addr, &main_addr, etx);
435           }
436       }
437
438 // we now rely solely on TC messages for routes to our two-hop neighbours
439
440 #if 0
441
442   // add edges between our neighbours and our two-hop neighbours
443
444   for (i = 0; i < HASHSIZE; i++)
445     for (neigh2 = two_hop_neighbortable[i].next;
446          neigh2 != &two_hop_neighbortable[i];
447          neigh2 = neigh2->next)
448       for (neigh_walker = neigh2->neighbor_2_nblist.next;
449            neigh_walker != &neigh2->neighbor_2_nblist;
450            neigh_walker = neigh_walker->next)
451       {
452         if (neigh_walker->second_hop_link_quality >=
453             MIN_LINK_QUALITY * MIN_LINK_QUALITY)
454         {
455           neigh = neigh_walker->neighbor;
456
457           etx = 1.0 / neigh_walker->second_hop_link_quality;
458
459           add_edge(&vertex_tree, &neigh2->neighbor_2_addr,
460                    &neigh->neighbor_main_addr, etx);
461         }
462       }
463
464 #endif
465
466   // add remaining edges
467
468   for (i = 0; i < HASHSIZE; i++)
469     for (tcsrc = tc_table[i].next; tcsrc != &tc_table[i]; tcsrc = tcsrc->next)
470       for (tcdst = tcsrc->destinations.next; tcdst != &tcsrc->destinations;
471            tcdst = tcdst->next)
472       {
473         if (tcdst->link_quality >= MIN_LINK_QUALITY &&
474             tcdst->inverse_link_quality >= MIN_LINK_QUALITY)
475           {
476             etx = 1.0 / (tcdst->link_quality * tcdst->inverse_link_quality);
477
478             add_edge(&vertex_tree, &tcdst->T_dest_addr, &tcsrc->T_last_addr,
479                      etx);
480           }
481       }
482
483   // create a sorted vertex list from the vertex tree
484
485   create_vertex_list(&vertex_tree, &vertex_list);
486
487   // run Dijkstra's algorithm
488
489   for (;;)
490   {
491     vert = extract_best(&vertex_list);
492
493     if (vert == NULL)
494       break;
495
496     relax(vert);
497   }
498
499   // save the old routing table
500
501   olsr_move_route_table(routingtable, old_routes);
502
503   node = list_get_head(&vertex_list);
504
505   // we're the first vertex in the list
506   
507   myself = node->data;
508
509   OLSR_PRINTF(2, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------- DIJKSTRA\n\n",
510               nowtm->tm_hour,
511               nowtm->tm_min,
512               nowtm->tm_sec,
513               (int)now.tv_usec/10000)
514
515   for (node = list_get_next(node); node != NULL; node = list_get_next(node))
516   {
517     vert = node->data;
518
519     hops = 1;
520
521     // count hops to until the path ends or until we have reached a
522     // one-hop neighbour
523
524     for (walker = vert; walker != NULL && walker->prev != myself;
525          walker = walker->prev)
526     {
527       OLSR_PRINTF(2, "%s:%s <- ", olsr_ip_to_string(&walker->addr),
528                   etx_to_string(walker->path_etx))
529       hops++;
530     }
531
532     // if no path to a one-hop neighbour was found, ignore this node
533
534     if (walker != NULL)
535     {
536       OLSR_PRINTF(2, "%s:%s (one-hop)\n", olsr_ip_to_string(&walker->addr),
537                   etx_to_string(walker->path_etx))
538
539       // node reachable => add to the set of unprocessed nodes
540       // for HNA processing
541
542       vert->done = OLSR_FALSE;
543     }
544
545     else
546     {
547       OLSR_PRINTF(2, "%s FAILED\n", olsr_ip_to_string(&vert->addr))
548       continue;
549     }
550
551     // find the best link to the one-hop neighbour
552
553     link = get_best_link_to_neighbor(&walker->addr);
554
555     // we may see NULL here, if the one-hop neighbour is not in the
556     // link and neighbour sets any longer, but we have derived an edge
557     // between us and the one-hop neighbour from the TC set
558
559     if (link != NULL)
560     {
561       // find the interface for the found link
562
563       inter = if_ifwithaddr(&link->local_iface_addr);
564
565       // we may see NULL here if the interface is down, but we have
566       // links that haven't timed out, yet
567
568       if (inter != NULL)
569       {
570         // XXX - fix me: structurally prevent duplicates, don't test via
571         //       olsr_lookup_routing_table()
572
573         // route addition, case A - add a route to the main address of the
574         // destination node
575
576         if (olsr_lookup_routing_table(&vert->addr) == NULL)
577           olsr_insert_routing_table(&vert->addr, &link->neighbor_iface_addr,
578                                     inter, hops, vert->path_etx);
579
580         // route addition, case B - add routes to the remaining interfaces
581         // of the destination node
582
583         for (mid_walker = mid_lookup_aliases(&vert->addr); mid_walker != NULL;
584              mid_walker = mid_walker->next_alias)
585           if (olsr_lookup_routing_table(&mid_walker->alias) == NULL)
586             olsr_insert_routing_table(&mid_walker->alias,
587                                       &link->neighbor_iface_addr, inter, hops, 
588                                       vert->path_etx);
589
590         // XXX - we used to use olsr_lookup_routing_table() only here, but
591         //       this assumed that case A or case B had already happened for
592         //       this destination; if case A or case B happened after case C
593         //       for the same destination, we had duplicates, as cases A and
594         //       B would not test whether case C had already happened
595
596         // route addition, case C - make sure that we have a route to the
597         // router - e.g. in case the router's not the main address and it's
598         // MID entry has timed out
599
600         if (olsr_lookup_routing_table(&link->neighbor_iface_addr) == NULL)
601           olsr_insert_routing_table(&link->neighbor_iface_addr,
602                                     &link->neighbor_iface_addr, inter, 1,
603                                     vert->path_etx);
604       }
605     }
606   }
607
608   // save the old HNA routing table
609
610   olsr_move_route_table(hna_routes, old_hna);
611
612   // add HNA routes - the set of unprocessed network nodes contains
613   // all reachable network nodes
614
615   for (;;)
616   {
617     // extract the network node with the best ETX and remove it
618     // from the set of unprocessed network nodes
619
620     vert = extract_best(&vertex_list);
621
622     // no more nodes left
623
624     if (vert == NULL)
625       break;
626
627     // find the node's HNAs
628
629     hna_gw = olsr_lookup_hna_gw(&vert->addr);
630
631     // node doesn't announce any HNAs
632
633     if (hna_gw == NULL)
634       continue;
635
636     // find route to the node
637
638     gw_rt = olsr_lookup_routing_table(&hna_gw->A_gateway_addr);
639
640     // maybe we haven't found a link or an interface for the gateway above
641     // and hence haven't added a route - skip the HNA in this case
642
643     if (gw_rt == NULL)
644       continue;
645
646     // loop through the node's HNAs
647
648     for (hna = hna_gw->networks.next; hna != &hna_gw->networks;
649          hna = hna->next)
650     {
651       // we already have a route via a previous (better) node
652
653       if (olsr_lookup_routing_table(&hna->A_network_addr) != NULL)
654         continue;
655
656       // create route for the HNA
657
658       hna_rt = olsr_malloc(sizeof(struct rt_entry), "LQ HNA route entry");
659
660       // set HNA IP address and netmask
661
662       COPY_IP(&hna_rt->rt_dst, &hna->A_network_addr);
663       hna_rt->rt_mask = hna->A_netmask;
664
665       // copy remaining fields from the node's route
666
667       COPY_IP(&hna_rt->rt_router, &gw_rt->rt_router);
668       hna_rt->rt_metric = gw_rt->rt_metric;
669       hna_rt->rt_etx = gw_rt->rt_etx;
670       hna_rt->rt_if = gw_rt->rt_if;
671
672       // we're not a host route
673
674       hna_rt->rt_flags = RTF_UP | RTF_GATEWAY;
675
676       // find the correct list
677
678       head_rt = &hna_routes[olsr_hashing(&hna->A_network_addr)];
679
680       // enqueue
681
682       head_rt->next->prev = hna_rt;
683       hna_rt->next = head_rt->next;
684
685       head_rt->next = hna_rt;
686       hna_rt->prev = head_rt;
687     }
688   }
689
690   // free the graph
691
692   free_everything(&vertex_list);
693
694   // move the route changes into the kernel
695
696   olsr_update_kernel_routes();
697   olsr_update_kernel_hna_routes();
698
699   // free the saved routing table
700
701   olsr_free_routing_table(old_routes);
702   olsr_free_routing_table(old_hna);
703 }