2 * The olsr.org Optimized Link-State Routing daemon(olsrd)
3 * Copyright (c) 2004, Andreas Tønnesen(andreto@olsr.org)
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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
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.
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.
33 * Visit http://www.olsr.org for more information.
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.
39 * $Id: neighbor_table.c,v 1.19 2004/11/21 13:45:50 kattemat Exp $
45 #include "two_hop_neighbor_table.h"
49 #include "scheduler.h"
51 #include "mpr_selector_set.h"
54 olsr_init_neighbor_table()
58 olsr_register_timeout_function(&olsr_time_out_neighborhood_tables);
60 for(i = 0; i < HASHSIZE; i++)
62 neighbortable[i].next = &neighbortable[i];
63 neighbortable[i].prev = &neighbortable[i];
69 *Delete a two hop neighbor from a neighbors two
72 *@param neighbor the neighbor to delete the two hop
74 *@param address the IP address of the two hop neighbor
77 *@return positive if entry deleted
80 olsr_delete_neighbor_2_pointer(struct neighbor_entry *neighbor, union olsr_ip_addr *address)
83 struct neighbor_2_list_entry *entry;
85 entry = neighbor->neighbor_2_list.next;
87 while(entry != &neighbor->neighbor_2_list)
90 if(COMP_IP(&entry->neighbor_2->neighbor_2_addr, address))
105 *Check if a two hop neighbor is reachable via a given
108 *@param neighbor neighbor-entry to check via
109 *@param neighbor_main_address the addres of the two hop neighbor
112 *@return a pointer to the neighbor_2_list_entry struct
113 *representing the two hop neighbor if found. NULL if not found.
115 struct neighbor_2_list_entry *
116 olsr_lookup_my_neighbors(struct neighbor_entry *neighbor, union olsr_ip_addr *neighbor_main_address)
119 struct neighbor_2_list_entry *entry;
121 for(entry = neighbor->neighbor_2_list.next;
122 entry != &neighbor->neighbor_2_list;
126 if(COMP_IP(&entry->neighbor_2->neighbor_2_addr, neighbor_main_address))
136 *Delete a neighbr table entry.
138 *Remember: Deleting a neighbor entry results
139 *the deletion of its 2 hop neighbors list!!!
140 *@param neighbor the neighbor entry to delete
146 olsr_delete_neighbor_table(union olsr_ip_addr *neighbor_addr)
148 struct neighbor_2_list_entry *two_hop_list, *two_hop_to_delete;
149 struct neighbor_2_entry *two_hop_entry;
151 struct neighbor_entry *entry;
153 //printf("inserting neighbor\n");
155 hash = olsr_hashing(neighbor_addr);
157 entry = neighbortable[hash].next;
160 * Find neighbor entry
162 while(entry != &neighbortable[hash])
164 if(COMP_IP(&entry->neighbor_main_addr, neighbor_addr))
170 if(entry == &neighbortable[hash])
174 two_hop_list = entry->neighbor_2_list.next;
176 while(two_hop_list != &entry->neighbor_2_list)
178 two_hop_entry = two_hop_list->neighbor_2;
180 two_hop_entry->neighbor_2_pointer--;
182 olsr_delete_neighbor_pointer(two_hop_entry, &entry->neighbor_main_addr);
184 /* Delete entry if it has no more one hop neighbors pointing to it */
185 if(two_hop_entry->neighbor_2_pointer < 1)
187 DEQUEUE_ELEM(two_hop_entry);
193 two_hop_to_delete = two_hop_list;
194 two_hop_list = two_hop_list->next;
196 free(two_hop_to_delete);
206 changes_neighborhood = OLSR_TRUE;
214 *Insert a neighbor entry in the neighbor table
216 *@param main_addr the main address of the new node
218 *@return 0 if neighbor already exists 1 if inserted
220 struct neighbor_entry *
221 olsr_insert_neighbor_table(union olsr_ip_addr *main_addr)
224 struct neighbor_entry *new_neigh;
226 hash = olsr_hashing(main_addr);
228 /* Check if entry exists */
230 for(new_neigh = neighbortable[hash].next;
231 new_neigh != &neighbortable[hash];
232 new_neigh = new_neigh->next)
234 if(COMP_IP(&new_neigh->neighbor_main_addr, main_addr))
238 //printf("inserting neighbor\n");
240 new_neigh = olsr_malloc(sizeof(struct neighbor_entry), "New neighbor entry");
242 /* Set address, willingness and status */
243 COPY_IP(&new_neigh->neighbor_main_addr, main_addr);
244 new_neigh->willingness = WILL_NEVER;
245 new_neigh->status = NOT_SYM;
247 new_neigh->neighbor_2_list.next = &new_neigh->neighbor_2_list;
248 new_neigh->neighbor_2_list.prev = &new_neigh->neighbor_2_list;
250 new_neigh->linkcount = 0;
251 new_neigh->is_mpr = OLSR_FALSE;
252 new_neigh->was_mpr = OLSR_FALSE;
255 QUEUE_ELEM(neighbortable[hash], new_neigh);
263 *Lookup a neighbor entry in the neighbortable based on an address.
265 *@param dst the IP address of the neighbor to look up
267 *@return a pointer to the neighbor struct registered on the given
268 *address. NULL if not found.
270 struct neighbor_entry *
271 olsr_lookup_neighbor_table(union olsr_ip_addr *dst)
273 struct neighbor_entry *entry;
275 //struct addresses *adr;
276 union olsr_ip_addr *tmp_ip;
279 *Find main address of node
281 if((tmp_ip = mid_lookup_main_addr(dst)) != NULL)
284 hash = olsr_hashing(dst);
287 //printf("\nLookup %s\n", olsr_ip_to_string(dst));
288 for(entry = neighbortable[hash].next;
289 entry != &neighbortable[hash];
292 //printf("Checking %s\n", olsr_ip_to_string(&neighbor_table_tmp->neighbor_main_addr));
293 if(COMP_IP(&entry->neighbor_main_addr, dst))
297 //printf("NOPE\n\n");
305 *Lookup a neighbor entry in the neighbortable based on an address.
307 *@param dst the IP address of the neighbor to look up
309 *@return a pointer to the neighbor struct registered on the given
310 *address. NULL if not found.
312 struct neighbor_entry *
313 olsr_lookup_neighbor_table_alias(union olsr_ip_addr *dst)
315 struct neighbor_entry *entry;
317 //struct addresses *adr;
319 hash = olsr_hashing(dst);
322 //printf("\nLookup %s\n", olsr_ip_to_string(dst));
323 for(entry = neighbortable[hash].next;
324 entry != &neighbortable[hash];
327 //printf("Checking %s\n", olsr_ip_to_string(&neighbor_table_tmp->neighbor_main_addr));
328 if(COMP_IP(&entry->neighbor_main_addr, dst))
332 //printf("NOPE\n\n");
341 update_neighbor_status(struct neighbor_entry *entry, int link)
343 struct neighbor_2_entry *two_hop_neighbor;
346 * Update neighbor entry
351 /* N_status is set to SYM */
352 if(entry->status == NOT_SYM)
355 /* Delete posible 2 hop entry on this neighbor */
356 if((two_hop_neighbor = olsr_lookup_two_hop_neighbor_table(&entry->neighbor_main_addr))!=NULL)
358 olsr_delete_two_hop_neighbor_table(two_hop_neighbor);
361 changes_neighborhood = OLSR_TRUE;
362 changes_topology = OLSR_TRUE;
363 if(olsr_cnf->tc_redundancy > 1)
370 if(entry->status == SYM)
372 changes_neighborhood = OLSR_TRUE;
373 changes_topology = OLSR_TRUE;
374 if(olsr_cnf->tc_redundancy > 1)
377 /* else N_status is set to NOT_SYM */
378 entry->status = NOT_SYM;
379 /* remove neighbor from routing list */
382 return entry->status;
388 *Times out the entries in the two hop neighbor table and
389 *deletes those who have exceeded their time to live since
396 olsr_time_out_two_hop_neighbors(struct neighbor_entry *neighbor)
398 struct neighbor_2_list_entry *two_hop_list, *two_hop_to_delete;
399 struct neighbor_2_entry *two_hop_entry;
402 two_hop_list = neighbor->neighbor_2_list.next;
404 //neighbor->neighbor_2_list = NULL;
406 while(two_hop_list != &neighbor->neighbor_2_list)
408 if(TIMED_OUT(&two_hop_list->neighbor_2_timer))
410 two_hop_entry = two_hop_list->neighbor_2;
411 two_hop_entry->neighbor_2_pointer--;
412 olsr_delete_neighbor_pointer(two_hop_entry, &neighbor->neighbor_main_addr);
414 if(two_hop_entry->neighbor_2_pointer < 1)
416 /* FIX THIS (fix what?)*/
417 DEQUEUE_ELEM(two_hop_entry);
419 free((void *)two_hop_entry);
422 two_hop_to_delete = two_hop_list;
423 two_hop_list = two_hop_list->next;
426 DEQUEUE_ELEM(two_hop_to_delete);
428 free(two_hop_to_delete);
430 /* This flag is set to OLSR_TRUE to recalculate the MPR set and the routing table*/
431 changes_neighborhood = OLSR_TRUE;
432 changes_topology = OLSR_TRUE;
436 two_hop_list = two_hop_list->next;
446 olsr_time_out_neighborhood_tables()
449 struct neighbor_entry *entry;
451 for(index=0;index<HASHSIZE;index++)
453 entry = neighbortable[index].next;
455 while(entry != &neighbortable[index])
457 olsr_time_out_two_hop_neighbors(entry);
469 *Prints the registered neighbors and two hop neighbors
475 olsr_print_neighbor_table()
478 struct neighbor_entry *neigh;
479 #if defined USE_LINK_QUALITY
480 struct link_entry *link;
482 double best_lq, inv_best_lq;
485 olsr_printf(1, "\n--- %02d:%02d:%02d.%02d ------------------------------------------------ NEIGHBORS\n\n",
491 if (olsr_cnf->ip_version == AF_INET)
493 olsr_printf(1, "IP address LQ NLQ SYM MPR MPRS will\n");
494 fstr = "%-15s %5.3f %5.3f %s %s %s %d\n";
499 olsr_printf(1, "IP address LQ NLQ SYM MPR MPRS will\n");
500 fstr = "%-39s %5.3f %5.3f %s %s %s %d\n";
503 for (i = 0; i < HASHSIZE; i++)
505 for(neigh = neighbortable[i].next; neigh != &neighbortable[i];
508 #if defined USE_LINK_QUALITY
509 link = olsr_neighbor_best_link(&neigh->neighbor_main_addr);
510 best_lq = link->neigh_link_quality;
512 link = olsr_neighbor_best_inverse_link(&neigh->neighbor_main_addr);
513 inv_best_lq = link->loss_link_quality;
519 olsr_printf(1, fstr, olsr_ip_to_string(&neigh->neighbor_main_addr),
520 inv_best_lq, best_lq,
521 (neigh->status == SYM) ? "YES " : "NO ",
522 neigh->is_mpr ? "YES " : "NO ",
523 olsr_lookup_mprs_set(&neigh->neighbor_main_addr) == NULL ? "NO " : "YES ",