/** * Update a HNA entry. If it does not exist it * is created. * This is the only function that should be called * from outside concerning creation of HNA entries. * *@param gw address of the gateway *@param net address of the network *@param prefixlen the prefix length *@param vtime the validitytime of the entry */ void olsr_update_hna_entry(const union olsr_ip_addr *gw, const union olsr_ip_addr *net, uint8_t prefixlen, olsr_reltime vtime) { struct hna_entry *gw_entry; struct hna_net *net_entry; gw_entry = olsr_lookup_hna_gw(gw); if (!gw_entry) { /* Need to add the entry */ gw_entry = olsr_add_hna_entry(gw); } net_entry = olsr_lookup_hna_net(&gw_entry->networks, net, prefixlen); if (net_entry == NULL) { /* Need to add the net */ net_entry = olsr_add_hna_net(gw_entry, net, prefixlen); changes_hna = true; } /* * Add the rt_path for the entry. */ olsr_insert_routing_table(&net_entry->hna_prefix.prefix, net_entry->hna_prefix.prefix_len, &gw_entry->A_gateway_addr, OLSR_RT_ORIGIN_HNA); /* * Start, or refresh the timer, whatever is appropriate. */ olsr_set_timer(&net_entry->hna_net_timer, vtime, OLSR_HNA_NET_JITTER, OLSR_TIMER_ONESHOT, &olsr_expire_hna_net_entry, net_entry, hna_net_timer_cookie); }
void olsr_init_duplicate_set(void) { avl_init(&duplicate_set, olsr_cnf->ip_version == AF_INET ? &avl_comp_ipv4 : &avl_comp_ipv6); olsr_set_timer(&duplicate_cleanup_timer, DUPLICATE_CLEANUP_INTERVAL, DUPLICATE_CLEANUP_JITTER, OLSR_TIMER_PERIODIC, &olsr_cleanup_duplicate_entry, NULL, 0); }
/** *Update the hello timeout of a hysteresis link *entry * *@param entry the link entry to update *@param htime the hello interval to use * *@return nada */ void olsr_update_hysteresis_hello(struct link_entry *entry, olsr_reltime htime) { struct ipaddr_str buf; OLSR_PRINTF(3, "HYST[%s]: HELLO update vtime %u ms\n", olsr_ip_to_string(&buf, &entry->neighbor_iface_addr), htime + htime / 2); olsr_set_timer(&entry->link_hello_timer, htime + htime / 2, OLSR_LINK_HELLO_JITTER, OLSR_TIMER_PERIODIC, &olsr_expire_link_hello_timer, entry, 0); return; }
/** *Processes an list of neighbors from an incoming HELLO message. *@param neighbor the neighbor who sent the message. *@param message the HELLO message *@return nada */ static void process_message_neighbors(struct neighbor_entry *neighbor, const struct hello_message *message) { struct hello_neighbor *message_neighbors; for (message_neighbors = message->neighbors; message_neighbors != NULL; message_neighbors = message_neighbors->next) { union olsr_ip_addr *neigh_addr; struct neighbor_2_entry *two_hop_neighbor; /* *check all interfaces *so that we don't add ourselves to the *2 hop list *IMPORTANT! */ if (if_ifwithaddr(&message_neighbors->address) != NULL) continue; /* Get the main address */ neigh_addr = mid_lookup_main_addr(&message_neighbors->address); if (neigh_addr != NULL) { message_neighbors->address = *neigh_addr; } if (((message_neighbors->status == SYM_NEIGH) || (message_neighbors->status == MPR_NEIGH))) { struct neighbor_2_list_entry *two_hop_neighbor_yet = olsr_lookup_my_neighbors(neighbor, &message_neighbors->address); if (two_hop_neighbor_yet != NULL) { /* Updating the holding time for this neighbor */ olsr_set_timer(&two_hop_neighbor_yet->nbr2_list_timer, message->vtime, OLSR_NBR2_LIST_JITTER, OLSR_TIMER_ONESHOT, &olsr_expire_nbr2_list, two_hop_neighbor_yet, 0); two_hop_neighbor = two_hop_neighbor_yet->neighbor_2; /* * For link quality OLSR, reset the path link quality here. * The path link quality will be calculated in the second pass, below. * Keep the saved_path_link_quality for reference. */ if (olsr_cnf->lq_level > 0) { /* * loop through the one-hop neighbors that see this * 'two_hop_neighbor' */ struct neighbor_list_entry *walker; for (walker = two_hop_neighbor->neighbor_2_nblist.next; walker != &two_hop_neighbor->neighbor_2_nblist; walker = walker->next) { /* * have we found the one-hop neighbor that sent the * HELLO message that we're current processing? */ if (walker->neighbor == neighbor) { walker->path_linkcost = LINK_COST_BROKEN; } } } } else { two_hop_neighbor = olsr_lookup_two_hop_neighbor_table(&message_neighbors->address); if (two_hop_neighbor == NULL) { changes_neighborhood = true; changes_topology = true; two_hop_neighbor = olsr_malloc(sizeof(struct neighbor_2_entry), "Process HELLO"); two_hop_neighbor->neighbor_2_nblist.next = &two_hop_neighbor->neighbor_2_nblist; two_hop_neighbor->neighbor_2_nblist.prev = &two_hop_neighbor->neighbor_2_nblist; two_hop_neighbor->neighbor_2_pointer = 0; two_hop_neighbor->neighbor_2_addr = message_neighbors->address; olsr_insert_two_hop_neighbor_table(two_hop_neighbor); linking_this_2_entries(neighbor, two_hop_neighbor, message->vtime); } else { /* linking to this two_hop_neighbor entry */ changes_neighborhood = true; changes_topology = true; linking_this_2_entries(neighbor, two_hop_neighbor, message->vtime); } } } } /* Separate, second pass for link quality OLSR */ /* Separate, second and third pass for link quality OLSR */ if (olsr_cnf->lq_level > 0) { olsr_linkcost first_hop_pathcost; struct link_entry *lnk = get_best_link_to_neighbor(&neighbor->neighbor_main_addr); if (!lnk) return; /* calculate first hop path quality */ first_hop_pathcost = lnk->linkcost; /* * Second pass for link quality OLSR: calculate the best 2-hop * path costs to all the 2-hop neighbors indicated in the * HELLO message. Since the same 2-hop neighbor may be listed * more than once in the same HELLO message (each at a possibly * different quality) we want to select only the best one, not just * the last one listed in the HELLO message. */ for (message_neighbors = message->neighbors; message_neighbors != NULL; message_neighbors = message_neighbors->next) { if (if_ifwithaddr(&message_neighbors->address) != NULL) continue; if (((message_neighbors->status == SYM_NEIGH) || (message_neighbors->status == MPR_NEIGH))) { struct neighbor_list_entry *walker; struct neighbor_2_entry *two_hop_neighbor; struct neighbor_2_list_entry *two_hop_neighbor_yet = olsr_lookup_my_neighbors(neighbor, &message_neighbors->address); if (!two_hop_neighbor_yet) continue; two_hop_neighbor = two_hop_neighbor_yet->neighbor_2; /* * loop through the one-hop neighbors that see this * 'two_hop_neighbor' */ for (walker = two_hop_neighbor->neighbor_2_nblist.next; walker != &two_hop_neighbor->neighbor_2_nblist; walker = walker->next) { /* * have we found the one-hop neighbor that sent the * HELLO message that we're current processing? */ if (walker->neighbor == neighbor) { olsr_linkcost new_second_hop_linkcost, new_path_linkcost; // the link cost between the 1-hop neighbour and the // 2-hop neighbour new_second_hop_linkcost = message_neighbors->cost; // the total cost for the route // "us --- 1-hop --- 2-hop" new_path_linkcost = first_hop_pathcost + new_second_hop_linkcost; // Only copy the link quality if it is better than what we have // for this 2-hop neighbor if (new_path_linkcost < walker->path_linkcost) { walker->second_hop_linkcost = new_second_hop_linkcost; walker->path_linkcost = new_path_linkcost; walker->saved_path_linkcost = new_path_linkcost; changes_neighborhood = true; changes_topology = true; } } } } } } }
/** * Set the mpr selector expiration timer. * * all timer setting shall be done using this function. * The timer param is a relative timer expressed in milliseconds. */ static void olsr_set_mpr_sel_timer(struct mpr_selector *mpr_sel, olsr_reltime rel_timer) { olsr_set_timer(&mpr_sel->MS_timer, rel_timer, OLSR_MPR_SEL_JITTER, OLSR_TIMER_ONESHOT, &olsr_expire_mpr_sel_entry, mpr_sel, 0); }