2 * OLSR ad-hoc routing table management protocol
3 * Copyright (C) 2004 Andreas Tønnesen (andreto@ifi.uio.no)
5 * This file is part of the olsr.org OLSR daemon.
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.
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.
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
22 * $Id: process_routes.c,v 1.12 2004/11/05 14:33:31 tlopatic Exp $
29 #include "kernel_routes.h"
32 #include "linux/tunnel.h"
37 #define strerror(x) StrError(x)
47 for(index=0;index<HASHSIZE;index++)
49 old_routes[index].next = &old_routes[index];
50 old_routes[index].prev = &old_routes[index];
51 old_hna[index].next = &old_hna[index];
52 old_hna[index].prev = &old_hna[index];
59 *Checks if there exists a route to a given host
60 *in a given hash table.
62 *@param dst the host to check for
63 *@param table the table to check
65 *@return 1 if the host exists in the table, 0 if not
68 olsr_find_up_route(struct rt_entry *dst, struct rt_entry *table)
70 struct rt_entry *destination;
73 hash = olsr_hashing(&dst->rt_dst);
75 for(destination = table[hash].next;
76 destination != &table[hash];
77 destination = destination->next)
79 //printf("Checking %s hc: %d ", olsr_ip_to_string(&dst->rt_dst), dst->rt_metric);
80 //printf("vs %s hc: %d ... ", olsr_ip_to_string(&destination->rt_dst), destination->rt_metric);
81 if (COMP_IP(&destination->rt_dst, &dst->rt_dst) &&
82 COMP_IP(&destination->rt_router, &dst->rt_router) &&
83 (destination->rt_if->if_nr == dst->rt_if->if_nr))
85 if(destination->rt_metric == dst->rt_metric)
102 *Create a list containing the entries in in_table
103 *that does not exist in from_table
105 *@param from_table the table to use
106 *@param in_table the routes already added
108 *@return a poiter to a linked list of routes to add
110 struct destination_n *
111 olsr_build_update_list(struct rt_entry *from_table,struct rt_entry *in_table)
113 struct destination_n *kernel_route_list = NULL;
114 struct destination_n *route_list = NULL;
115 struct rt_entry *destination;
118 for(index=0;index<HASHSIZE;index++)
120 for(destination = from_table[index].next;
121 destination != &from_table[index];
122 destination = destination->next)
124 if (!olsr_find_up_route(destination, in_table))
127 route_list = olsr_malloc(sizeof(struct destination_n), "create route tmp list");
129 route_list->destination = destination;
131 route_list->next = kernel_route_list;
132 kernel_route_list = route_list;
137 return (kernel_route_list);
145 *Deletes all OLSR routes
151 olsr_delete_all_kernel_routes()
153 struct destination_n *delete_kernel_list=NULL;
154 struct destination_n *tmp=NULL;
155 union olsr_ip_addr *tmp_addr;
157 olsr_u32_t tmp_tnl_addr;
160 olsr_printf(1, "Deleting all routes...\n");
165 /* Delete Internet GW tunnel */
166 delete_tunnel_route();
167 /* Take down tunnel */
170 set_up_gw_tunnel((union olsr_ip_addr *)&tmp_tnl_addr);
174 delete_kernel_list = olsr_build_update_list(hna_routes, old_hna);
176 tmp = delete_kernel_list;
178 olsr_printf(1, "HNA list:\n");
181 tmp_addr = &tmp->destination->rt_dst;
182 olsr_printf(1, "Dest: %s\n", olsr_ip_to_string(tmp_addr));
186 olsr_delete_routes_from_kernel(delete_kernel_list);
188 delete_kernel_list = olsr_build_update_list(routingtable,old_routes);
190 tmp = delete_kernel_list;
192 olsr_printf(1, "Route list:\n");
195 tmp_addr = &tmp->destination->rt_dst;
196 olsr_printf(1, "Dest: %s\n", olsr_ip_to_string(tmp_addr));
200 olsr_delete_routes_from_kernel(delete_kernel_list);
207 *Perform all neccessary actions for an update of the
208 *routes in the kernel.
213 olsr_update_kernel_routes()
215 struct destination_n *delete_kernel_list = NULL;
216 struct destination_n *add_kernel_list = NULL;
218 olsr_printf(3, "Updating kernel routes...\n");
219 delete_kernel_list = olsr_build_update_list(old_routes, routingtable);
220 add_kernel_list = olsr_build_update_list(routingtable, old_routes);
221 //#warning deletion and addition of routes swapped in 0.4.7 - TEST!
222 olsr_add_routes_in_kernel(add_kernel_list);
223 olsr_delete_routes_from_kernel(delete_kernel_list);
229 *Perform all neccessary actions for an update of the
230 *HNA routes in the kernel.
235 olsr_update_kernel_hna_routes()
237 struct destination_n *delete_kernel_list = NULL;
238 //struct destination_n *delete_kernel_list2;
239 struct destination_n *add_kernel_list = NULL;
241 olsr_printf(3, "Updating kernel HNA routes...\n");
244 delete_kernel_list = olsr_build_update_list(old_hna, hna_routes);
245 add_kernel_list = olsr_build_update_list(hna_routes, old_hna);
247 olsr_delete_routes_from_kernel(delete_kernel_list);
248 olsr_add_routes_in_kernel(add_kernel_list);
253 *Create a copy of the routing table and
254 *clear the current table
256 *@param original the table to move from
257 *@param the table to move to
262 olsr_move_route_table(struct rt_entry *original, struct rt_entry *new)
266 for(index=0;index<HASHSIZE;index++)
268 if(original[index].next == &original[index])
270 new[index].next = &new[index];
271 new[index].prev = &new[index];
276 new[index].next = original[index].next;
277 new[index].next->prev = &new[index];
278 new[index].prev = original[index].prev;
279 new[index].prev->next = &new[index];
282 original[index].next = &original[index];
283 original[index].prev = &original[index];
290 *Delete a linked list of routes from the kernel.
292 *@param delete_kernel_list the list to delete
297 olsr_delete_routes_from_kernel(struct destination_n *delete_kernel_list)
299 struct destination_n *destination_kernel;
302 while(delete_kernel_list!=NULL)
304 if(olsr_cnf->ip_version == AF_INET)
307 error = olsr_ioctl_del_route(delete_kernel_list->destination);
312 error = olsr_ioctl_del_route6(delete_kernel_list->destination);
318 olsr_printf(1, "Delete route:%s\n", strerror(errno));
319 olsr_syslog(OLSR_LOG_ERR, "Delete route:%m");
322 destination_kernel=delete_kernel_list;
323 delete_kernel_list=delete_kernel_list->next;
325 free(destination_kernel);
333 *Add a list of routes to the kernel. Adding
334 *is done by hopcount to be sure a route
335 *to the nexthop is added.
337 *@param add_kernel_list the linked list of routes to add
342 olsr_add_routes_in_kernel(struct destination_n *add_kernel_list)
344 struct destination_n *destination_kernel = NULL;
345 struct destination_n *previous_node = add_kernel_list;
347 int metric_counter = 0, first_run = 1;
350 //printf("Calculating routes\n");
352 while(add_kernel_list != NULL)
354 //searching for all the items with metric equal to n
355 for(destination_kernel = add_kernel_list; destination_kernel != NULL; )
357 if((destination_kernel->destination->rt_metric == metric_counter) &&
359 COMP_IP(&destination_kernel->destination->rt_dst, &destination_kernel->destination->rt_router)) || !first_run))
361 /* First add all 1-hop routes that has themselves as GW */
363 if(olsr_cnf->ip_version == AF_INET)
364 error=olsr_ioctl_add_route(destination_kernel->destination);
366 error=olsr_ioctl_add_route6(destination_kernel->destination);
368 if(error < 0) //print the error msg
370 olsr_printf(1, "Add route: %s\n",strerror(errno));
371 olsr_syslog(OLSR_LOG_ERR, "Add route:%m");
374 //getting rid of this node and hooking up the broken point
375 if(destination_kernel == add_kernel_list)
377 destination_kernel = add_kernel_list->next;
378 free(add_kernel_list);
379 add_kernel_list = destination_kernel;
380 previous_node=add_kernel_list;
384 previous_node->next = destination_kernel->next;
385 free(destination_kernel);
386 destination_kernel = previous_node->next;
391 previous_node = destination_kernel;
392 destination_kernel = destination_kernel->next;