Example #1
0
/**
 *This function processes the chosen MPRs and updates the counters
 *used in calculations
 */
static int
olsr_chosen_mpr(struct neighbor_entry *one_hop_neighbor, uint16_t * two_hop_covered_count)
{
  struct neighbor_list_entry *the_one_hop_list;
  struct neighbor_2_list_entry *second_hop_entries;
  struct neighbor_entry *dup_neighbor;
  uint16_t count;
  struct ipaddr_str buf;
  count = *two_hop_covered_count;

  OLSR_PRINTF(1, "Setting %s as MPR\n", olsr_ip_to_string(&buf, &one_hop_neighbor->neighbor_main_addr));

  //printf("PRE COUNT: %d\n\n", count);

  one_hop_neighbor->is_mpr = true;      //NBS_MPR;

  for (second_hop_entries = one_hop_neighbor->neighbor_2_list.next; second_hop_entries != &one_hop_neighbor->neighbor_2_list;
       second_hop_entries = second_hop_entries->next) {
    dup_neighbor = olsr_lookup_neighbor_table(&second_hop_entries->neighbor_2->neighbor_2_addr);

    if ((dup_neighbor != NULL) && (dup_neighbor->status == SYM)) {
      //OLSR_PRINTF(7, "(2)Skipping 2h neighbor %s - already 1hop\n", olsr_ip_to_string(&buf, &second_hop_entries->neighbor_2->neighbor_2_addr));
      continue;
    }
    //      if(!second_hop_entries->neighbor_2->neighbor_2_state)
    //if(second_hop_entries->neighbor_2->mpr_covered_count < olsr_cnf->mpr_coverage)
    //{
    /*
       Now the neighbor is covered by this mpr
     */
    second_hop_entries->neighbor_2->mpr_covered_count++;
    the_one_hop_list = second_hop_entries->neighbor_2->neighbor_2_nblist.next;

    //OLSR_PRINTF(1, "[%s](%x) has coverage %d\n", olsr_ip_to_string(&buf, &second_hop_entries->neighbor_2->neighbor_2_addr), second_hop_entries->neighbor_2, second_hop_entries->neighbor_2->mpr_covered_count);

    if (second_hop_entries->neighbor_2->mpr_covered_count >= olsr_cnf->mpr_coverage)
      count++;

    while (the_one_hop_list != &second_hop_entries->neighbor_2->neighbor_2_nblist) {

      if ((the_one_hop_list->neighbor->status == SYM)) {
        if (second_hop_entries->neighbor_2->mpr_covered_count >= olsr_cnf->mpr_coverage) {
          the_one_hop_list->neighbor->neighbor_2_nocov--;
        }
      }
      the_one_hop_list = the_one_hop_list->next;
    }

    //}
  }

  //printf("POST COUNT %d\n\n", count);

  *two_hop_covered_count = count;
  return count;

}
Example #2
0
/**
 *Find all 2 hop neighbors with 1 link
 *connecting them to us trough neighbors
 *with a given willingness.
 *
 *@param willingness the willigness of the neighbors
 *
 *@return a linked list of allocated neighbor_2_list_entry structures
 */
static struct neighbor_2_list_entry *
olsr_find_2_hop_neighbors_with_1_link(int willingness)
{

  uint8_t idx;
  struct neighbor_2_list_entry *two_hop_list_tmp = NULL;
  struct neighbor_2_list_entry *two_hop_list = NULL;
  struct neighbor_entry *dup_neighbor;
  struct neighbor_2_entry *two_hop_neighbor = NULL;

  for (idx = 0; idx < HASHSIZE; idx++) {

    for (two_hop_neighbor = two_hop_neighbortable[idx].next; two_hop_neighbor != &two_hop_neighbortable[idx];
         two_hop_neighbor = two_hop_neighbor->next) {

      //two_hop_neighbor->neighbor_2_state=0;
      //two_hop_neighbor->mpr_covered_count = 0;

      dup_neighbor = olsr_lookup_neighbor_table(&two_hop_neighbor->neighbor_2_addr);

      if ((dup_neighbor != NULL) && (dup_neighbor->status != NOT_SYM)) {

        //OLSR_PRINTF(1, "(1)Skipping 2h neighbor %s - already 1hop\n", olsr_ip_to_string(&buf, &two_hop_neighbor->neighbor_2_addr));

        continue;
      }

      if (two_hop_neighbor->neighbor_2_pointer == 1) {
        if ((two_hop_neighbor->neighbor_2_nblist.next->neighbor->willingness == willingness)
            && (two_hop_neighbor->neighbor_2_nblist.next->neighbor->status == SYM)) {
          two_hop_list_tmp = olsr_malloc(sizeof(struct neighbor_2_list_entry), "MPR two hop list");

          //OLSR_PRINTF(1, "ONE LINK ADDING %s\n", olsr_ip_to_string(&buf, &two_hop_neighbor->neighbor_2_addr));

          /* Only queue one way here */
          two_hop_list_tmp->neighbor_2 = two_hop_neighbor;

          two_hop_list_tmp->next = two_hop_list;

          two_hop_list = two_hop_list_tmp;
        }
      }

    }

  }

  return (two_hop_list_tmp);
}
Example #3
0
/**
 *Optimize MPR set by removing all entries
 *where all 2 hop neighbors actually is
 *covered by enough MPRs already
 *Described in RFC3626 section 8.3.1
 *point 5
 *
 *@return nada
 */
static void
olsr_optimize_mpr_set(void)
{
  struct neighbor_entry *a_neighbor, *dup_neighbor;
  struct neighbor_2_list_entry *two_hop_list;
  int i, removeit;

#if 0
  printf("\n**MPR OPTIMIZING**\n\n");
#endif

  for (i = WILL_NEVER + 1; i < WILL_ALWAYS; i++) {

    OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {

      if (a_neighbor->willingness != i) {
        continue;
      }

      if (a_neighbor->is_mpr) {
        removeit = 1;

        for (two_hop_list = a_neighbor->neighbor_2_list.next; two_hop_list != &a_neighbor->neighbor_2_list;
             two_hop_list = two_hop_list->next) {

          dup_neighbor = olsr_lookup_neighbor_table(&two_hop_list->neighbor_2->neighbor_2_addr);

          if ((dup_neighbor != NULL) && (dup_neighbor->status != NOT_SYM)) {
            continue;
          }
          //printf("\t[%s] coverage %d\n", olsr_ip_to_string(&buf, &two_hop_list->neighbor_2->neighbor_2_addr), two_hop_list->neighbor_2->mpr_covered_count);
          /* Do not remove if we find a entry which need this MPR */
          if (two_hop_list->neighbor_2->mpr_covered_count <= olsr_cnf->mpr_coverage) {
            removeit = 0;
          }
        }

        if (removeit) {
          struct ipaddr_str buf;
          OLSR_PRINTF(3, "MPR OPTIMIZE: removiong mpr %s\n\n", olsr_ip_to_string(&buf, &a_neighbor->neighbor_main_addr));
          a_neighbor->is_mpr = false;
        }
      }
    } OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);
  }
}
Example #4
0
/**
 *This function calculates the number of two hop neighbors
 */
static uint16_t
olsr_calculate_two_hop_neighbors(void)
{
  struct neighbor_entry *a_neighbor, *dup_neighbor;
  struct neighbor_2_list_entry *twohop_neighbors;
  uint16_t count = 0;
  uint16_t n_count = 0;
  uint16_t sum = 0;

  /* Clear 2 hop neighs */
  olsr_clear_two_hop_processed();

  OLSR_FOR_ALL_NBR_ENTRIES(a_neighbor) {

    if (a_neighbor->status == NOT_SYM) {
      a_neighbor->neighbor_2_nocov = count;
      continue;
    }

    for (twohop_neighbors = a_neighbor->neighbor_2_list.next; twohop_neighbors != &a_neighbor->neighbor_2_list;
         twohop_neighbors = twohop_neighbors->next) {

      dup_neighbor = olsr_lookup_neighbor_table(&twohop_neighbors->neighbor_2->neighbor_2_addr);

      if ((dup_neighbor == NULL) || (dup_neighbor->status != SYM)) {
        n_count++;
        if (!twohop_neighbors->neighbor_2->processed) {
          count++;
          twohop_neighbors->neighbor_2->processed = 1;
        }
      }
    }
    a_neighbor->neighbor_2_nocov = n_count;

    /* Add the two hop count */
    sum += count;

  }
  OLSR_FOR_ALL_NBR_ENTRIES_END(a_neighbor);

  OLSR_PRINTF(3, "Two hop neighbors: %d\n", sum);
  return sum;
}
Example #5
0
/**
 *Check if a message is to be forwarded and forward
 *it if necessary.
 *
 *@param m the OLSR message to be forwarded
 *@param neighbour we received message from
 *
 *@returns positive if forwarded
 */
int
olsr_forward_message(union olsr_message *m, struct interface *in_if, union olsr_ip_addr *from_addr)
{
  union olsr_ip_addr *src;
  struct neighbor_entry *neighbor;
  int msgsize;
  struct interface *ifn;
  bool is_ttl_1 = false;

  /*
   * Sven-Ola: We should not flood the mesh with overdue messages. Because
   * of a bug in parser.c:parse_packet, we have a lot of messages because
   * all older olsrd's have lq_fish enabled.
   */
  if (AF_INET == olsr_cnf->ip_version) {
    if (m->v4.ttl < 2 || 255 < (int)m->v4.hopcnt + (int)m->v4.ttl)
      is_ttl_1 = true;
  } else {
    if (m->v6.ttl < 2 || 255 < (int)m->v6.hopcnt + (int)m->v6.ttl)
      is_ttl_1 = true;
  }

  /* Lookup sender address */
  src = mid_lookup_main_addr(from_addr);
  if (!src)
    src = from_addr;

  neighbor = olsr_lookup_neighbor_table(src);
  if (!neighbor)
    return 0;

  if (neighbor->status != SYM)
    return 0;

  /* Check MPR */
  if (olsr_lookup_mprs_set(src) == NULL) {
#ifdef DEBUG
    struct ipaddr_str buf;
    OLSR_PRINTF(5, "Forward - sender %s not MPR selector\n", olsr_ip_to_string(&buf, src));
#endif
    return 0;
  }

  if (olsr_message_is_duplicate(m)) {
    return 0;
  }

  /* Treat TTL hopcnt except for ethernet link */
  if (!is_ttl_1) {
    if (olsr_cnf->ip_version == AF_INET) {
      /* IPv4 */
      m->v4.hopcnt++;
      m->v4.ttl--;
    } else {
      /* IPv6 */
      m->v6.hopcnt++;
      m->v6.ttl--;
    }
  }

  /* Update packet data */
  msgsize = ntohs(m->v4.olsr_msgsize);

  /* looping trough interfaces */
  for (ifn = ifnet; ifn; ifn = ifn->int_next) {
    /* do not retransmit out through the same interface if it has mode == ether */
    if (ifn == in_if && ifn->mode == IF_MODE_ETHER) continue;

    /* do not forward TTL 1 messages to non-ether interfaces */
    if (is_ttl_1 && ifn->mode != IF_MODE_ETHER) continue;

    if (net_output_pending(ifn)) {
      /*
       * Check if message is to big to be piggybacked
       */
      if (net_outbuffer_push(ifn, m, msgsize) != msgsize) {
        /* Send */
        net_output(ifn);
        /* Buffer message */
        set_buffer_timer(ifn);

        if (net_outbuffer_push(ifn, m, msgsize) != msgsize) {
          OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
          olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
        }
      }
    } else {
      /* No forwarding pending */
      set_buffer_timer(ifn);

      if (net_outbuffer_push(ifn, m, msgsize) != msgsize) {
        OLSR_PRINTF(1, "Received message to big to be forwarded in %s(%d bytes)!", ifn->int_name, msgsize);
        olsr_syslog(OLSR_LOG_ERR, "Received message to big to be forwarded on %s(%d bytes)!", ifn->int_name, msgsize);
      }
    }
  }
  return 1;
}