示例#1
0
int
ospf_hello_timer (struct thread *thread)
{
  struct ospf_interface *oi;

  oi = THREAD_ARG (thread);
  oi->t_hello = NULL;

  if (IS_DEBUG_OSPF (ism, ISM_TIMERS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: Timer (Hello timer expire)",
	  IF_NAME (oi));

  /* Sending hello packet. */
  ospf_hello_send (oi);

  /* Hello timer set. */
  OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer,
		     OSPF_IF_PARAM (oi, v_hello));

  return 0;
}
示例#2
0
文件: ospf_nsm.c 项目: OPSF/uClinux
void
nsm_change_state (struct ospf_neighbor *nbr, int state)
{
  struct ospf_interface *oi = nbr->oi;
  struct ospf_area *vl_area = NULL;
  u_char old_state;
  int x;
  int force = 1;
  
  /* Logging change of status. */
  if (IS_DEBUG_OSPF (nsm, NSM_STATUS))
    zlog_debug ("NSM[%s:%s]: State change %s -> %s",
	       IF_NAME (nbr->oi), inet_ntoa (nbr->router_id),
	       LOOKUP (ospf_nsm_state_msg, nbr->state),
	       LOOKUP (ospf_nsm_state_msg, state));

  /* Preserve old status. */
  old_state = nbr->state;

  /* Change to new status. */
  nbr->state = state;

  /* Statistics. */
  nbr->state_change++;

  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
    vl_area = ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
  
  /* One of the neighboring routers changes to/from the FULL state. */
  if ((old_state != NSM_Full && state == NSM_Full) ||
      (old_state == NSM_Full && state != NSM_Full))
    {
      if (state == NSM_Full)
	{
	  oi->full_nbrs++;
	  oi->area->full_nbrs++;

          ospf_check_abr_status (oi->ospf);

	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area)
            if (++vl_area->full_vls == 1)
	      ospf_schedule_abr_task (oi->ospf);

	  /* kevinm: refresh any redistributions */
	  for (x = ZEBRA_ROUTE_SYSTEM; x < ZEBRA_ROUTE_MAX; x++)
	    {
	      if (x == ZEBRA_ROUTE_OSPF || x == ZEBRA_ROUTE_OSPF6)
		continue;
	      ospf_external_lsa_refresh_type (oi->ospf, x, force);
	    }
	}
      else
	{
	  oi->full_nbrs--;
	  oi->area->full_nbrs--;

          ospf_check_abr_status (oi->ospf);

	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area)
	    if (vl_area->full_vls > 0)
	      if (--vl_area->full_vls == 0)
		ospf_schedule_abr_task (oi->ospf);
 
          /* clear neighbor retransmit list */
          if (!ospf_ls_retransmit_isempty (nbr))
            ospf_ls_retransmit_clear (nbr);
	}

      zlog_info ("nsm_change_state(%s, %s -> %s): "
		 "scheduling new router-LSA origination",
		 inet_ntoa (nbr->router_id),
		 LOOKUP(ospf_nsm_state_msg, old_state),
		 LOOKUP(ospf_nsm_state_msg, state));

      ospf_router_lsa_timer_add (oi->area);

      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	{
	  struct ospf_area *vl_area =
	    ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);
	  
	  if (vl_area)
	    ospf_router_lsa_timer_add (vl_area);
	}

      /* Originate network-LSA. */
      if (oi->state == ISM_DR)
	{
	  if (oi->network_lsa_self && oi->full_nbrs == 0)
	    {
	      ospf_lsa_flush_area (oi->network_lsa_self, oi->area);
	      ospf_lsa_unlock (oi->network_lsa_self);
	      oi->network_lsa_self = NULL;
	      OSPF_TIMER_OFF (oi->t_network_lsa_self);
	    }
	  else
	    ospf_network_lsa_timer_add (oi);
	}
    }

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_nsm_change (nbr, old_state);
#endif /* HAVE_OPAQUE_LSA */

  /* Start DD exchange protocol */
  if (state == NSM_ExStart)
    {
      if (nbr->dd_seqnum == 0)
	nbr->dd_seqnum = time (NULL);
      else
	nbr->dd_seqnum++;

      nbr->dd_flags = OSPF_DD_FLAG_I|OSPF_DD_FLAG_M|OSPF_DD_FLAG_MS;
      ospf_db_desc_send (nbr);
    }

  /* clear cryptographic sequence number */
  if (state == NSM_Down)
    nbr->crypt_seqnum = 0;
  
  /* Generete NeighborChange ISM event. */
#ifdef BUGGY_ISM_TRANSITION
  if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) ||
      (old_state >= NSM_TwoWay && state < NSM_TwoWay))
    OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange);
#else /* BUGGY_ISM_TRANSITION */
  switch (oi->state) {
  case ISM_DROther:
  case ISM_Backup:
  case ISM_DR:
    if ((old_state < NSM_TwoWay && state >= NSM_TwoWay) ||
        (old_state >= NSM_TwoWay && state < NSM_TwoWay))
      OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange);
    break;
  default:
    /* ISM_PointToPoint -> ISM_Down, ISM_Loopback -> ISM_Down, etc. */
    break;
  }
#endif /* BUGGY_ISM_TRANSITION */

  /* Performance hack. Send hello immideately when some neighbor enter
     Init state.  This whay we decrease neighbor discovery time. Gleb.*/
  if (state == NSM_Init)
    {
      OSPF_ISM_TIMER_OFF (oi->t_hello);
      OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, 1);
    }

  /* Preserve old status? */
}
示例#3
0
/* Hook function called after ospf ISM event is occured. And vty's
   network command invoke this function after making interface
   structure. */
static void
ism_timer_set (struct ospf_interface *oi)
{
  switch (oi->state)
    {
    case ISM_Down:
      /* First entry point of ospf interface state machine. In this state
	 interface parameters must be set to initial values, and timers are
	 reset also. */
      OSPF_ISM_TIMER_OFF (oi->t_hello);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
      break;
    case ISM_Loopback:
      /* In this state, the interface may be looped back and will be
	 unavailable for regular data traffic. */
      OSPF_ISM_TIMER_OFF (oi->t_hello);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
      break;
    case ISM_Waiting:
      /* The router is trying to determine the identity of DRouter and
	 BDRouter. The router begin to receive and send Hello Packets. */
      /* send first hello immediately */
      OSPF_ISM_TIMER_MSEC_ON (oi->t_hello, ospf_hello_timer, 1);
      OSPF_ISM_TIMER_ON (oi->t_wait, ospf_wait_timer,
			 OSPF_IF_PARAM (oi, v_wait));
      OSPF_ISM_TIMER_OFF (oi->t_ls_ack);
      break;
    case ISM_PointToPoint:
      /* The interface connects to a physical Point-to-point network or
	 virtual link. The router attempts to form an adjacency with
	 neighboring router. Hello packets are also sent. */
      /* send first hello immediately */
      OSPF_ISM_TIMER_MSEC_ON (oi->t_hello, ospf_hello_timer, 1);      
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    case ISM_DROther:
      /* The network type of the interface is broadcast or NBMA network,
	 and the router itself is neither Designated Router nor
	 Backup Designated Router. */
      OSPF_HELLO_TIMER_ON (oi);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    case ISM_Backup:
      /* The network type of the interface is broadcast os NBMA network,
	 and the router is Backup Designated Router. */
      OSPF_HELLO_TIMER_ON (oi);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    case ISM_DR:
      /* The network type of the interface is broadcast or NBMA network,
	 and the router is Designated Router. */
      OSPF_HELLO_TIMER_ON (oi);
      OSPF_ISM_TIMER_OFF (oi->t_wait);
      OSPF_ISM_TIMER_ON (oi->t_ls_ack, ospf_ls_ack_timer, oi->v_ls_ack);
      break;
    }
}
示例#4
0
void
nsm_change_status (struct ospf_neighbor *nbr, int status)
{
  int old_status;
  struct ospf_interface *oi;
  struct ospf_area *vl_area = NULL;
  
  /* Logging change of status. */
  if (IS_DEBUG_OSPF (nsm, NSM_STATUS))
    zlog_info ("NSM[%s:%s]: Status change %s -> %s",
	       IF_NAME (nbr->oi), inet_ntoa (nbr->router_id),
	       LOOKUP (ospf_nsm_status_msg, nbr->status),
	       LOOKUP (ospf_nsm_status_msg, status));

  /* Preserve old status. */
  old_status = nbr->status;

  /* Change to new status. */
  nbr->status = status;

  /* Statistics. */
  nbr->state_change++;

  oi = nbr->oi;

  if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
    vl_area = ospf_area_lookup_by_area_id (oi->vl_data->vl_area_id);
  
  /* One of the neighboring routers changes to/from the FULL state. */
  if ((old_status != NSM_Full && status == NSM_Full) ||
      (old_status == NSM_Full && status != NSM_Full))
    { 
      if (status == NSM_Full)
	{
	  oi->full_nbrs++;
	  oi->area->full_nbrs++;

          ospf_check_abr_status ();

	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area)
            if (++vl_area->full_vls == 1)
	      ospf_schedule_abr_task ();
	}
      else
	{
	  oi->full_nbrs--;
	  oi->area->full_nbrs--;

          ospf_check_abr_status ();

	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK && vl_area)
	    if (vl_area->full_vls > 0)
	      if (--vl_area->full_vls == 0)
		ospf_schedule_abr_task ();
 
          /* clear neighbor retransmit list */
          if (!ospf_ls_retransmit_isempty (nbr))
            ospf_ls_retransmit_clear (nbr);
	}

      zlog_info ("nsm_change_status(): "
		 "scheduling new router-LSA origination");

      ospf_router_lsa_timer_add (oi->area);

      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
	{
	  struct ospf_area *vl_area =
	    ospf_area_lookup_by_area_id (oi->vl_data->vl_area_id);
	  
	  if (vl_area)
	    ospf_router_lsa_timer_add (vl_area);
	}

      /* Originate network-LSA. */
      if (oi->status == ISM_DR)
	{
	  if (oi->network_lsa_self && oi->full_nbrs == 0)
	    {
	      ospf_lsa_flush_area (oi->network_lsa_self, oi->area);
	      ospf_lsa_unlock (oi->network_lsa_self);
	      oi->network_lsa_self = NULL;
	      OSPF_TIMER_OFF (oi->t_network_lsa_self);
	    }
	  else
	    ospf_network_lsa_timer_add (oi);
	}
    }

  /* Start DD exchange protocol */
  if (status == NSM_ExStart)
    {
      if (nbr->dd_seqnum == 0)
	nbr->dd_seqnum = time (NULL);
      else
	nbr->dd_seqnum++;

      nbr->dd_flags = OSPF_DD_FLAG_I|OSPF_DD_FLAG_M|OSPF_DD_FLAG_MS;
      ospf_db_desc_send (nbr);
    }

  /* clear cryptographic sequence number */
  if (status == NSM_Down)
    nbr->crypt_seqnum = 0;
  
  /* Generete NeighborChange ISM event. */
  if ((old_status < NSM_TwoWay && status >= NSM_TwoWay) ||
      (old_status >= NSM_TwoWay && status < NSM_TwoWay))
    OSPF_ISM_EVENT_EXECUTE (oi, ISM_NeighborChange);

  /* Performance hack. Send hello immideately when some neighbor enter
     Init state.  This whay we decrease neighbor discovery time. Gleb.*/
  if (status == NSM_Init)
    {
      OSPF_ISM_TIMER_OFF (oi->t_hello);
      OSPF_ISM_TIMER_ON (oi->t_hello, ospf_hello_timer, 1);
    }

  /* Preserve old status? */
}