Example #1
0
static int on_neighbor_timer(struct thread *t)
{
  struct pim_neighbor *neigh;
  struct interface *ifp;
  char msg[100];

  zassert(t);
  neigh = THREAD_ARG(t);
  zassert(neigh);

  ifp = neigh->interface;

  if (PIM_DEBUG_PIM_TRACE) {
    char src_str[100];
    pim_inet4_dump("<src?>", neigh->source_addr, src_str, sizeof(src_str));
    zlog_debug("Expired %d sec holdtime for neighbor %s on interface %s",
	       neigh->holdtime, src_str, ifp->name);
  }

  neigh->t_expire_timer = 0;

  snprintf(msg, sizeof(msg), "%d-sec holdtime expired", neigh->holdtime);
  pim_neighbor_delete(ifp, neigh, msg);

  /*
    RFC 4601: 4.3.2.  DR Election
    
    A router's idea of the current DR on an interface can change when a
    PIM Hello message is received, when a neighbor times out, or when a
    router's own DR Priority changes.
  */
  pim_if_dr_election(ifp); // neighbor times out

  return 0;
}
static void pim_addr_change(struct interface *ifp)
{
  struct pim_interface *pim_ifp;

  pim_ifp = ifp->info;
  zassert(pim_ifp);

  pim_if_dr_election(ifp); /* router's own DR Priority (addr) changes -- Done TODO T30 */
  pim_if_update_join_desired(pim_ifp); /* depends on DR */
  pim_if_update_could_assert(ifp); /* depends on DR */
  pim_if_update_my_assert_metric(ifp); /* depends on could_assert */
  pim_if_update_assert_tracking_desired(ifp); /* depends on DR, join_desired */

  /*
    RFC 4601: 4.3.1.  Sending Hello Messages

    1) Before an interface goes down or changes primary IP address, a
    Hello message with a zero HoldTime should be sent immediately
    (with the old IP address if the IP address changed).
    -- FIXME See CAVEAT C13

    2) After an interface has changed its IP address, it MUST send a
    Hello message with its new IP address.
    -- DONE below

    3) If an interface changes one of its secondary IP addresses, a
    Hello message with an updated Address_List option and a non-zero
    HoldTime should be sent immediately.
    -- FIXME See TODO T31
   */
  pim_ifp->pim_ifstat_hello_sent = 0; /* reset hello counter */
  if (pim_ifp->pim_sock_fd < 0)
    return;
  pim_hello_restart_now(ifp);         /* send hello and restart timer */
}
Example #3
0
static void update_dr_priority(struct pim_neighbor *neigh,
			       pim_hello_options hello_options,
			       uint32_t dr_priority)
{
  pim_hello_options will_set_pri; /* boolean */
  pim_hello_options bit_flip;     /* boolean */
  pim_hello_options pri_change;   /* boolean */

  will_set_pri = PIM_OPTION_IS_SET(hello_options,
				   PIM_OPTION_MASK_DR_PRIORITY);

  bit_flip =
    (
     will_set_pri !=
     PIM_OPTION_IS_SET(neigh->hello_options, PIM_OPTION_MASK_DR_PRIORITY)
     );

  if (bit_flip) {
    struct pim_interface *pim_ifp = neigh->interface->info;

    /* update num. of neighbors without dr_pri */

    if (will_set_pri) {
      --pim_ifp->pim_dr_num_nondrpri_neighbors; 
    }
    else {
      ++pim_ifp->pim_dr_num_nondrpri_neighbors; 
    }
  }

  pri_change = 
    (
     bit_flip
     ||
     (neigh->dr_priority != dr_priority)
     );

  if (will_set_pri) {
    neigh->dr_priority = dr_priority;
  }
  else {
    neigh->dr_priority = 0; /* cosmetic unset */
  }

  if (pri_change) {
    /*
      RFC 4601: 4.3.2.  DR Election
      
      A router's idea of the current DR on an interface can change when a
      PIM Hello message is received, when a neighbor times out, or when a
      router's own DR Priority changes.
    */
    pim_if_dr_election(neigh->interface); // router's own DR Priority changes
  }
}
Example #4
0
struct pim_neighbor *pim_neighbor_add(struct interface *ifp,
				      struct in_addr source_addr,
				      pim_hello_options hello_options,
				      uint16_t holdtime,
				      uint16_t propagation_delay,
				      uint16_t override_interval,
				      uint32_t dr_priority,
				      uint32_t generation_id,
				      struct list *addr_list)
{
  struct pim_interface *pim_ifp;
  struct pim_neighbor *neigh;

  neigh = pim_neighbor_new(ifp, source_addr,
			   hello_options,
			   holdtime,
			   propagation_delay,
			   override_interval,
			   dr_priority,
			   generation_id,
			   addr_list);
  if (!neigh) {
    return 0;
  }

  pim_ifp = ifp->info;
  zassert(pim_ifp);

  listnode_add(pim_ifp->pim_neighbor_list, neigh);

  /*
    RFC 4601: 4.3.2.  DR Election

    A router's idea of the current DR on an interface can change when a
    PIM Hello message is received, when a neighbor times out, or when a
    router's own DR Priority changes.
  */
  pim_if_dr_election(neigh->interface); // new neighbor -- should not trigger dr election...

  /*
    RFC 4601: 4.3.1.  Sending Hello Messages

    To allow new or rebooting routers to learn of PIM neighbors quickly,
    when a Hello message is received from a new neighbor, or a Hello
    message with a new GenID is received from an existing neighbor, a
    new Hello message should be sent on this interface after a
    randomized delay between 0 and Triggered_Hello_Delay.
  */
  pim_hello_restart_triggered(neigh->interface);

  return neigh;
}