Removed GW tunneling code
[olsrd.git] / src / process_routes.c
1 /*
2  * OLSR ad-hoc routing table management protocol
3  * Copyright (C) 2004 Andreas T√łnnesen (andreto@ifi.uio.no)
4  *
5  * This file is part of the olsr.org OLSR daemon.
6  *
7  * olsr.org is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * olsr.org is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with olsr.org; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  * 
22  * $Id: process_routes.c,v 1.13 2004/11/17 19:21:42 kattemat Exp $
23  *
24  */
25
26
27 #include "defs.h"
28 #include "olsr.h"
29 #include "kernel_routes.h"
30
31 #ifdef WIN32
32 #undef strerror
33 #define strerror(x) StrError(x)
34 #endif
35
36
37
38 int
39 olsr_init_old_table()
40 {
41   int index;
42
43   for(index=0;index<HASHSIZE;index++)
44     {
45       old_routes[index].next = &old_routes[index];
46       old_routes[index].prev = &old_routes[index];
47       old_hna[index].next = &old_hna[index];
48       old_hna[index].prev = &old_hna[index];
49     }
50
51   return 1;
52 }
53
54 /**
55  *Checks if there exists a route to a given host
56  *in a given hash table.
57  *
58  *@param dst the host to check for
59  *@param table the table to check
60  *
61  *@return 1 if the host exists in the table, 0 if not
62  */
63 int
64 olsr_find_up_route(struct rt_entry *dst, struct rt_entry *table)
65
66   struct rt_entry *destination;
67   olsr_u32_t      hash;
68  
69   hash = olsr_hashing(&dst->rt_dst);
70
71   for(destination = table[hash].next;
72       destination != &table[hash];
73       destination = destination->next)
74     {
75       //printf("Checking %s hc: %d ", olsr_ip_to_string(&dst->rt_dst), dst->rt_metric);
76       //printf("vs %s hc: %d ... ", olsr_ip_to_string(&destination->rt_dst), destination->rt_metric);      
77       if (COMP_IP(&destination->rt_dst, &dst->rt_dst) &&
78           COMP_IP(&destination->rt_router, &dst->rt_router) &&
79           (destination->rt_if->if_nr == dst->rt_if->if_nr))
80         {
81           if(destination->rt_metric == dst->rt_metric)
82             {
83               return 1;
84             }
85           else
86             {
87               return 0;
88             }
89         }
90     }
91
92   return 0;
93
94 }
95
96
97 /**
98  *Create a list containing the entries in in_table
99  *that does not exist in from_table
100  *
101  *@param from_table the table to use
102  *@param in_table the routes already added
103  *
104  *@return a poiter to a linked list of routes to add
105  */
106 struct destination_n *
107 olsr_build_update_list(struct rt_entry *from_table,struct rt_entry *in_table)
108 {
109   struct destination_n *kernel_route_list = NULL;
110   struct destination_n *route_list = NULL;
111   struct rt_entry      *destination;
112   olsr_u8_t            index;
113   
114   for(index=0;index<HASHSIZE;index++)
115     {
116       for(destination = from_table[index].next;
117           destination != &from_table[index];
118           destination = destination->next)
119         {
120           if (!olsr_find_up_route(destination, in_table))
121             {
122               
123               route_list = olsr_malloc(sizeof(struct destination_n), "create route tmp list");
124               
125               route_list->destination = destination;
126               
127               route_list->next = kernel_route_list;
128               kernel_route_list = route_list;
129             }
130         }   
131     }
132   
133   return (kernel_route_list);
134 }
135
136
137
138
139
140 /**
141  *Deletes all OLSR routes
142  *
143  *
144  *@return 1
145  */
146 int
147 olsr_delete_all_kernel_routes()
148
149   struct destination_n *delete_kernel_list=NULL;
150   struct destination_n *tmp=NULL;
151   union olsr_ip_addr *tmp_addr;
152
153   olsr_printf(1, "Deleting all routes...\n");
154
155   delete_kernel_list = olsr_build_update_list(hna_routes, old_hna);
156
157   tmp = delete_kernel_list;
158
159   olsr_printf(1, "HNA list:\n");
160   while(tmp)
161     {
162       tmp_addr = &tmp->destination->rt_dst;
163       olsr_printf(1, "Dest: %s\n", olsr_ip_to_string(tmp_addr));
164       tmp = tmp->next;
165     }
166
167   olsr_delete_routes_from_kernel(delete_kernel_list);
168
169   delete_kernel_list = olsr_build_update_list(routingtable,old_routes);
170
171   tmp = delete_kernel_list;
172
173   olsr_printf(1, "Route list:\n");
174   while(tmp)
175     {
176       tmp_addr = &tmp->destination->rt_dst;
177       olsr_printf(1, "Dest: %s\n", olsr_ip_to_string(tmp_addr));
178       tmp = tmp->next;
179     }
180
181   olsr_delete_routes_from_kernel(delete_kernel_list);
182
183   return 1;
184 }
185
186
187 /**
188  *Perform all neccessary actions for an update of the 
189  *routes in the kernel.
190  *
191  *@return nada
192  */
193 void
194 olsr_update_kernel_routes()
195 {
196   struct destination_n *delete_kernel_list = NULL;
197   struct destination_n *add_kernel_list = NULL;
198   
199   olsr_printf(3, "Updating kernel routes...\n");
200   delete_kernel_list = olsr_build_update_list(old_routes, routingtable);
201   add_kernel_list = olsr_build_update_list(routingtable, old_routes);
202   //#warning deletion and addition of routes swapped in 0.4.7 - TEST!
203   olsr_add_routes_in_kernel(add_kernel_list);
204   olsr_delete_routes_from_kernel(delete_kernel_list);
205 }
206
207
208
209 /**
210  *Perform all neccessary actions for an update of the 
211  *HNA routes in the kernel.
212  *
213  *@return nada
214  */
215 void
216 olsr_update_kernel_hna_routes()
217 {
218   struct destination_n *delete_kernel_list = NULL;
219   //struct destination_n *delete_kernel_list2;
220   struct destination_n *add_kernel_list = NULL;
221
222   olsr_printf(3, "Updating kernel HNA routes...\n");
223
224
225   delete_kernel_list = olsr_build_update_list(old_hna, hna_routes);
226   add_kernel_list = olsr_build_update_list(hna_routes, old_hna);
227
228   olsr_delete_routes_from_kernel(delete_kernel_list);
229   olsr_add_routes_in_kernel(add_kernel_list);
230 }
231
232
233 /**
234  *Create a copy of the routing table and
235  *clear the current table
236  *
237  *@param original the table to move from
238  *@param the table to move to
239  *
240  *@return nada
241  */
242 void
243 olsr_move_route_table(struct rt_entry *original, struct rt_entry *new)
244 {
245   olsr_16_t index;
246
247   for(index=0;index<HASHSIZE;index++)
248     {
249       if(original[index].next == &original[index])
250         {
251           new[index].next = &new[index];
252           new[index].prev = &new[index];
253         }
254       else
255         {
256           /* Copy to old */
257           new[index].next = original[index].next;
258           new[index].next->prev = &new[index];
259           new[index].prev = original[index].prev;
260           new[index].prev->next = &new[index];
261
262           /* Clear original */
263           original[index].next = &original[index];
264           original[index].prev = &original[index];
265         }
266     }
267 }
268
269
270 /**
271  *Delete a linked list of routes from the kernel.
272  *
273  *@param delete_kernel_list the list to delete
274  *
275  *@return nada
276  */
277 void 
278 olsr_delete_routes_from_kernel(struct destination_n *delete_kernel_list)
279 {
280   struct destination_n *destination_kernel;
281   olsr_16_t error;
282
283   while(delete_kernel_list!=NULL)
284     {
285       if(olsr_cnf->ip_version == AF_INET)
286         {
287           /* IPv4 */
288           error = olsr_ioctl_del_route(delete_kernel_list->destination);
289         }
290       else
291         {
292           /* IPv6 */
293           error = olsr_ioctl_del_route6(delete_kernel_list->destination);
294         }
295
296
297       if(error < 0)
298         {
299           olsr_printf(1, "Delete route:%s\n", strerror(errno));
300           olsr_syslog(OLSR_LOG_ERR, "Delete route:%m");
301         }
302
303       destination_kernel=delete_kernel_list;
304       delete_kernel_list=delete_kernel_list->next;
305       
306       free(destination_kernel);
307     }
308
309
310   
311 }
312
313 /**
314  *Add a list of routes to the kernel. Adding
315  *is done by hopcount to be sure a route
316  *to the nexthop is added.
317  *
318  *@param add_kernel_list the linked list of routes to add
319  *
320  *@return nada
321  */
322 void 
323 olsr_add_routes_in_kernel(struct destination_n *add_kernel_list)
324 {
325   struct destination_n *destination_kernel = NULL;
326   struct destination_n *previous_node = add_kernel_list;
327   olsr_16_t error;
328   int metric_counter = 0, first_run = 1;
329   //char str[46];
330   
331   //printf("Calculating routes\n");
332   
333   while(add_kernel_list != NULL)
334     {
335       //searching for all the items with metric equal to n
336       for(destination_kernel = add_kernel_list; destination_kernel != NULL; )
337         {
338           if((destination_kernel->destination->rt_metric == metric_counter) &&
339              ((first_run && 
340                COMP_IP(&destination_kernel->destination->rt_dst, &destination_kernel->destination->rt_router)) || !first_run))
341             {
342               /* First add all 1-hop routes that has themselves as GW */
343
344               if(olsr_cnf->ip_version == AF_INET)
345                 error=olsr_ioctl_add_route(destination_kernel->destination);
346               else
347                 error=olsr_ioctl_add_route6(destination_kernel->destination);
348                     
349               if(error < 0) //print the error msg
350                 {
351                   olsr_printf(1, "Add route(%s): %s\n", olsr_ip_to_string(&destination_kernel->destination->rt_dst), strerror(errno));
352                   olsr_syslog(OLSR_LOG_ERR, "Add route:%m");
353                 }
354                     
355               //getting rid of this node and hooking up the broken point
356               if(destination_kernel == add_kernel_list) 
357                 {
358                   destination_kernel = add_kernel_list->next;
359                   free(add_kernel_list);
360                   add_kernel_list = destination_kernel;
361                   previous_node=add_kernel_list;
362                 }
363               else 
364                 {
365                   previous_node->next = destination_kernel->next;
366                   free(destination_kernel);
367                   destination_kernel = previous_node->next;
368                 }
369             }
370           else 
371             {
372               previous_node = destination_kernel;
373               destination_kernel = destination_kernel->next;
374             }
375                 
376         }
377       if(first_run)
378         first_run = 0;
379       else
380         ++metric_counter;
381     }
382         
383 }
384
385
386