/*
 * Create <tlv-block>
 */
void
build_tlv_local_by_list(void *olsr, olsr_pktbuf_t *buf, OLSR_LIST *addr_list) {
  OLSR_LIST tlv_block;
  OLSR_InitList(&tlv_block);

  create_other_if_tlv_by_list(olsr, &tlv_block, addr_list);
  build_tlv_msg(buf, &tlv_block);

  free_tlv_block(&tlv_block);
}
void
build_tlv_attached_network_by_list(void *olsr, olsr_pktbuf_t *buf, OLSR_LIST *addr_list)
{
  OLSR_LIST tlv_block;
  OLSR_InitList(&tlv_block);

  OLSR_LIST_ENTRY* tmp = NULL, *tmp1 = NULL, * next = NULL;
  BLOCK_DATA* data = NULL, *tmpData = NULL;

  tmp = addr_list->head;

  while(tmp)
    {
      data = (BLOCK_DATA* )tmp->data;
      create_tlv_by_list(olsr, &tlv_block,
             addr_list,
             PREFIX_LENGTH,
             data->Prefix_Length);

      tmp1 = tmp->next;
      while(tmp1){
        tmpData = (BLOCK_DATA* )tmp1->data;
        next = tmp1->next;
        if(data->Prefix_Length == tmpData->Prefix_Length){
           OLSR_DeleteListEntry(addr_list, tmp1);
        }
        tmp1 = next;
      }

      //delete current entry also
      tmp1 = tmp->next;
      OLSR_DeleteListEntry(addr_list, tmp);
      tmp = tmp1;
    }

  build_tlv_msg(buf, &tlv_block);
  free_tlv_block(&tlv_block);
}
void
build_tlv_hello_by_list(void *olsr, olsr_pktbuf_t *buf, OLSR_LIST *addr_list)
{
  OLSR_LIST tlv_block;
  OLSR_InitList(&tlv_block);


#ifdef USE_MULTI_VALUE
  create_hello_addr_tlv_by_multivalue(olsr, &tlv_block,
                      addr_list,
                      Link_Status);

  create_hello_addr_tlv_by_multivalue(olsr, &tlv_block,
                      addr_list,
                      PREFIX_LENGTH);
#else

  /*   create_tlv_by_list(&tlv_block, addr_list, Link_Status, SYMMETRIC); */
  /*   create_tlv_by_list(&tlv_block, addr_list, Link_Status, ASYMMETRIC); */
  /*     create_tlv_by_list(&tlv_block, addr_list, Link_Status, HEARD); */
  /* create_tlv_by_list(&tlv_block, addr_list, Link_Status, LOST); */
  create_linkstatus_tlv_by_list(olsr, &tlv_block, addr_list);
  //create_R_etx_tlv_by_list(olsr, &tlv_block, addr_list);
  create_mpr_selection_tlv_by_list(olsr, &tlv_block, addr_list); 
  create_other_neigh_tlv_by_list(olsr, &tlv_block, addr_list);
  create_prefix_tlv_by_list(olsr, &tlv_block, addr_list);
// wiss byetkawan 3enna list "tlv_block" b2alba bel partie data link status w mpr selection w .... TLVS 
//wiss : hella2 ma ba2 3layna ella nelze2on bel buffer
#endif

/*   create_tlv_by_list(&tlv_block, addr_list, Other_If, OLSR_TRUE); */
/*   create_tlv_by_list(&tlv_block, addr_list, MPR_Selection, OLSR_TRUE); */

  build_tlv_msg(buf, &tlv_block);

  free_tlv_block(&tlv_block);
}
示例#4
0
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;
}
示例#5
0
/* function implimentations */
void init_mpr_set(struct olsrv2 *olsr)
{
  olsr->change_mpr_set = OLSR_FALSE;
  OLSR_InitList(&olsr->mpr_set);
}
/* function implimentations */
void init_relay_set(struct olsrv2 *olsr)
{
  olsr->change_relay_set = OLSR_FALSE;
  OLSR_InitList(&olsr->relay_set);
}
static olsr_bool
tc_change_structure(struct olsrv2 *olsr, struct tc_message *tc_msg,
            struct message_header *m, union olsr_ip_addr *source)
{
  struct address_tuple *tmp_addr_entry = NULL;
  struct tlv_tuple *tlv_entry = NULL;

  struct tc_mpr_addr *mpr_entry = NULL;
  int i;
  ATTACHED_NETWORK *attached_net_entry = NULL;

  OLSR_LOCAL_INTERFACE_BLOCK_ENTRY local_iface_entry;

  // initialize
  memset(tc_msg, 0, sizeof(struct tc_message));

  // fill ipv4 header informations
  tlv_entry = get_msg_tlv(olsr, Validity_Time);
  if(tlv_entry->length == 1)
    tc_msg->vtime = me_to_double((olsr_u8_t)tlv_entry->value);
  else// greater than 3 byte
    tc_msg->vtime = get_validity_time_from_hop(tlv_entry, m->hop_count);

  olsr_ip_copy(olsr, &tc_msg->source_addr, source);
  olsr_ip_copy(olsr, &tc_msg->originator, &m->orig_addr);
  tc_msg->message_seq_number = m->message_seq_num;
  tc_msg->hop_count = m->hop_count;
  tc_msg->ttl = m->ttl;

  if ((tlv_entry = get_msg_tlv(olsr, Content_Sequence_Number)) == NULL){
    olsr_error("This Message include no ASSN\n");
  }else{//assume that assn is less equal than 4byte
    tc_msg->assn = (olsr_u16_t)tlv_entry->value;
  }
/*
//codexxx'
  tlv_entry = get_msg_tlv(olsr, queuelen);
   tc_msg->queuelength = (olsr_u8_t)tlv_entry->value;
  
  //end codexxx'  
*/
  if(proc_assn_history_set(olsr, &tc_msg->originator, tc_msg->assn)){
    free_all_address_entries(olsr);
    free_message_tlv(olsr);
    olsr_free_tc_packet(tc_msg);

    return OLSR_FALSE;
  }

  //local interface block
  OLSR_InitList(&tc_msg->local_iface_list);
  tmp_addr_entry = olsr->local_interface_block_entry;
  while(tmp_addr_entry) {
    olsr_ip_copy(olsr, &local_iface_entry.iface_addr, &tmp_addr_entry->ip_addr);
    local_iface_entry.other_if = OLSR_FALSE;

    tlv_entry = tmp_addr_entry->addr_tlv;
    while(tlv_entry) {
      switch(tlv_entry->type){
      case Other_If:
    if(tlv_entry->value == OLSR_TRUE)
      local_iface_entry.other_if = OLSR_TRUE;
    break;
      default:
    break;
      }
      tlv_entry = tlv_entry->next;
    }
    OLSR_InsertList(&tc_msg->local_iface_list, &local_iface_entry,
            sizeof(OLSR_LOCAL_INTERFACE_BLOCK_ENTRY));

    tmp_addr_entry= tmp_addr_entry->next;
  }

  // all mpr selector : advertized by tc
  tc_msg->mpr_selector_address = NULL;
  tc_msg->attached_net_addr = NULL;
  for (i = 0; i < olsr->num_of_addr_tlv_block_entries; ++i){
    tmp_addr_entry = olsr->addr_tlv_block_entries[i];
    tlv_entry = NULL;
    while (tmp_addr_entry){
      //attached network address
      if((tlv_entry = have_attached_network_tlv(tmp_addr_entry->addr_tlv)) != NULL)
    {
      attached_net_entry = (ATTACHED_NETWORK *)olsr_malloc( sizeof(ATTACHED_NETWORK), __FUNCTION__);
      memset(attached_net_entry, 0 , sizeof(ATTACHED_NETWORK));
      attached_net_entry->next = NULL;
      olsr_ip_copy(olsr, &attached_net_entry->network_addr, &tmp_addr_entry->ip_addr);
      attached_net_entry->prefix_length = (olsr_u8_t)tlv_entry->value;

      //queue
      if(tc_msg->attached_net_addr == NULL)
        tc_msg->attached_net_addr = attached_net_entry;
      else{
        attached_net_entry->next = tc_msg->attached_net_addr;
        tc_msg->attached_net_addr = attached_net_entry;
      }
      tmp_addr_entry = tmp_addr_entry->next;
      continue;
    }

      mpr_entry = (struct tc_mpr_addr *)olsr_malloc(sizeof(struct tc_mpr_addr), __FUNCTION__);
      memset(mpr_entry, 0, sizeof(struct tc_mpr_addr));

      olsr_ip_copy(olsr, &mpr_entry->address, &tmp_addr_entry->ip_addr);


      if (tc_msg->mpr_selector_address == NULL){//first
    tc_msg->mpr_selector_address = mpr_entry;
    mpr_entry->next = NULL;
      }else{
    mpr_entry->next = tc_msg->mpr_selector_address;
    tc_msg->mpr_selector_address = mpr_entry;
      }
      tmp_addr_entry = tmp_addr_entry->next;
    }

  }//for

  debug_code(print_tc_message(olsr, tc_msg));
  //free address tlv & message tlv
  free_all_address_entries(olsr);
  free_message_tlv(olsr);

  return OLSR_TRUE;
}
static olsr_bool
hello_change_structure(struct olsrv2 *olsr, struct hello_message *h_msg,
               struct message_header *m)
{
  struct address_tuple *tmp_addr_entry = NULL;
  struct tlv_tuple *tlv_entry = NULL;
  struct hello_neighbor *neigh = NULL;
  olsr_u8_t link_status_count;
  olsr_u8_t mpr_selection_count;
  olsr_u8_t other_neigh_count;

  //olsr_bool link_status_flag;
  //olsr_bool mpr_selection_flag;
  //olsr_bool other_neigh_flag;
  olsr_bool add_neigh;

  OLSR_LOCAL_INTERFACE_BLOCK_ENTRY local_iface_entry;

//MEMSET added for Linux
  memset(&local_iface_entry, 0, sizeof(OLSR_LOCAL_INTERFACE_BLOCK_ENTRY));

  int i;


  //initialize
  memset(h_msg, 0, sizeof(struct hello_message));
  //wiss: fill validity from message tlv
  tlv_entry = get_msg_tlv(olsr, Validity_Time);  // byetle3 3enna men el olsr el TLV_entry yalli 3endou tlv_type "Validity_Time"
  if(tlv_entry->length == 1)
    h_msg->vtime = me_to_double((olsr_u8_t)tlv_entry->value);
  else// greater than 3 byte
    h_msg->vtime = get_validity_time_from_hop(tlv_entry, m->hop_count);

  h_msg->htime = (double)h_msg->vtime/3; //wiss: ma fhemet chou hiye el htime

  //olsr_ip_copy(&h_msg->source_addr, &m->orig_addr);
  tmp_addr_entry = olsr->local_interface_block_entry;
  olsr_ip_copy(olsr, &h_msg->source_addr, &tmp_addr_entry->ip_addr);
  olsr_ip_copy(olsr, &h_msg->orig_addr, &m->orig_addr);
  //olsr_printf("Source = %s\n", IP_TO_STRING(&h_msg->source_addr));


  h_msg->hop_count = m->hop_count;
  h_msg->ttl = m->ttl;
  h_msg->message_seq_number = m->message_seq_num;

  // fill willingness from message tlv
  if((tlv_entry = get_msg_tlv(olsr, Willingness)) == NULL){
    // default //wiss: ya3ni hon ma la2a TLV willingness donc will_default
    h_msg->willingness = WILL_DEFAULT;
  }else{
    // assume that willingness is less equal than 4byte
    h_msg->willingness = (olsr_u8_t)tlv_entry->value;
  }

  //codexxx
  tlv_entry = get_msg_tlv(olsr, queuelen);
   h_msg->queuelength = (olsr_u8_t)tlv_entry->value;
  
  //end codexxx

  //local interface block
  OLSR_InitList(&h_msg->local_iface_list);
  tmp_addr_entry = olsr->local_interface_block_entry;
  while(tmp_addr_entry) {
    olsr_ip_copy(olsr, &local_iface_entry.iface_addr, &tmp_addr_entry->ip_addr);
    local_iface_entry.other_if = OLSR_FALSE;

    tlv_entry = tmp_addr_entry->addr_tlv;
    while(tlv_entry) {
      switch(tlv_entry->type){
      case Other_If:
    local_iface_entry.other_if = (olsr_u8_t)tlv_entry->value;
    break;
      default:
    break;
      }
      tlv_entry = tlv_entry->next;
    } // wiss: set local_iface_entry.other_if
    OLSR_InsertList(&h_msg->local_iface_list, &local_iface_entry,
            sizeof(OLSR_LOCAL_INTERFACE_BLOCK_ENTRY));

    tmp_addr_entry= tmp_addr_entry->next;
  }
// wiss : lahon biikoun tmalla el hello message "h_msg" bi kell el ma3loumet el lezme ella el champs "neighbors"
  //test
/*   olsr_ip_copy(&local_iface_entry.iface_addr, &olsr->local_interface_block_entry->ip_addr); */
/*   local_iface_entry.iface_addr.v4 += 1; */
/*   local_iface_entry.other_if = OLSR_FALSE; */
/*   OLSR_InsertList(&h_msg->local_iface_list, &local_iface_entry, */
/*        sizeof(OLSR_LOCAL_INTERFACE_BLOCK_ENTRY)); */

/*   olsr_ip_copy(&local_iface_entry.iface_addr, &olsr->local_interface_block_entry->ip_addr); */
/*   local_iface_entry.iface_addr.v4 += 2; */
/*   local_iface_entry.other_if = OLSR_FALSE; */
/*   OLSR_InsertList(&h_msg->local_iface_list, &local_iface_entry, */
/*        sizeof(OLSR_LOCAL_INTERFACE_BLOCK_ENTRY)); */

  // all neighbor :advertized by hello
  h_msg->neighbors = NULL;
  for (i = 0; i < olsr->num_of_addr_tlv_block_entries; ++i){
    tmp_addr_entry = olsr->addr_tlv_block_entries[i];
    while (tmp_addr_entry)
      {
    neigh = (struct hello_neighbor *)olsr_malloc(sizeof(struct hello_neighbor), __FUNCTION__);
    memset(neigh, 0, sizeof(struct hello_neighbor));

    add_neigh = OLSR_TRUE;


    tlv_entry = tmp_addr_entry->addr_tlv;
    link_status_count = mpr_selection_count = other_neigh_count = 0;
    //link_status_flag = mpr_selection_flag = other_neigh_flag = OLSR_FALSE;


    neigh->is_mpr = OLSR_FALSE;
    neigh->status = 255;
    neigh->other_neigh = 255;

    while (tlv_entry){
      switch (tlv_entry->type)
        {
        case Link_Status:
          link_status_count++;
          //link_status_flag = OLSR_TRUE;
          //assume that link status is less equal than 4byte
          neigh->status = (olsr_u8_t)tlv_entry->value;
          break;
        case MPR_Selection:
          mpr_selection_count++;
          //assume that mpr selection is less equal than 4byte
          neigh->is_mpr = OLSR_TRUE;
          break;
        case Other_Neigh:
          other_neigh_count ++;
          //other_neigh_flag = OLSR_TRUE;
          neigh->other_neigh = OLSR_TRUE;
          break;
        default:
          //default ignore
          break;
        }

      tlv_entry = tlv_entry->next;
    }

    // wiss:  la hon menkoun 3abayna el fields taba3 el neigh ella el IP address
    if (link_status_count > 1 || other_neigh_count > 1 || mpr_selection_count > 1)
    {
        if(DEBUG_OLSRV2)
        {
        char* paddr = olsr_niigata_ip_to_string(olsr, &neigh->address);
        olsr_printf("This Neighbor %s have over 2 same tlv type\n",paddr);
        free(paddr);
        }
      add_neigh = OLSR_FALSE; // wiss: bima ennu 3endou aktar men 2 same TLV men7ot add_neigh= false
    }

    if (olsr->olsr_cnf->ip_version == AF_INET){
      //check inconsistency
      if (neigh->is_mpr == OLSR_TRUE && neigh->status != SYMMETRIC)
        {
        if(DEBUG_OLSRV2)
        {
            olsr_printf("MPR have non symmetric link\n");
        }
        free(neigh);

        tmp_addr_entry = tmp_addr_entry->next;
        continue;
        /*
        free_all_address_entries(olsr);
        free_message_tlv(olsr);
        return OLSR_FALSE;
        */
        }

//    if (neigh->transmitting_iface == Other && neigh->status != SYMMETRIC)
//    {
//        if (DEBUG_OLSRV2){
//        olsr_printf("Other Interface have non symmetric link\n");
//        }
//        free_all_address_entries(olsr);
//        free_message_tlv(olsr);
//        free(neigh);
//        return OLSR_FALSE;
//    }

    }

    //add neighbor to hello_message
    if (add_neigh == OLSR_TRUE){ // wiss: bikoun true iza linkstatus count aw mpr count aw ...count <=1
      //copy neigh
      olsr_ip_copy(olsr, &neigh->address, &tmp_addr_entry->ip_addr);
      //queue
      if (h_msg->neighbors == NULL)
        {
          neigh->next = NULL;
          h_msg->neighbors = neigh;
        }
      else
        {
          neigh->next = h_msg->neighbors;
          h_msg->neighbors = neigh;
        }
    }else{// add_neigh == FALSE
      //skip this neighbor
        if(DEBUG_OLSRV2)
        {
        olsr_printf("Neighbor %s don't add neigh list\n");
        }
        free(neigh);
    }

    //next address advertized by hello
    tmp_addr_entry = tmp_addr_entry->next;
      }
  }//for


  if(DEBUG_OLSRV2)
  {
      print_hello_message(olsr, h_msg);
  }

  // free address tlv & message tlv
  free_all_address_entries(olsr);
  free_message_tlv(olsr);

  return OLSR_TRUE;
}