olsr_bool search_mpr_set_handler(void *olsr, void *arg_a, void *arg_b) { OLSR_MPR_TUPLE *data = NULL, *search = NULL; data = (OLSR_MPR_TUPLE *)arg_a; search = (OLSR_MPR_TUPLE *)arg_b; return (olsr_bool)(equal_ip_addr((struct olsrv2 *)olsr, &data->MPR_if_addr, &search->MPR_if_addr) && equal_ip_addr((struct olsrv2 *)olsr, &data->local_iface_addr, &search->local_iface_addr)); }
olsr_bool search_topology_set_handler(void* olsr, void *arg_a, void *arg_b) { OLSR_TOPOLOGY_TUPLE *data = NULL, *param = NULL; data = (OLSR_TOPOLOGY_TUPLE *)arg_a; param = (OLSR_TOPOLOGY_TUPLE *)arg_b; return (olsr_bool)(equal_ip_addr((struct olsrv2* )olsr, &data->T_dest_iface_addr, ¶m->T_dest_iface_addr) && equal_ip_addr((struct olsrv2* )olsr, &data->T_last_iface_addr, ¶m->T_last_iface_addr)); }
//yowada olsr_bool match_local_iface_addr(void *olsr, olsr_ip_addr *neigh_addr) { struct olsrv2* olsr1 = (struct olsrv2* ) olsr; union olsr_ip_addr *local_addr = NULL; int ifnum,i; ifnum = ((struct olsrv2 *)olsr)->iface_num; for (i=0; i < ifnum; i++){ local_addr = &((struct olsrv2 *)olsr)->iface_addr[i]; if (DEBUG_OLSRV2) { if (olsr1->olsr_cnf->ip_version == AF_INET) { char str1[INET_ADDRSTRLEN], str2[INET_ADDRSTRLEN]; ConvertIpv4AddressToString(local_addr->v4, str1); ConvertIpv4AddressToString(neigh_addr->v4, str2); olsr_printf("Local addr %s,\tNeigh addr %s\n",str1, str2); } else if (olsr1->olsr_cnf->ip_version == AF_INET6) { char str1[INET6_ADDRSTRLEN], str2[INET6_ADDRSTRLEN]; ConvertIpv6AddressToString(&local_addr->v6, str1, OLSR_FALSE); ConvertIpv6AddressToString(&neigh_addr->v6, str2, OLSR_FALSE); olsr_printf("Local addr %s,\tNeigh addr %s\n",str1, str2); } } if (equal_ip_addr((struct olsrv2 *)olsr, neigh_addr ,local_addr) == OLSR_TRUE) return OLSR_TRUE; } return OLSR_FALSE; }
//WIN FIX: changed type from void* to char* olsr_bool search_proc_set_handler(void *olsr, void *arg_a, void *arg_vb) { OLSR_PROC_TUPLE *data = NULL; union olsr_ip_addr *orig_addr = NULL; olsr_u16_t *seq_number = NULL; olsr_u8_t *type = NULL; //WIN FIX: changed type from void* to char* char *arg_b = (char *)arg_vb; data = (OLSR_PROC_TUPLE *)arg_a; orig_addr = (union olsr_ip_addr *)arg_b; arg_b += sizeof(union olsr_ip_addr); seq_number = (olsr_u16_t *)arg_b; arg_b += sizeof(olsr_u16_t); type = (olsr_u8_t *)arg_b; arg_b -= sizeof(olsr_u16_t); arg_b -= sizeof(union olsr_ip_addr); //WIN FIX: explicit typecast required return (olsr_bool)(equal_ip_addr((struct olsrv2* )olsr, &data->P_addr, orig_addr) && data->P_seq_number == *seq_number && data->P_type == *type); }
olsr_bool search_routing_set_for_next_and_dest_handler(void* olsr, void *arg_a, void *arg_b) { OLSR_ROUTING_TUPLE *data = NULL, *param = NULL; data = (OLSR_ROUTING_TUPLE *)arg_a; param = (OLSR_ROUTING_TUPLE *)arg_b; return (olsr_bool)(equal_ip_addr((struct olsrv2* )olsr, &data->R_dest_iface_addr, ¶m->R_dest_iface_addr) && equal_ip_addr((struct olsrv2* )olsr, &data->R_next_iface_addr, ¶m->R_next_iface_addr)); }
olsr_bool search_mprN2_handler(void *olsr, void *arg_a, void *arg_b) { OLSR_MPR_N2_TUPLE *data = NULL; union olsr_ip_addr *search = NULL; data = (OLSR_MPR_N2_TUPLE *)arg_a; search = (union olsr_ip_addr *)arg_b; return (olsr_bool)equal_ip_addr((struct olsrv2 *)olsr, &data->addr, search); }
olsr_bool delete_relay_set_handler(void *olsr, void *arg_a, void *arg_b) { OLSR_RELAY_TUPLE *data = NULL; union olsr_ip_addr *neighbor_iface_addr; data = (OLSR_RELAY_TUPLE *)arg_a; neighbor_iface_addr = (union olsr_ip_addr *)arg_b; return (olsr_bool)(equal_ip_addr((struct olsrv2 *)olsr, &data->RS_if_addr, neighbor_iface_addr)); }
olsr_bool delete_mprN2_handler(void *olsr, void *arg_a, void *arg_b) { OLSR_MPR_N2_TUPLE *data = NULL; union olsr_ip_addr *todelete = NULL; data = (OLSR_MPR_N2_TUPLE *)arg_a; todelete = (union olsr_ip_addr *)arg_b; return (olsr_bool)equal_ip_addr((struct olsrv2 *)olsr, &data->addr, todelete); }
void insert_routing_set(struct olsrv2 *olsr, union olsr_ip_addr *dest_iface_addr, const union olsr_ip_addr *next_iface_addr, olsr_u8_t prefix_length, olsr_u16_t dist, const union olsr_ip_addr *iface_addr) { OLSR_ROUTING_TUPLE data; //Multi path check if (OLSR_TRUE) { if (search_routing_set_for_dest_exist(olsr, dest_iface_addr) == OLSR_TRUE ||//yowada add match_local_iface_addr(olsr, dest_iface_addr) == OLSR_TRUE) { if (DEBUG_OLSRV2) { char* paddr = olsr_niigata_ip_to_string(olsr, dest_iface_addr); olsr_printf("Route %s has already exist! hopcount = %d\n",paddr,dist); free(paddr); } return; //olsr_error("Multi path!!\n"); } } //Fix for Solaris //data.R_dest_iface_addr = *dest_iface_addr; //data.R_next_iface_addr = *next_iface_addr; olsr_ip_copy(olsr, &data.R_dest_iface_addr, dest_iface_addr); olsr_ip_copy(olsr, &data.R_next_iface_addr, next_iface_addr); data.R_prefix_length = prefix_length; data.R_dist = dist; //data.R_iface_addr = *iface_addr; olsr_ip_copy(olsr, &data.R_iface_addr, iface_addr); /* assert(equal_ip_addr(olsr_cnf->ip_version, data.R_dest_iface_addr, data.R_iface_addr) == OLSR_FALSE); */ if (equal_ip_addr(olsr, &data.R_dest_iface_addr, &data.R_iface_addr)) { return; } OLSR_InsertList(&olsr->routing_set[olsr_hashing(olsr,&data.R_dest_iface_addr)].list, &data, sizeof(OLSR_ROUTING_TUPLE)); /* OLSR_InsertList_Sort(&olsr->routing_set, */ /* &data, */ /* sizeof(OLSR_ROUTING_TUPLE), */ /* sort_routing_set_handler); */ }
olsr_bool delete_association_set_for_addr_handler(void* olsr, void *arg_a, void *arg_b){ olsr_ip_addr *data = NULL, *param = NULL; data = (olsr_ip_addr *)arg_a; param = (olsr_ip_addr *)arg_b; return (olsr_bool)equal_ip_addr((struct olsrv2* )olsr, data, param); }
olsr_bool search_association_set_for_addr_handler(void* olsr, void *arg_a, void *arg_b){ OLSR_ASSOCIATION_TUPLE *data = NULL, *param = NULL; data = (OLSR_ASSOCIATION_TUPLE *)arg_a; param = (OLSR_ASSOCIATION_TUPLE *)arg_b; return (olsr_bool)equal_ip_addr((struct olsrv2* )olsr, &data->NA_iface_addr, ¶m->NA_iface_addr); }
olsr_bool lookup_topology_set_handler(void* olsr, void *arg_a,void *arg_b) { OLSR_TOPOLOGY_TUPLE *data = NULL; union olsr_ip_addr *T_last_addr = NULL; data = (OLSR_TOPOLOGY_TUPLE *)arg_a; T_last_addr = (union olsr_ip_addr *)arg_b; return (olsr_bool)(equal_ip_addr((struct olsrv2* )olsr, &data->T_last_iface_addr, T_last_addr)); }
olsr_bool search_routing_set_for_dest_handler(void *olsr, void *arg_a, void *arg_b) { OLSR_ROUTING_TUPLE *data = NULL; union olsr_ip_addr *addr = NULL; data = (OLSR_ROUTING_TUPLE *)arg_a; addr = (union olsr_ip_addr *)arg_b; return (olsr_bool)equal_ip_addr((struct olsrv2* )olsr, &data->R_dest_iface_addr, addr); }
olsr_bool delete_topology_set_for_same_entry_handler(void* olsr, void *arg_a, void *arg_b) { OLSR_TOPOLOGY_TUPLE *data = NULL, *param = NULL; data = (OLSR_TOPOLOGY_TUPLE *)arg_a; param = (OLSR_TOPOLOGY_TUPLE *)arg_b; return (olsr_bool)(equal_ip_addr((struct olsrv2* )olsr, &data->T_last_iface_addr, ¶m->T_last_iface_addr) && data->T_seq < param->T_seq); }
void proc_routing_set(struct olsrv2 *olsr) { OLSR_LIST_ENTRY *tmp_A = NULL, *tmp_B = NULL; OLSR_LINK_TUPLE *link_data = NULL, *link_data_2hop = NULL; OLSR_2NEIGH_TUPLE *two_nei_data = NULL; //OLSR_ASSOCI_TUPLE *associ_data; OLSR_ASSOCIATION_TUPLE *associ_data = NULL, *list_data = NULL; OLSR_TOPOLOGY_TUPLE *topology_data = NULL; OLSR_ROUTING_TUPLE *routing_data = NULL; olsr_u8_t default_prefix; olsr_u32_t index; int i; OLSR_LIST *retList = NULL, *link_retList = NULL; olsr_time_t time; int hash_index; int h; olsr_bool insert;; get_current_time(olsr, &time); // block signals until routing calcuration is finished if (olsr->olsr_cnf->ip_version == AF_INET) { default_prefix = 32; }else { default_prefix = 128; } //14 //14.1 for (hash_index = 0; hash_index < HASHSIZE; hash_index++) { delete_routing_set_for_all_entry(olsr, &olsr->routing_set[hash_index].list); } //14.2 tmp_A = olsr->link_set.head; while (tmp_A) { link_data = (OLSR_LINK_TUPLE *)tmp_A->data; if (get_link_status(time, link_data->L_SYM_time, link_data->L_ASYM_time, link_data->L_LOST_LINK_time) == SYMMETRIC) { if (DEBUG_OLSRV2) { olsr_printf("------call insert_routing_set---------\n"); } insert_routing_set(olsr, &link_data->L_neighbor_iface_addr, &link_data->L_neighbor_iface_addr, default_prefix, 1, &link_data->L_local_iface_addr); } tmp_A = tmp_A->next; } //14.3 (XXX) // for each neighbor address association tuple, for which two // addresses A1 and A2 exist in I_neighbor_iface_addr_list where: for (index=0; index < HASHSIZE; index++) { union olsr_ip_addr A_addr, B_addr; tmp_A = olsr->associ_set[index].list.head; while (tmp_A) { associ_data = (OLSR_ASSOCIATION_TUPLE *)tmp_A->data; olsr_ip_copy(olsr, &A_addr, &associ_data->NA_iface_addr); for (i = 0; i < associ_data->num_NAlist; i++) { tmp_B = associ_data->NA_list[i]; list_data = (OLSR_ASSOCIATION_TUPLE *)tmp_B->data; olsr_ip_copy(olsr, &B_addr, &list_data->NA_iface_addr); if (!equal_ip_addr(olsr, &A_addr, &B_addr)) { retList = search_routing_set_for_dest(olsr, &A_addr); if (retList != NULL) { routing_data = (OLSR_ROUTING_TUPLE *)retList->head->data; OLSR_DeleteList_Search(retList); insert_routing_set(olsr, &B_addr, &routing_data->R_next_iface_addr, default_prefix, routing_data->R_dist, &routing_data->R_iface_addr); assert(routing_data->R_dist == 1); } } } tmp_A = tmp_A->next; } } for (hash_index = 0; hash_index < HASHSIZE; hash_index++) { tmp_A = olsr->routing_set[hash_index].list.head; while (tmp_A) { routing_data = (OLSR_ROUTING_TUPLE *)tmp_A->data; retList = search_2neigh_set_for_mpr_n(olsr, &routing_data->R_iface_addr, &routing_data->R_next_iface_addr); if (retList) { tmp_B = retList->head; while (tmp_B) { two_nei_data = (OLSR_2NEIGH_TUPLE *)tmp_B->data; link_retList = search_link_set(olsr, &two_nei_data->N2_2hop_iface_addr); if (link_retList) { link_data_2hop = (OLSR_LINK_TUPLE *)link_retList->head->data; OLSR_DeleteList_Search(link_retList); if (get_link_status( time, link_data_2hop->L_SYM_time, link_data_2hop->L_ASYM_time, link_data_2hop->L_LOST_LINK_time) == SYMMETRIC) { tmp_B = tmp_B->next; continue; } } insert_routing_set(olsr, &two_nei_data->N2_2hop_iface_addr, &routing_data->R_next_iface_addr, default_prefix, 2, &routing_data->R_iface_addr); tmp_B = tmp_B->next; } OLSR_DeleteList_Search(retList); } tmp_A = tmp_A->next; } } //14.5 //14.5.1 h = 2; insert = OLSR_TRUE; while (insert == OLSR_TRUE) { insert = OLSR_FALSE; for (hash_index = 0; hash_index < HASHSIZE; hash_index++) { tmp_A = olsr->routing_set[hash_index].list.head; while (tmp_A) { routing_data = (OLSR_ROUTING_TUPLE *)tmp_A->data; tmp_A = tmp_A->next; if (routing_data->R_dist != h) { continue; } retList = search_topology_set_for_last(olsr, &routing_data->R_dest_iface_addr); if (retList) { tmp_B = retList->head; while (tmp_B) { topology_data = (OLSR_TOPOLOGY_TUPLE *)tmp_B->data; if (search_routing_set_for_dest_exist( olsr, &topology_data->T_dest_iface_addr) == OLSR_FALSE) { insert_routing_set(olsr, &topology_data->T_dest_iface_addr, &routing_data->R_next_iface_addr, default_prefix, routing_data->R_dist+1, &routing_data->R_iface_addr); insert = OLSR_TRUE; } tmp_B = tmp_B->next; } OLSR_DeleteList_Search(retList); } }//while }//for h++; } //14.5.2 }
static olsr_bool process_hello(struct olsrv2 *olsr, struct hello_message *hello, union olsr_ip_addr *in_if, union olsr_ip_addr *from_addr) { struct hello_neighbor *hello_neigh = NULL; OLSR_LIST* retList = NULL; OLSR_LIST_ENTRY *entry = NULL; OLSR_LOCAL_INTERFACE_BLOCK_ENTRY *local_entry = NULL; OLSR_SYMMETRIC_NEIGHBOR_TUPLE *sym_data = NULL; olsr_time_t time; olsr_bool change_assn = OLSR_FALSE, selected_mpr = OLSR_FALSE; //codexxx // before processing hello message add the queue length of the corresponding originator to the OLSR_LIST "queue_set" olsr_bool IPfound = OLSR_FALSE; struct queue_info *queueInf = NULL, *tempo= NULL ; OLSR_LIST_ENTRY *queueEntry = NULL; queueInf = (queue_info *)olsr_malloc(sizeof(queue_info), __FUNCTION__); queueInf->orig_IP = hello->orig_addr ; queueInf->Qlength = hello->queuelength; if(olsr->queue_set.numEntry == 0) { // insert to the list directly OLSR_InsertList(&olsr->queue_set,queueInf,sizeof(queue_info)); }else{ // liste deja contient des element ...donc trouver si deja existe queueEntry = olsr->queue_set.head ; while(queueEntry != NULL) ///// { tempo = (queue_info *)queueEntry->data ; if(!cmp_ip_addr(olsr,&tempo->orig_IP,&queueInf->orig_IP)) //// { // on a trouver cet originator IP ds la liste alors update le queue et sortir de la boucle tempo->Qlength = queueInf->Qlength; IPfound = OLSR_TRUE; break; } queueEntry = queueEntry->next ; } if(IPfound == OLSR_FALSE) { // cet IP n'existe pas deja dans la liste => l'introduire OLSR_InsertList(&olsr->queue_set,queueInf,sizeof(queue_info)); } } //end codexxx if (own_ip_addr(olsr, &hello->source_addr)) { // wiss: ma3neta el source address byetaba2 ma3 wa7ed men el intrface address taba3 node if(DEBUG_OLSRV2){ char* paddr = olsr_niigata_ip_to_string(olsr, &olsr->main_addr); olsr_printf("Received Hello, but this Hello is sent from ME!!\n[%s]",paddr); free(paddr); } return OLSR_FALSE; // wiss: betla3 men process_hello } if(search_link_set_local_for_exist(olsr, in_if, &hello->source_addr) == OLSR_FALSE){ // wiss:ma la2a bel olsr linkset entry 3enda local_if= "in_if" w neigbor_if=&hello->source_addr // wiss: ma la2a jar 3endou ip hello->source_addr ma3neta el link da3 proc_link_set(olsr, in_if, &hello->source_addr, LOST, hello->willingness, hello->vtime, hello->htime); } // neighbor address hello_neigh = hello->neighbors; while (hello_neigh){ if(equal_ip_addr(olsr, &hello_neigh->address, in_if )) { // wiss: hello_neigh->address, byetaba2 ma3 in_if proc_link_set(olsr, in_if, &hello->source_addr, hello_neigh->status, hello->willingness, hello->vtime, hello->htime); //update symmetric neighbor set proc_symmetric_neighbor_set(olsr, in_if, hello_neigh->status, hello); break; // wiss : so iza fet hon ya3ni la2a el neighbor so break... so iza ma la2an byente2el 3al neigh->next } hello_neigh = hello_neigh->next; } //update neighbor address association set proc_association_set(olsr, &hello->local_iface_list, hello->vtime); hello_neigh = hello->neighbors; while (hello_neigh){ //process 2hop Neighbor set proc_2neigh_set(olsr, in_if, &hello->source_addr, &hello_neigh->address, hello_neigh->status, hello_neigh->other_neigh, hello->vtime); //check: own interfaces is selected MPR by source nodes. if(selected_mpr == OLSR_FALSE && own_ip_addr(olsr, &hello_neigh->address) == OLSR_TRUE && hello_neigh->is_mpr == OLSR_TRUE) { selected_mpr = OLSR_TRUE; } //next pointer hello_neigh = hello_neigh->next; } //update mpr selector set , relay set, advertise neighbor set if(selected_mpr == OLSR_TRUE) { entry = hello->local_iface_list.head; while(entry) { local_entry = (OLSR_LOCAL_INTERFACE_BLOCK_ENTRY *)entry->data; retList = search_symmetric_neighbor_set(olsr, in_if, &local_entry->iface_addr); if(retList) { if(retList->numEntry != 1) { olsr_error("process_hello():5"); } get_current_time(olsr, &time); sym_data = (OLSR_SYMMETRIC_NEIGHBOR_TUPLE *)retList->head->data; OLSR_DeleteList_Search(retList); if(get_neighbor_status(&time, &sym_data->N_time) == SYMMETRIC) { proc_mpr_selector_set(olsr, &local_entry->iface_addr); if(olsr->change_mpr_selector_set) { if(proc_adv_neigh_set(olsr, &local_entry->iface_addr)){ proc_relay_set(olsr, &local_entry->iface_addr); change_assn = OLSR_TRUE; } } }//if(get_neigh...) } //next entry entry = entry->next; }//while } else{ // wiss: ici selected_mpr==false entry = hello->local_iface_list.head; while(entry) { local_entry = (OLSR_LOCAL_INTERFACE_BLOCK_ENTRY *)entry->data; delete_mpr_selector_set(olsr, &local_entry->iface_addr); if(olsr->change_mpr_selector_set) { delete_adv_neigh_set(olsr, &local_entry->iface_addr); if(olsr->change_adv_neigh_set) { change_assn = OLSR_TRUE; delete_relay_set(olsr, &local_entry->iface_addr); } } //next entry entry = entry->next; }//while } /* if I am selecetd as MPR by someone, I_am_MPR_flag turns ON and send TC message every TC_INTERVAL */ if (olsr->I_am_MPR_flag == OLSR_FALSE && olsr->adv_neigh_set.head != NULL){ olsr->I_am_MPR_flag = OLSR_TRUE; } if(DEBUG_OLSRV2) { olsr_printf("\tassn[%d]\n", get_local_assn(olsr)); } if (change_assn == OLSR_TRUE) increment_local_assn(olsr); return OLSR_TRUE; }
OLSR_LIST *proc_mpr_set_per_interface(struct olsrv2 *olsr, union olsr_ip_addr *local_iface_addr) { OLSR_LIST *MPR_set = NULL, N, N2; OLSR_LIST *retList = NULL; OLSR_LIST_ENTRY *tmp = NULL, *retList_tmp = NULL; OLSR_LINK_TUPLE *link_data = NULL; OLSR_2NEIGH_TUPLE *two_neigh_data = NULL; OLSR_MPR_N_TUPLE *mpr_n_data = NULL; OLSR_MPR_N2_TUPLE *mpr_n2_data = NULL; int hash_index; olsr_time_t time; get_current_time(olsr, &time); if (DEBUG_OLSRV2) { olsr_printf("\n[Start MPR selection per interface]\n"); } //Init MPR set MPR_set = (OLSR_LIST *)olsr_malloc(sizeof(OLSR_LIST), __FUNCTION__); OLSR_InitList(MPR_set); //Create MPR N // N - the set of such neighbor interfaces if (DEBUG_OLSRV2) { olsr_printf("[Create N]\n"); olsr_printf("[Appendix A.2]\n"); } OLSR_InitList(&N); tmp = olsr->link_set.head; while (tmp != NULL){ link_data = (OLSR_LINK_TUPLE *)tmp->data; if (link_data->L_willingness > WILL_NEVER && get_link_status(time, link_data->L_SYM_time, link_data->L_ASYM_time, link_data->L_LOST_LINK_time) == SYMMETRIC){ if (equal_ip_addr(olsr, &link_data->L_local_iface_addr, local_iface_addr)){ if (search_mprN_for_exist(olsr, &N, &link_data->L_neighbor_iface_addr) == OLSR_FALSE){ // Calculate D(y), where y is a member of N, for all interfaces in N. int retNum = check_2neigh_set_for_mpr_n_exist_num_entry(olsr, local_iface_addr, &link_data->L_neighbor_iface_addr); if (retNum > 0){ insert_mprN(&N, &link_data->L_neighbor_iface_addr, /*retList->numEntry*/retNum, 0, link_data->L_willingness); } } } } tmp = tmp->next; } //print_mprN(olsr, &N); //Create MPR N2 // N2 - the set of such 2-hop neighbor interfaces if (DEBUG_OLSRV2) { olsr_printf("[Create N2]\n"); } OLSR_InitList(&N2); for (hash_index = 0; hash_index < HASHSIZE; hash_index++) { tmp = olsr->two_neigh_set[hash_index].list.head; while (tmp != NULL){ two_neigh_data = (OLSR_2NEIGH_TUPLE *)tmp->data; if (search_mprN_for_exist(olsr, &N, &two_neigh_data->N2_neighbor_iface_addr) == OLSR_TRUE && search_association_set_for_addr_exist(olsr, &two_neigh_data->N2_2hop_iface_addr) == OLSR_FALSE){ if (equal_ip_addr(olsr, &two_neigh_data->N2_local_iface_addr, local_iface_addr)){ if (search_mprN_for_exist(olsr, &N, &two_neigh_data->N2_2hop_iface_addr) == OLSR_TRUE){ tmp = tmp->next; continue; } if (search_mprN2_for_exist(olsr, &N2, &two_neigh_data->N2_2hop_iface_addr) == OLSR_FALSE) { insert_mprN2(&N2, &two_neigh_data->N2_2hop_iface_addr); } } } tmp = tmp->next; } } //print_mprN2(olsr, &N2); //Appendix A.1 // Start with an MPR set made of all members of N with N_willingness // equal to WILL_ALWAYS if (DEBUG_OLSRV2) { olsr_printf("[Appendix A.1]\n"); } tmp = N.head; while (tmp != NULL){ mpr_n_data = (OLSR_MPR_N_TUPLE *)tmp->data; if (mpr_n_data->willingness == WILL_ALWAYS) insert_mpr_set_per_interface(MPR_set, local_iface_addr, &mpr_n_data->addr); tmp = tmp->next; } update_mprN2(olsr, &N2, MPR_set, local_iface_addr); //print_mprN2(olsr, &N2); //Appendix A.3 // Add to the MPR set those interfaces in N, which are the *only* // nodes to provide reachability to an interface in N2. For // example, if interface B in N2 can be reached only through a // symmetric link to interface A in N, then add interface B to the // MPR set. Remove the interfaces from N2 which are now covered by // a interface in the MPR set. if (DEBUG_OLSRV2) { olsr_printf("[Appendix A.3]\n"); } tmp = N2.head; while (tmp != NULL){ mpr_n2_data = (OLSR_MPR_N2_TUPLE *)tmp->data; retList = search_2neigh_set_for_mpr_n2(olsr, local_iface_addr, &mpr_n2_data->addr); if (retList != NULL){ if (retList->numEntry == 1){ two_neigh_data = (OLSR_2NEIGH_TUPLE *)retList->head->data; insert_mpr_set_per_interface(MPR_set, local_iface_addr, &two_neigh_data->N2_neighbor_iface_addr); update_mprN2_locally(olsr, &N2, local_iface_addr, &two_neigh_data->N2_neighbor_iface_addr); tmp = N2.head; OLSR_DeleteList_Search(retList); continue; } OLSR_DeleteList_Search(retList); } tmp = tmp->next; } //print_mprN2(olsr, &N2); //Appendix A.4 // While there exist interfaces in N2 which are not covered by at // least one interface in the MPR set: if (DEBUG_OLSRV2) { olsr_printf("[Appendix A.4]\n"); } while (N2.head != NULL){ //Appendix A.4.1 // For each interface in N, calculate the reachability, i.e., // the number of interfaces in N2 which are not yet covered by // at least one node in the MPR set, and which are reachable // through this neighbor interface; //OLSR_LIST *ret; olsr_u32_t max_willingness, max_reachability, max_D; olsr_u32_t i; union olsr_ip_addr mpr_addr; union olsr_ip_addr random_mpr[OLSR_MAX_DUPLICATE_MPR]; memset(&mpr_addr, 0, sizeof(olsr_ip_addr)); if (DEBUG_OLSRV2) { olsr_printf("[Appendix A.4.1]\n"); } tmp = N.head; while (tmp != NULL){ mpr_n_data = (OLSR_MPR_N_TUPLE *)tmp->data; mpr_n_data->reachability = 0; retList = search_2neigh_set_for_mpr_n(olsr, local_iface_addr, &mpr_n_data->addr); if (retList != NULL){ retList_tmp = retList->head; while (retList_tmp != NULL){ two_neigh_data = (OLSR_2NEIGH_TUPLE *)retList_tmp->data; if (search_mprN2_for_exist(olsr, &N2, &two_neigh_data->N2_2hop_iface_addr) == OLSR_TRUE){ mpr_n_data->reachability++; } retList_tmp = retList_tmp->next; } OLSR_DeleteList_Search(retList); } tmp = tmp->next; } //print_mprN(olsr, &N); //Appendix A.4.2(XXX) // Select as a MPR the interface with highest N_willingness // among the interfaces in N with non-zero reachability. // In case of multiple choice select the interface which provides // reachability to the maximum number of interfaces in N2. // In case of multiple interfaces providing the same amount of // reachability, select the interface as MPR whose D(y) is // greater. // Remove the interfaces from N2 which are now covered by an interface in the MPR set. tmp = N.head; max_willingness = WILL_NEVER; //0 max_reachability = 0; max_D = 0; i = 0; while (tmp != NULL){ mpr_n_data = (OLSR_MPR_N_TUPLE *)tmp->data; if (mpr_n_data->reachability == 0){ tmp = tmp->next; continue; } //check willingness if (mpr_n_data->willingness > max_willingness){ max_willingness = mpr_n_data->willingness; max_reachability = mpr_n_data->reachability; max_D = mpr_n_data->D; i = 0; mpr_addr = mpr_n_data->addr; } else if (mpr_n_data->willingness == max_willingness){ //check reachability if (mpr_n_data->reachability > max_reachability){ max_reachability = mpr_n_data->reachability; max_D = mpr_n_data->D; i = 0; mpr_addr = mpr_n_data->addr; } else if (mpr_n_data->reachability == max_reachability){ //check D(y) if (mpr_n_data->D > max_D){ max_D = mpr_n_data->D; i = 0; mpr_addr = mpr_n_data->addr; } else if (mpr_n_data->D == max_D){ if (i == 0){ random_mpr[i++] = mpr_addr; } if (i < OLSR_MAX_DUPLICATE_MPR){ random_mpr[i++] = mpr_n_data->addr; } } } } tmp = tmp->next; }// ....now checked duplication if (max_willingness == WILL_NEVER){ olsr_error("MPR selection is wrong " "there is no MPR which have available willingness, " "or non-zero-reachability"); } if (i != 0){ i = (olsr_u32_t)(random(olsr)%i); mpr_addr = random_mpr[i]; } insert_mpr_set_per_interface(MPR_set, local_iface_addr, &mpr_addr); update_mprN2_locally(olsr, &N2, local_iface_addr, &mpr_addr); //print_mpr_set_per_interface(olsr, MPR_set); } //print_mpr_set_per_interface(olsr, MPR_set); if (DEBUG_OLSRV2) { olsr_printf("[Complete MPR selection per interface]\n\n"); } OLSR_DeleteList_Static(&N); OLSR_DeleteList_Static(&N2); return MPR_set; }