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.13 2004/11/17 19:21:42 kattemat Exp $
29 #include "kernel_routes.h"
33 #define strerror(x) StrError(x)
43 for(index=0;index<HASHSIZE;index++)
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];
55 *Checks if there exists a route to a given host
56 *in a given hash table.
58 *@param dst the host to check for
59 *@param table the table to check
61 *@return 1 if the host exists in the table, 0 if not
64 olsr_find_up_route(struct rt_entry *dst, struct rt_entry *table)
66 struct rt_entry *destination;
69 hash = olsr_hashing(&dst->rt_dst);
71 for(destination = table[hash].next;
72 destination != &table[hash];
73 destination = destination->next)
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))
81 if(destination->rt_metric == dst->rt_metric)
98 *Create a list containing the entries in in_table
99 *that does not exist in from_table
101 *@param from_table the table to use
102 *@param in_table the routes already added
104 *@return a poiter to a linked list of routes to add
106 struct destination_n *
107 olsr_build_update_list(struct rt_entry *from_table,struct rt_entry *in_table)
109 struct destination_n *kernel_route_list = NULL;
110 struct destination_n *route_list = NULL;
111 struct rt_entry *destination;
114 for(index=0;index<HASHSIZE;index++)
116 for(destination = from_table[index].next;
117 destination != &from_table[index];
118 destination = destination->next)
120 if (!olsr_find_up_route(destination, in_table))
123 route_list = olsr_malloc(sizeof(struct destination_n), "create route tmp list");
125 route_list->destination = destination;
127 route_list->next = kernel_route_list;
128 kernel_route_list = route_list;
133 return (kernel_route_list);
141 *Deletes all OLSR routes
147 olsr_delete_all_kernel_routes()
149 struct destination_n *delete_kernel_list=NULL;
150 struct destination_n *tmp=NULL;
151 union olsr_ip_addr *tmp_addr;
153 olsr_printf(1, "Deleting all routes...\n");
155 delete_kernel_list = olsr_build_update_list(hna_routes, old_hna);
157 tmp = delete_kernel_list;
159 olsr_printf(1, "HNA list:\n");
162 tmp_addr = &tmp->destination->rt_dst;
163 olsr_printf(1, "Dest: %s\n", olsr_ip_to_string(tmp_addr));
167 olsr_delete_routes_from_kernel(delete_kernel_list);
169 delete_kernel_list = olsr_build_update_list(routingtable,old_routes);
171 tmp = delete_kernel_list;
173 olsr_printf(1, "Route list:\n");
176 tmp_addr = &tmp->destination->rt_dst;
177 olsr_printf(1, "Dest: %s\n", olsr_ip_to_string(tmp_addr));
181 olsr_delete_routes_from_kernel(delete_kernel_list);
188 *Perform all neccessary actions for an update of the
189 *routes in the kernel.
194 olsr_update_kernel_routes()
196 struct destination_n *delete_kernel_list = NULL;
197 struct destination_n *add_kernel_list = NULL;
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);
210 *Perform all neccessary actions for an update of the
211 *HNA routes in the kernel.
216 olsr_update_kernel_hna_routes()
218 struct destination_n *delete_kernel_list = NULL;
219 //struct destination_n *delete_kernel_list2;
220 struct destination_n *add_kernel_list = NULL;
222 olsr_printf(3, "Updating kernel HNA routes...\n");
225 delete_kernel_list = olsr_build_update_list(old_hna, hna_routes);
226 add_kernel_list = olsr_build_update_list(hna_routes, old_hna);
228 olsr_delete_routes_from_kernel(delete_kernel_list);
229 olsr_add_routes_in_kernel(add_kernel_list);
234 *Create a copy of the routing table and
235 *clear the current table
237 *@param original the table to move from
238 *@param the table to move to
243 olsr_move_route_table(struct rt_entry *original, struct rt_entry *new)
247 for(index=0;index<HASHSIZE;index++)
249 if(original[index].next == &original[index])
251 new[index].next = &new[index];
252 new[index].prev = &new[index];
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];
263 original[index].next = &original[index];
264 original[index].prev = &original[index];
271 *Delete a linked list of routes from the kernel.
273 *@param delete_kernel_list the list to delete
278 olsr_delete_routes_from_kernel(struct destination_n *delete_kernel_list)
280 struct destination_n *destination_kernel;
283 while(delete_kernel_list!=NULL)
285 if(olsr_cnf->ip_version == AF_INET)
288 error = olsr_ioctl_del_route(delete_kernel_list->destination);
293 error = olsr_ioctl_del_route6(delete_kernel_list->destination);
299 olsr_printf(1, "Delete route:%s\n", strerror(errno));
300 olsr_syslog(OLSR_LOG_ERR, "Delete route:%m");
303 destination_kernel=delete_kernel_list;
304 delete_kernel_list=delete_kernel_list->next;
306 free(destination_kernel);
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.
318 *@param add_kernel_list the linked list of routes to add
323 olsr_add_routes_in_kernel(struct destination_n *add_kernel_list)
325 struct destination_n *destination_kernel = NULL;
326 struct destination_n *previous_node = add_kernel_list;
328 int metric_counter = 0, first_run = 1;
331 //printf("Calculating routes\n");
333 while(add_kernel_list != NULL)
335 //searching for all the items with metric equal to n
336 for(destination_kernel = add_kernel_list; destination_kernel != NULL; )
338 if((destination_kernel->destination->rt_metric == metric_counter) &&
340 COMP_IP(&destination_kernel->destination->rt_dst, &destination_kernel->destination->rt_router)) || !first_run))
342 /* First add all 1-hop routes that has themselves as GW */
344 if(olsr_cnf->ip_version == AF_INET)
345 error=olsr_ioctl_add_route(destination_kernel->destination);
347 error=olsr_ioctl_add_route6(destination_kernel->destination);
349 if(error < 0) //print the error msg
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");
355 //getting rid of this node and hooking up the broken point
356 if(destination_kernel == add_kernel_list)
358 destination_kernel = add_kernel_list->next;
359 free(add_kernel_list);
360 add_kernel_list = destination_kernel;
361 previous_node=add_kernel_list;
365 previous_node->next = destination_kernel->next;
366 free(destination_kernel);
367 destination_kernel = previous_node->next;
372 previous_node = destination_kernel;
373 destination_kernel = destination_kernel->next;