Пример #1
0
int
if_setsockopt_bindtodevice(int *sd, interface_t *ifp)
{
	int ret;

	if (*sd < 0)
		return -1;

	/* -> inbound processing option
	 * Specify the bound_dev_if.
	 * why IP_ADD_MEMBERSHIP & IP_MULTICAST_IF doesnt set
	 * sk->bound_dev_if themself ??? !!!
	 * Needed for filter multicasted advert per interface.
	 *
	 * -- If you read this !!! and know the answer to the question
	 *    please feel free to answer me ! :)
	 */
	ret = setsockopt(*sd, SOL_SOCKET, SO_BINDTODEVICE, IF_NAME(ifp), strlen(IF_NAME(ifp)) + 1);
	if (ret < 0) {
		log_message(LOG_INFO, "cant bind to device %s. errno=%d. (try to run it as root)",
			    IF_NAME(ifp), errno);
		close(*sd);
		*sd = -1;
	}

	return *sd;
}
Пример #2
0
/* Execute NSM event process. */
int
ospf_nsm_event (struct thread *thread)
{
  int event;
  int next_state;
  struct ospf_neighbor *nbr;
  struct in_addr router_id;
  int old_state;
  struct ospf_interface *oi;

  nbr = THREAD_ARG (thread);
  event = THREAD_VAL (thread);
  router_id = nbr->router_id;

  old_state = nbr->state;
  oi = nbr->oi ;
  
  /* Call function. */
  next_state = (*(NSM [nbr->state][event].func))(nbr);

  /* When event is NSM_KillNbr or InactivityTimer, the neighbor is
     deleted. */
  if (event == NSM_KillNbr || event == NSM_InactivityTimer)
    {
      if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
	zlog_debug ("NSM[%s:%s]: neighbor deleted",
		   IF_NAME (oi), inet_ntoa (router_id));

      /* Timers are canceled in ospf_nbr_free, moreover we cannot call
         nsm_timer_set here because nbr is freed already!!!*/
      /*nsm_timer_set (nbr);*/

      return 0;
    }

  if (! next_state)
    next_state = NSM [nbr->state][event].next_state;

  if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
    zlog_debug ("NSM[%s:%s]: %s (%s)", IF_NAME (oi),
	       inet_ntoa (nbr->router_id),
	       LOOKUP (ospf_nsm_state_msg, nbr->state),
	       ospf_nsm_event_str [event]);
  
  /* If state is changed. */
  if (next_state != nbr->state)
    nsm_change_state (nbr, next_state);

  /* Make sure timer is set. */
  nsm_timer_set (nbr);

  return 0;
}
Пример #3
0
static void
nsm_notice_state_change (struct ospf_neighbor *nbr, int next_state, int event)
{
  /* Logging change of status. */
  if (IS_DEBUG_OSPF (nsm, NSM_STATUS))
    zlog_debug ("NSM[%s:%s]: State change %s -> %s (%s)",
               IF_NAME (nbr->oi), inet_ntoa (nbr->router_id),
               LOOKUP (ospf_nsm_state_msg, nbr->state),
               LOOKUP (ospf_nsm_state_msg, next_state),
               ospf_nsm_event_str [event]);

  /* Optionally notify about adjacency changes */
  if (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_CHANGES) &&
      (CHECK_FLAG(nbr->oi->ospf->config, OSPF_LOG_ADJACENCY_DETAIL) ||
       (next_state == NSM_Full) || (next_state < nbr->state)))
    zlog_notice("AdjChg: Nbr %s on %s: %s -> %s (%s)",
                inet_ntoa (nbr->router_id), IF_NAME (nbr->oi),
                LOOKUP (ospf_nsm_state_msg, nbr->state),
                LOOKUP (ospf_nsm_state_msg, next_state),
                ospf_nsm_event_str [event]);

  /* Advance in NSM */
  if (next_state > nbr->state)
    nbr->ts_last_progress = recent_relative_time ();
  else /* regression in NSM */
    {
      nbr->ts_last_regress = recent_relative_time ();
      nbr->last_regress_str = ospf_nsm_event_str [event];
    }

#ifdef HAVE_SNMP
  /* Terminal state or regression */ 
  if ((next_state == NSM_Full) 
      || (next_state == NSM_TwoWay)
      || (next_state < nbr->state))
    {
      /* ospfVirtNbrStateChange */
      if (nbr->oi->type == OSPF_IFTYPE_VIRTUALLINK)
        ospfTrapVirtNbrStateChange(nbr);
      /* ospfNbrStateChange trap  */
      else	
        /* To/From FULL, only managed by DR */
        if (((next_state != NSM_Full) && (nbr->state != NSM_Full)) 
            || (nbr->oi->state == ISM_DR))
          ospfTrapNbrStateChange(nbr);
    }
#endif
}
Пример #4
0
void
address_print(FILE *file, void *data)
{
	ip_address_t *ipaddr = data;
	char *broadcast = (char *) MALLOC(21);
	char *addr_str = (char *) MALLOC(41);

	if (IP_IS6(ipaddr)) {
		inet_ntop(AF_INET6, &ipaddr->u.sin6_addr, addr_str, 41);
	} else {
		inet_ntop(AF_INET, &ipaddr->u.sin.sin_addr, addr_str, 41);
	if (ipaddr->u.sin.sin_brd.s_addr)
		snprintf(broadcast, 20, " brd %s",
			 inet_ntop2(ipaddr->u.sin.sin_brd.s_addr));
	}

	fprintf(file, "     %s/%d%s dev %s scope %s%s%s\n"
		, addr_str
		, ipaddr->ifa.ifa_prefixlen
		, broadcast
		, IF_NAME(ipaddr->ifp)
		, netlink_scope_n2a(ipaddr->ifa.ifa_scope)
		, ipaddr->label ? " label " : ""
		, ipaddr->label ? ipaddr->label : "");
	FREE(broadcast);
	FREE(addr_str);
}
Пример #5
0
/* Delete specified OSPF neighbor from interface. */
void ospf_nbr_delete(struct ospf_neighbor *nbr)
{
	struct ospf_interface *oi;
	struct route_node *rn;
	struct prefix p;

	oi = nbr->oi;

	/* get appropriate prefix 'key' */
	ospf_nbr_key(oi, nbr, &p);

	rn = route_node_lookup(oi->nbrs, &p);
	if (rn) {
		/* If lookup for a NBR succeeds, the leaf route_node could
		 * only exist because there is (or was) a nbr there.
		 * If the nbr was deleted, the leaf route_node should have
		 * lost its last refcount too, and be deleted.
		 * Therefore a looked-up leaf route_node in nbrs table
		 * should never have NULL info.
		 */
		assert(rn->info);

		if (rn->info) {
			rn->info = NULL;
			route_unlock_node(rn);
		} else
			zlog_info("Can't find neighbor %s in the interface %s",
				  inet_ntoa(nbr->src), IF_NAME(oi));

		route_unlock_node(rn);
	}

	/* Free ospf_neighbor structure. */
	ospf_nbr_free(nbr);
}
Пример #6
0
void
dump_iproute(void *rt_data)
{
	ip_route_t *route = rt_data;
	char *log_msg = MALLOC(1024);
	char *op = log_msg;

	if (route->blackhole) {
		strncat(log_msg, "blackhole ", 30);
	}
	if (route->dst)
		op += snprintf(op, log_msg + 1024 - op, "%s/%d", ipaddresstos(NULL, route->dst), route->dmask);
	if (route->gw)
		op += snprintf(op, log_msg + 1024 - op, " gw %s", ipaddresstos(NULL, route->gw));
	if (route->gw2)
		op += snprintf(op, log_msg + 1024 - op, " or gw %s", ipaddresstos(NULL, route->gw2));
	if (route->src)
		op += snprintf(op, log_msg + 1024 - op, " src %s", ipaddresstos(NULL, route->src));
	if (route->index)
		op += snprintf(op, log_msg + 1024 - op, " dev %s",
			 IF_NAME(if_get_by_ifindex(route->index)));
	if (route->table)
		op += snprintf(op, log_msg + 1024 - op, " table %d", route->table);
	if (route->scope)
		op += snprintf(op, log_msg + 1024 - op, " scope %s",
			 netlink_scope_n2a(route->scope));
	if (route->metric)
		op += snprintf(op, log_msg + 1024 - op, " metric %d", route->metric);

	log_message(LOG_INFO, "     %s", log_msg);

	FREE(log_msg);
}
Пример #7
0
static void
route_print(FILE *file, void *data)
{
	ip_route_t *route = data;

	fprintf(file, "     ");

	if (route->blackhole)
		fprintf(file, "blackhole ");
	if (route->dst)
		fprintf(file, "%s/%d", ipaddresstos(NULL, route->dst), route->dmask);
	if (route->gw)
		fprintf(file, " gw %s", ipaddresstos(NULL, route->gw));
	if (route->gw2)
		fprintf(file, " or gw %s", ipaddresstos(NULL, route->gw2));
	if (route->src)
		fprintf(file, " src %s", ipaddresstos(NULL, route->src));
	if (route->index)
		fprintf(file, " dev %s", IF_NAME(if_get_by_ifindex(route->index)));
	if (route->table)
		fprintf(file, " table %d", route->table);
	if (route->scope)
		fprintf(file, " scope %s", netlink_scope_n2a(route->scope));
	if (route->metric)
		fprintf(file, " metric %d", route->metric);

	fprintf(file, "\n");
}
Пример #8
0
static void
address_print(FILE *file, void *data)
{
	ip_address_t *ipaddr = data;
	char broadcast[INET_ADDRSTRLEN + 5] = "";	/* allow for " brd " */
	char addr_str[INET6_ADDRSTRLEN] = "";

	if (IP_IS6(ipaddr)) {
		inet_ntop(AF_INET6, &ipaddr->u.sin6_addr, addr_str, sizeof(addr_str));
	} else {
		inet_ntop(AF_INET, &ipaddr->u.sin.sin_addr, addr_str, sizeof(addr_str));
	if (ipaddr->u.sin.sin_brd.s_addr)
		snprintf(broadcast, sizeof(broadcast) - 1, " brd %s",
			 inet_ntop2(ipaddr->u.sin.sin_brd.s_addr));
	}

	fprintf(file, "     %s/%d%s dev %s%s%s%s%s\n"
		, addr_str
		, ipaddr->ifa.ifa_prefixlen
		, broadcast
		, IF_NAME(ipaddr->ifp)
		, IP_IS4(ipaddr) ? " scope " : ""
		, IP_IS4(ipaddr) ? netlink_scope_n2a(ipaddr->ifa.ifa_scope) : ""
		, ipaddr->label ? " label " : ""
		, ipaddr->label ? ipaddr->label : "");
}
Пример #9
0
int
nsm_kill_nbr (struct ospf_neighbor *nbr)
{
  /* call it here because we cannot call it from ospf_nsm_event */
  nsm_change_status (nbr, NSM_Down);
  
  /* Reset neighbor. */
  nsm_reset_nbr (nbr);

  if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_static != NULL)
    {
      struct ospf_nbr_static *nbr_static = nbr->nbr_static;

      nbr_static->neighbor = NULL;
      nbr_static->state_change = nbr->state_change;

      nbr->nbr_static = NULL;

      OSPF_POLL_TIMER_ON (nbr_static->t_poll, ospf_poll_timer,
			  nbr_static->v_poll);

      if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
	zlog_info ("NSM[%s:%s]: Down (PollIntervalTimer scheduled)",
		   IF_NAME (nbr->oi),
		   inet_ntoa (nbr->address.u.prefix4));  
    }

  /* Delete neighbor from interface. */
  ospf_nbr_delete (nbr);

  return 0;
}
Пример #10
0
/* Delete specified OSPF neighbor from interface. */
void
ospf_nbr_delete (struct ospf_neighbor *nbr)
{
  struct ospf_interface *oi;
  struct route_node *rn;
  struct prefix p;

  oi = nbr->oi;

  /* Unlink ospf neighbor from the interface. */
  p.family = AF_INET;
  p.prefixlen = IPV4_MAX_BITLEN;
  p.u.prefix4 = nbr->src;

  rn = route_node_lookup (oi->nbrs, &p);
  if (rn)
    {
      if (rn->info)
	{
	  rn->info = NULL;
	  route_unlock_node (rn);
	}
      else
	zlog_info ("Can't find neighbor %s in the interface %s",
		   inet_ntoa (nbr->src), IF_NAME (oi));

      route_unlock_node (rn);
    }

  /* Free ospf_neighbor structure. */
  ospf_nbr_free (nbr);
}
Пример #11
0
/* Execute ISM event process. */
int
ospf_ism_event (struct thread *thread)
{
  int event;
  int next_state;
  struct ospf_interface *oi;

  oi = THREAD_ARG (thread);
  event = THREAD_VAL (thread);

  /* Call function. */
  next_state = (*(ISM [oi->state][event].func))(oi);

  if (! next_state)
    next_state = ISM [oi->state][event].next_state;

  if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: %s (%s)", IF_NAME (oi),
	  LOOKUP (ospf_ism_state_msg, oi->state),
	  ospf_ism_event_str[event]);

  /* If state is changed. */
  if (next_state != oi->state)
    ism_change_state (oi, next_state);

  /* Make sure timer is set. */
  ism_timer_set (oi);

  return 0;
}
Пример #12
0
static int
nsm_kill_nbr (struct ospf_neighbor *nbr)
{
  /* killing nbr_self is invalid */
  if (nbr == nbr->oi->nbr_self)
    {
      assert (nbr != nbr->oi->nbr_self);
      return 0;
    }
  
  if (nbr->oi->type == OSPF_IFTYPE_NBMA && nbr->nbr_nbma != NULL)
    {
      struct ospf_nbr_nbma *nbr_nbma = nbr->nbr_nbma;

      nbr_nbma->nbr = NULL;
      nbr_nbma->state_change = nbr->state_change;

      nbr->nbr_nbma = NULL;

      OSPF_POLL_TIMER_ON (nbr_nbma->t_poll, ospf_poll_timer,
			  nbr_nbma->v_poll);

      if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
	zlog_debug ("NSM[%s:%s]: Down (PollIntervalTimer scheduled)",
		   IF_NAME (nbr->oi), inet_ntoa (nbr->address.u.prefix4));  
    }

  return 0;
}
Пример #13
0
void
dump_iproute(void *rt_data)
{
	ip_route_t *route = rt_data;
	char *log_msg = MALLOC(1024);
	char *tmp = MALLOC(INET6_ADDRSTRLEN + 30);
	char *tmp_str;

	if (route->blackhole) {
		strncat(log_msg, "blackhole ", 30);
	}
	if (route->dst) {
		tmp_str = ipaddresstos(route->dst);
		snprintf(tmp, INET6_ADDRSTRLEN + 30, "%s/%d", tmp_str, route->dmask);
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
		FREE(tmp_str);
	}
	if (route->gw) {
		tmp_str = ipaddresstos(route->gw);
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " gw %s", tmp_str);
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
		FREE(tmp_str);
	}
	if (route->gw2) {
		tmp_str = ipaddresstos(route->gw2);
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " or gw %s", tmp_str);
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
		FREE(tmp_str);
	}
	if (route->src) {
		tmp_str = ipaddresstos(route->src);
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " src %s", tmp_str);
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
		FREE(tmp_str);
	}
	if (route->index) {
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " dev %s",
			 IF_NAME(if_get_by_ifindex(route->index)));
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
	}
	if (route->table) {
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " table %d", route->table);
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
	}
	if (route->scope) {
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " scope %s",
			 netlink_scope_n2a(route->scope));
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
	}
	if (route->metric) {
		snprintf(tmp, INET6_ADDRSTRLEN + 30, " metric %d", route->metric);
		strncat(log_msg, tmp, INET6_ADDRSTRLEN + 30);
	}

	log_message(LOG_INFO, "     %s", log_msg);

	FREE(tmp);
	FREE(log_msg);
}
Пример #14
0
static void vrrp_log_int_up(vrrp_t *vrrp)
{
	if (IF_ISUP(vrrp->ifp))
		log_message(LOG_INFO, "Kernel is reporting: interface %s UP",
		       IF_NAME(vrrp->ifp));
	if (!LIST_ISEMPTY(vrrp->track_ifp))
		log_message(LOG_INFO, "Kernel is reporting: tracked interface are UP");
}
Пример #15
0
static int
ism_ignore (struct ospf_interface *oi)
{
  if (IS_DEBUG_OSPF (ism, ISM_EVENTS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: ism_ignore called", IF_NAME (oi));

  return 0;
}
Пример #16
0
/* Log interface message */
static void vrrp_log_int_down(vrrp_t *vrrp)
{
	if (!IF_ISUP(vrrp->ifp))
		log_message(LOG_INFO, "Kernel is reporting: interface %s DOWN",
		       IF_NAME(vrrp->ifp));
	if (!LIST_ISEMPTY(vrrp->track_ifp))
		vrrp_log_tracked_down(vrrp->track_ifp);
}
Пример #17
0
void
ism_change_state (struct ospf_interface *oi, int state)
{
  int old_state;
  struct ospf_lsa *lsa;

  /* Logging change of state. */
  if (IS_DEBUG_OSPF (ism, ISM_STATUS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: State change %s -> %s", IF_NAME (oi),
	  LOOKUP (ospf_ism_state_msg, oi->state),
	  LOOKUP (ospf_ism_state_msg, state));

  old_state = oi->state;
  oi->state = state;
  oi->state_change++;

  if (old_state == ISM_Down || state == ISM_Down)
    ospf_check_abr_status (oi->ospf);

  /* Originate router-LSA. */
  if (oi->area)
    {
      if (state == ISM_Down)
	{
	  if (oi->area->act_ints > 0)
	    oi->area->act_ints--;
	}
      else if (old_state == ISM_Down)
	oi->area->act_ints++;

      /* schedule router-LSA originate. */
      ospf_router_lsa_timer_add (oi->area);
    }

  /* Originate network-LSA. */
  if (old_state != ISM_DR && state == ISM_DR)
    ospf_network_lsa_timer_add (oi);
  else if (old_state == ISM_DR && state != ISM_DR)
    {
      /* Free self originated network LSA. */
      lsa = oi->network_lsa_self;
      if (lsa)
	{
	  ospf_lsa_flush_area (lsa, oi->area);
	  OSPF_TIMER_OFF (oi->t_network_lsa_self);
	}

      ospf_lsa_unlock (oi->network_lsa_self);
      oi->network_lsa_self = NULL;
    }

#ifdef HAVE_OPAQUE_LSA
  ospf_opaque_ism_change (oi, old_state);
#endif /* HAVE_OPAQUE_LSA */

  /* Check area border status.  */
  ospf_check_abr_status (oi->ospf);
}
Пример #18
0
/* OSPF NSM functions. */
int
nsm_ignore (struct ospf_neighbor *nbr)
{
  if (IS_DEBUG_OSPF (nsm, NSM_EVENTS))
    zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: nsm_ignore called",
	  IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));

  return 0;
}
Пример #19
0
void
ism_change_status (struct ospf_interface *oi, int status)
{
  int old_status;
  struct ospf_lsa *lsa;

  /* Logging change of status. */
  if (IS_DEBUG_OSPF (ism, ISM_STATUS))
    zlog (NULL, LOG_INFO, "ISM[%s]: Status change %s -> %s", IF_NAME (oi),
	  LOOKUP (ospf_ism_status_msg, oi->status),
	  LOOKUP (ospf_ism_status_msg, status));

  old_status = oi->status;
  oi->status = status;
  oi->status_change++;

  if (old_status == ISM_Down || status == NSM_Down)
    ospf_check_abr_status();

  /* Originate router-LSA. */
  if (oi->area)
    {
      if (status == ISM_Down)
	{
	  if (oi->area->act_ints > 0)
	    oi->area->act_ints--;
	}
      else if (old_status == ISM_Down)
	oi->area->act_ints++;

      /* schedule router-LSA originate. */
      ospf_router_lsa_timer_add (oi->area);
    }

  /* Originate network-LSA. */
  if (old_status != ISM_DR && status == ISM_DR)
    ospf_network_lsa_timer_add (oi);
  else if (old_status == ISM_DR && status != ISM_DR)
    {
      /* Free self originated network LSA. */
      lsa = oi->network_lsa_self;
      if (lsa)
	{
	  ospf_lsa_flush_area (lsa, oi->area);
	  OSPF_TIMER_OFF (oi->t_network_lsa_self);
	}

      ospf_lsa_unlock (oi->network_lsa_self);
      oi->network_lsa_self = NULL;
    }

  /* Preserve old status? */

  /* Check area border status.  */
  ospf_check_abr_status ();
}
Пример #20
0
void
route_print(FILE *file, void *data)
{
	ip_route_t *route = data;
	char *msg = MALLOC(150);
	char *tmp = MALLOC(30);

	if (route->blackhole) {
		strncat(msg, "blackhole ", 30);
	}
	if (route->dst) {
		snprintf(tmp, 30, "%s/%d", ipaddresstos(route->dst),
			route->dmask);
		strncat(msg, tmp, 30);
	}
	if (route->gw) {
		snprintf(tmp, 30, " gw %s", ipaddresstos(route->gw));
		strncat(msg, tmp, 30);
	}
	if (route->gw2) {
		snprintf(tmp, 30, " or gw %s", ipaddresstos(route->gw2));
		strncat(msg, tmp, 30);
	}
	if (route->src) {
		snprintf(tmp, 30, " src %s", ipaddresstos(route->src));
		strncat(msg, tmp, 30);
	}
	if (route->index) {
		snprintf(tmp, 30, " dev %s",
		  IF_NAME(if_get_by_ifindex(route->index)));
		strncat(msg, tmp, 30);
	}
	if (route->table) {
		snprintf(tmp, 30, " table %d", route->table);
		strncat(msg, tmp, 30);
	}
	if (route->scope) {
		snprintf(tmp, 30, " scope %s",
		  netlink_scope_n2a(route->scope));
		strncat(msg, tmp, 30);
	}
	if (route->metric) {
		snprintf(tmp, 30, " metric %d", route->metric);
		strncat(msg, tmp, 30);
	}

	fprintf(file, "     %s\n", msg);

	FREE(tmp);
	FREE(msg);

}
Пример #21
0
/* Log tracked interface down */
void
vrrp_log_tracked_down(list l)
{
	element e;
	tracked_if *tip;

	for (e = LIST_HEAD(l); e; ELEMENT_NEXT(e)) {
		tip = ELEMENT_DATA(e);
		if (!IF_ISUP(tip->ifp))
			log_message(LOG_INFO, "Kernel is reporting: interface %s DOWN",
			       IF_NAME(tip->ifp));
	}
}
Пример #22
0
static int ospf_wait_timer(struct thread *thread)
{
	struct ospf_interface *oi;

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

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

	OSPF_ISM_EVENT_SCHEDULE(oi, ISM_WaitTimer);

	return 0;
}
Пример #23
0
/* OSPF NSM Timer functions. */
int
ospf_inactivity_timer (struct thread *thread)
{
  struct ospf_neighbor *nbr;

  nbr = THREAD_ARG (thread);
  nbr->t_inactivity = NULL;

  if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
    zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (Inactivity timer expire)",
	  IF_NAME (nbr->oi), inet_ntoa (nbr->router_id));

  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_InactivityTimer);

  return 0;
}
Пример #24
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_HELLO_TIMER_ON(oi);

	return 0;
}
Пример #25
0
static struct ospf_neighbor *
ospf_nbr_add (struct ospf_interface *oi, struct ospf_header *ospfh,
              struct prefix *p)
{
  struct ospf_neighbor *nbr;
  
  nbr = ospf_nbr_new (oi);
  nbr->state = NSM_Down;
  nbr->src = p->u.prefix4;
  memcpy (&nbr->address, p, sizeof (struct prefix));

  nbr->nbr_nbma = NULL;
  if (oi->type == OSPF_IFTYPE_NBMA)
    {
      struct ospf_nbr_nbma *nbr_nbma;
      struct listnode *node;

      for (ALL_LIST_ELEMENTS_RO (oi->nbr_nbma, node, nbr_nbma))
        {
          if (IPV4_ADDR_SAME(&nbr_nbma->addr, &nbr->src))
            {
              nbr_nbma->nbr = nbr;
              nbr->nbr_nbma = nbr_nbma;

              if (nbr_nbma->t_poll)
                OSPF_POLL_TIMER_OFF (nbr_nbma->t_poll);

              nbr->state_change = nbr_nbma->state_change + 1;
            }
        }
    }
      
  /* New nbr, save the crypto sequence number if necessary */
  if (ntohs (ospfh->auth_type) == OSPF_AUTH_CRYPTOGRAPHIC)
    nbr->crypt_seqnum = ospfh->u.crypt.crypt_seqnum;
  
  if (IS_DEBUG_OSPF_EVENT)
    zlog_debug ("NSM[%s:%s]: start", IF_NAME (nbr->oi),
               inet_ntoa (nbr->router_id));
  
  return nbr;
}
Пример #26
0
/* Send the gratuitous ARP message */
static int send_arp(ip_address_t *ipaddress)
{
	struct sockaddr_ll sll;
	int len;

	/* Build the dst device */
	memset(&sll, 0, sizeof(sll));
	sll.sll_family = AF_PACKET;
	memcpy(sll.sll_addr, IF_HWADDR(ipaddress->ifp), ETH_ALEN);
	sll.sll_halen = ETHERNET_HW_LEN;
	sll.sll_ifindex = IF_INDEX(ipaddress->ifp);

	/* Send packet */
	len = sendto(garp_fd, garp_buffer, sizeof(arphdr_t) + ETHER_HDR_LEN
		     , 0, (struct sockaddr *)&sll, sizeof(sll));
	if (len < 0)
		log_message(LOG_INFO, "Error sending gratuitous ARP on %s for %s",
			    IF_NAME(ipaddress->ifp), inet_ntop2(ipaddress->u.sin.sin_addr.s_addr));
	return len;
}
Пример #27
0
void
dump_ipaddress(void *if_data)
{
	ip_address_t *ipaddr = if_data;
	char broadcast[INET_ADDRSTRLEN + 5] = "";

	if (!IP_IS6(ipaddr) && ipaddr->u.sin.sin_brd.s_addr) {
		snprintf(broadcast, 21, " brd %s",
			 inet_ntop2(ipaddr->u.sin.sin_brd.s_addr));
	}

	log_message(LOG_INFO, "     %s/%d%s dev %s scope %s%s%s"
			    , ipaddresstos(NULL, ipaddr)
			    , ipaddr->ifa.ifa_prefixlen
			    , broadcast
			    , IF_NAME(ipaddr->ifp)
			    , get_rttables_scope(ipaddr->ifa.ifa_scope)
			    , ipaddr->label ? " label " : ""
			    , ipaddr->label ? ipaddr->label : "");
}
Пример #28
0
static int
ospf_db_desc_timer (struct thread *thread)
{
  struct ospf_neighbor *nbr;

  nbr = THREAD_ARG (thread);
  nbr->t_db_desc = NULL;

  if (IS_DEBUG_OSPF (nsm, NSM_TIMERS))
    zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (DD Retransmit timer expire)",
	  IF_NAME (nbr->oi), inet_ntoa (nbr->src));

  /* resent last send DD packet. */
  assert (nbr->last_send);
  ospf_db_desc_resend (nbr);

  /* DD Retransmit timer set. */
  OSPF_NSM_TIMER_ON (nbr->t_db_desc, ospf_db_desc_timer, nbr->v_db_desc);

  return 0;
}
Пример #29
0
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? */
}
Пример #30
0
static void
ism_change_state (struct ospf_interface *oi, int state)
{
  int old_state;
  struct ospf_lsa *lsa;

  /* Logging change of state. */
  if (IS_DEBUG_OSPF (ism, ISM_STATUS))
    zlog (NULL, LOG_DEBUG, "ISM[%s]: State change %s -> %s", IF_NAME (oi),
	  LOOKUP (ospf_ism_state_msg, oi->state),
	  LOOKUP (ospf_ism_state_msg, state));

  old_state = oi->state;
  oi->state = state;
  oi->state_change++;

#ifdef HAVE_SNMP
  /* Terminal state or regression */ 
  if ((state == ISM_DR) || (state == ISM_Backup) || (state == ISM_DROther) ||
      (state == ISM_PointToPoint) || (state < old_state))
    {
      /* ospfVirtIfStateChange */
      if (oi->type == OSPF_IFTYPE_VIRTUALLINK)
        ospfTrapVirtIfStateChange (oi);
      /* ospfIfStateChange */
      else
        ospfTrapIfStateChange (oi);
    }
#endif

  /* Set multicast memberships appropriately for new state. */
  ospf_if_set_multicast(oi);

  if (old_state == ISM_Down || state == ISM_Down)
    ospf_check_abr_status (oi->ospf);

  /* Originate router-LSA. */
  if (state == ISM_Down)
    {
      if (oi->area->act_ints > 0)
        oi->area->act_ints--;
    }
  else if (old_state == ISM_Down)
    oi->area->act_ints++;

  /* schedule router-LSA originate. */
  ospf_router_lsa_update_area (oi->area);

  /* Originate network-LSA. */
  if (old_state != ISM_DR && state == ISM_DR)
    ospf_network_lsa_update (oi);
  else if (old_state == ISM_DR && state != ISM_DR)
    {
      /* Free self originated network LSA. */
      lsa = oi->network_lsa_self;
      if (lsa)
        ospf_lsa_flush_area (lsa, oi->area);

      ospf_lsa_unlock (&oi->network_lsa_self);
      oi->network_lsa_self = NULL;
    }

  ospf_opaque_ism_change (oi, old_state);

  /* Check area border status.  */
  ospf_check_abr_status (oi->ospf);
}