2 * OLSR ad-hoc routing table management protocol
3 * Copyright (C) 2003 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: neighbor_table.c,v 1.10 2004/11/05 11:52:55 kattemat Exp $
30 #include "two_hop_neighbor_table.h"
34 #include "scheduler.h"
37 olsr_init_neighbor_table()
41 olsr_register_timeout_function(&olsr_time_out_neighborhood_tables);
43 for(i = 0; i < HASHSIZE; i++)
45 neighbortable[i].next = &neighbortable[i];
46 neighbortable[i].prev = &neighbortable[i];
52 *Delete a two hop neighbor from a neighbors two
55 *@param neighbor the neighbor to delete the two hop
57 *@param address the IP address of the two hop neighbor
60 *@return positive if entry deleted
63 olsr_delete_neighbor_2_pointer(struct neighbor_entry *neighbor, union olsr_ip_addr *address)
66 struct neighbor_2_list_entry *entry;
68 entry = neighbor->neighbor_2_list.next;
70 while(entry != &neighbor->neighbor_2_list)
73 if(COMP_IP(&entry->neighbor_2->neighbor_2_addr, address))
88 *Check if a two hop neighbor is reachable via a given
91 *@param neighbor neighbor-entry to check via
92 *@param neighbor_main_address the addres of the two hop neighbor
95 *@return a pointer to the neighbor_2_list_entry struct
96 *representing the two hop neighbor if found. NULL if not found.
98 struct neighbor_2_list_entry *
99 olsr_lookup_my_neighbors(struct neighbor_entry *neighbor, union olsr_ip_addr *neighbor_main_address)
102 struct neighbor_2_list_entry *entry;
104 for(entry = neighbor->neighbor_2_list.next;
105 entry != &neighbor->neighbor_2_list;
109 if(COMP_IP(&entry->neighbor_2->neighbor_2_addr, neighbor_main_address))
119 *Delete a neighbr table entry.
121 *Remember: Deleting a neighbor entry results
122 *the deletion of its 2 hop neighbors list!!!
123 *@param neighbor the neighbor entry to delete
129 olsr_delete_neighbor_table(union olsr_ip_addr *neighbor_addr)
131 struct neighbor_2_list_entry *two_hop_list, *two_hop_to_delete;
132 struct neighbor_2_entry *two_hop_entry;
134 struct neighbor_entry *entry;
136 //printf("inserting neighbor\n");
138 hash = olsr_hashing(neighbor_addr);
140 entry = neighbortable[hash].next;
143 * Find neighbor entry
145 while(entry != &neighbortable[hash])
147 if(COMP_IP(&entry->neighbor_main_addr, neighbor_addr))
153 if(entry == &neighbortable[hash])
157 two_hop_list = entry->neighbor_2_list.next;
159 while(two_hop_list != &entry->neighbor_2_list)
161 two_hop_entry = two_hop_list->neighbor_2;
163 two_hop_entry->neighbor_2_pointer--;
165 olsr_delete_neighbor_pointer(two_hop_entry, &entry->neighbor_main_addr);
167 /* Delete entry if it has no more one hop neighbors pointing to it */
168 if(two_hop_entry->neighbor_2_pointer < 1)
170 DEQUEUE_ELEM(two_hop_entry);
176 two_hop_to_delete = two_hop_list;
177 two_hop_list = two_hop_list->next;
179 free(two_hop_to_delete);
189 changes_neighborhood = OLSR_TRUE;
197 *Insert a neighbor entry in the neighbor table
199 *@param main_addr the main address of the new node
201 *@return 0 if neighbor already exists 1 if inserted
203 struct neighbor_entry *
204 olsr_insert_neighbor_table(union olsr_ip_addr *main_addr)
207 struct neighbor_entry *new_neigh;
209 hash = olsr_hashing(main_addr);
211 /* Check if entry exists */
213 for(new_neigh = neighbortable[hash].next;
214 new_neigh != &neighbortable[hash];
215 new_neigh = new_neigh->next)
217 if(COMP_IP(&new_neigh->neighbor_main_addr, main_addr))
221 //printf("inserting neighbor\n");
223 new_neigh = olsr_malloc(sizeof(struct neighbor_entry), "New neighbor entry");
225 /* Set address, willingness and status */
226 COPY_IP(&new_neigh->neighbor_main_addr, main_addr);
227 new_neigh->willingness = WILL_NEVER;
228 new_neigh->status = NOT_SYM;
230 new_neigh->neighbor_2_list.next = &new_neigh->neighbor_2_list;
231 new_neigh->neighbor_2_list.prev = &new_neigh->neighbor_2_list;
233 new_neigh->linkcount = 0;
234 new_neigh->is_mpr = OLSR_FALSE;
235 new_neigh->was_mpr = OLSR_FALSE;
238 QUEUE_ELEM(neighbortable[hash], new_neigh);
246 *Lookup a neighbor entry in the neighbortable based on an address.
248 *@param dst the IP address of the neighbor to look up
250 *@return a pointer to the neighbor struct registered on the given
251 *address. NULL if not found.
253 struct neighbor_entry *
254 olsr_lookup_neighbor_table(union olsr_ip_addr *dst)
256 struct neighbor_entry *entry;
258 //struct addresses *adr;
259 union olsr_ip_addr *tmp_ip;
262 *Find main address of node
264 if((tmp_ip = mid_lookup_main_addr(dst)) != NULL)
267 hash = olsr_hashing(dst);
270 //printf("\nLookup %s\n", olsr_ip_to_string(dst));
271 for(entry = neighbortable[hash].next;
272 entry != &neighbortable[hash];
275 //printf("Checking %s\n", olsr_ip_to_string(&neighbor_table_tmp->neighbor_main_addr));
276 if(COMP_IP(&entry->neighbor_main_addr, dst))
280 //printf("NOPE\n\n");
288 *Lookup a neighbor entry in the neighbortable based on an address.
290 *@param dst the IP address of the neighbor to look up
292 *@return a pointer to the neighbor struct registered on the given
293 *address. NULL if not found.
295 struct neighbor_entry *
296 olsr_lookup_neighbor_table_alias(union olsr_ip_addr *dst)
298 struct neighbor_entry *entry;
300 //struct addresses *adr;
302 hash = olsr_hashing(dst);
305 //printf("\nLookup %s\n", olsr_ip_to_string(dst));
306 for(entry = neighbortable[hash].next;
307 entry != &neighbortable[hash];
310 //printf("Checking %s\n", olsr_ip_to_string(&neighbor_table_tmp->neighbor_main_addr));
311 if(COMP_IP(&entry->neighbor_main_addr, dst))
315 //printf("NOPE\n\n");
324 update_neighbor_status(struct neighbor_entry *entry, int link)
326 struct neighbor_2_entry *two_hop_neighbor;
329 * Update neighbor entry
334 /* N_status is set to SYM */
335 if(entry->status == NOT_SYM)
338 /* Delete posible 2 hop entry on this neighbor */
339 if((two_hop_neighbor = olsr_lookup_two_hop_neighbor_table(&entry->neighbor_main_addr))!=NULL)
341 olsr_delete_two_hop_neighbor_table(two_hop_neighbor);
344 changes_neighborhood = OLSR_TRUE;
345 changes_topology = OLSR_TRUE;
346 if(olsr_cnf->tc_redundancy > 1)
353 if(entry->status == SYM)
355 changes_neighborhood = OLSR_TRUE;
356 changes_topology = OLSR_TRUE;
357 if(olsr_cnf->tc_redundancy > 1)
360 /* else N_status is set to NOT_SYM */
361 entry->status = NOT_SYM;
362 /* remove neighbor from routing list */
365 return entry->status;
371 *Times out the entries in the two hop neighbor table and
372 *deletes those who have exceeded their time to live since
379 olsr_time_out_two_hop_neighbors(struct neighbor_entry *neighbor)
381 struct neighbor_2_list_entry *two_hop_list, *two_hop_to_delete;
382 struct neighbor_2_entry *two_hop_entry;
385 two_hop_list = neighbor->neighbor_2_list.next;
387 //neighbor->neighbor_2_list = NULL;
389 while(two_hop_list != &neighbor->neighbor_2_list)
391 if(TIMED_OUT(&two_hop_list->neighbor_2_timer))
393 two_hop_entry = two_hop_list->neighbor_2;
394 two_hop_entry->neighbor_2_pointer--;
395 olsr_delete_neighbor_pointer(two_hop_entry, &neighbor->neighbor_main_addr);
397 if(two_hop_entry->neighbor_2_pointer < 1)
399 /* FIX THIS (fix what?)*/
400 DEQUEUE_ELEM(two_hop_entry);
402 free((void *)two_hop_entry);
405 two_hop_to_delete = two_hop_list;
406 two_hop_list = two_hop_list->next;
409 DEQUEUE_ELEM(two_hop_to_delete);
411 free(two_hop_to_delete);
413 /* This flag is set to OLSR_TRUE to recalculate the MPR set and the routing table*/
414 changes_neighborhood = OLSR_TRUE;
415 changes_topology = OLSR_TRUE;
419 two_hop_list = two_hop_list->next;
429 olsr_time_out_neighborhood_tables()
432 struct neighbor_entry *entry;
434 for(index=0;index<HASHSIZE;index++)
436 entry = neighbortable[index].next;
438 while(entry != &neighbortable[index])
440 olsr_time_out_two_hop_neighbors(entry);
452 *Prints the registered neighbors and two hop neighbors
458 olsr_print_neighbor_table()
461 struct neighbor_entry *neighbor_table_tmp;
462 struct neighbor_2_list_entry *list_2;
466 olsr_printf(1, "Neighbor list(%02d:%02d:%02d.%06lu):\n",
472 for(index=0;index<HASHSIZE;index++)
475 for(neighbor_table_tmp = neighbortable[index].next;
476 neighbor_table_tmp != &neighbortable[index];
477 neighbor_table_tmp = neighbor_table_tmp->next)
479 olsr_printf(1, "%s:l=%d:m=%d:w=%d[2hlist:",
480 olsr_ip_to_string(&neighbor_table_tmp->neighbor_main_addr),
481 neighbor_table_tmp->status, neighbor_table_tmp->is_mpr, neighbor_table_tmp->willingness);
483 for(list_2 = neighbor_table_tmp->neighbor_2_list.next;
484 list_2 != &neighbor_table_tmp->neighbor_2_list;
485 list_2 = list_2->next)
487 olsr_printf(1, "%s:", olsr_ip_to_string(&list_2->neighbor_2->neighbor_2_addr));
489 olsr_printf(1, "]\n");