예제 #1
0
/*
 * Add this IS to the root of SPT
 */
static void
isis_spf_add_self (struct isis_spftree *spftree, struct isis_area *area,
		   int level)
{
  struct isis_vertex *vertex;
  struct isis_lsp *lsp;
  u_char lspid[ISIS_SYS_ID_LEN + 2];
  memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN);
  LSP_PSEUDO_ID (lspid) = 0;
  LSP_FRAGMENT (lspid) = 0;

  lsp = lsp_search (lspid, area->lspdb[level - 1]);

  if (lsp == NULL)
    Log(LOG_WARNING, "WARN ( default/core/ISIS ): ISIS-Spf: could not find own l%d LSP!\n", level);

  if (!area->oldmetric)
    vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_TE_IS);
  else 
    vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_IS);

  vertex->lsp = lsp;

  listnode_add (spftree->paths, vertex);

  return;
}
예제 #2
0
/* 
 * Find the system LSP: returns the LSP in our LSP database 
 * associated with the given system ID.
 */
static struct isis_lsp *
isis_root_system_lsp (struct isis_area *area, int level, u_char *sysid)
{
  struct isis_lsp *lsp;
  u_char lspid[ISIS_SYS_ID_LEN + 2];

  memcpy (lspid, sysid, ISIS_SYS_ID_LEN);
  LSP_PSEUDO_ID (lspid) = 0;
  LSP_FRAGMENT (lspid) = 0;
  lsp = lsp_search (lspid, area->lspdb[level - 1]);
  if (lsp && lsp->lsp_header->rem_lifetime != 0)
    return lsp;
  return NULL;
}
예제 #3
0
/*
 * Add this IS to the root of SPT
 */
static void
isis_spf_add_self (struct isis_spftree *spftree, struct isis_area *area,
		   int level)
{
  struct isis_vertex *vertex;
  struct isis_lsp *lsp;
  u_char lspid[ISIS_SYS_ID_LEN + 2];
#ifdef EXTREME_DEBUG
  u_char buff[BUFSIZ];
#endif /* EXTREME_DEBUG */
  memcpy (lspid, isis->sysid, ISIS_SYS_ID_LEN);
  LSP_PSEUDO_ID (lspid) = 0;
  LSP_FRAGMENT (lspid) = 0;

  lsp = lsp_search (lspid, area->lspdb[level - 1]);

  if (lsp == NULL)
    zlog_warn ("ISIS-Spf: could not find own l%d LSP!", level);

  if (!area->oldmetric)
    vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_TE_IS);
  else
    vertex = isis_vertex_new (isis->sysid, VTYPE_NONPSEUDO_IS);

  vertex->lsp = lsp;

  listnode_add (spftree->paths, vertex);

#ifdef EXTREME_DEBUG
  zlog_debug ("ISIS-Spf: added this IS  %s %s depth %d dist %d to PATHS",
	      vtype2string (vertex->type), vid2string (vertex, buff),
	      vertex->depth, vertex->d_N);
#endif /* EXTREME_DEBUG */

  return;
}
예제 #4
0
/*
 * C.2.6 Step 1
 */
static int
isis_spf_process_lsp (struct isis_spftree *spftree, struct isis_lsp *lsp,
		      uint32_t cost, uint16_t depth, int family)
{
  struct listnode *node, *fragnode = NULL;
  u_int16_t dist;
  struct is_neigh *is_neigh;
  struct te_is_neigh *te_is_neigh;
  struct ipv4_reachability *ipreach;
  struct te_ipv4_reachability *te_ipv4_reach;
  enum vertextype vtype;
  struct prefix prefix;
#ifdef HAVE_IPV6
  struct ipv6_reachability *ip6reach;
#endif /* HAVE_IPV6 */


  if (!lsp->adj)
    return ISIS_WARNING;
  if (lsp->tlv_data.nlpids == NULL || !speaks (lsp->tlv_data.nlpids, family))
    return ISIS_OK;

lspfragloop:
  if (lsp->lsp_header->seq_num == 0)
    {
      zlog_warn ("isis_spf_process_lsp(): lsp with 0 seq_num"
		 " - do not process");
      return ISIS_WARNING;
    }

  if (!ISIS_MASK_LSP_OL_BIT (lsp->lsp_header->lsp_bits))
    {
      if (lsp->tlv_data.is_neighs)
	{
          for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.is_neighs, node, is_neigh))
	    {
	      /* C.2.6 a) */
	      /* Two way connectivity */
	      if (!memcmp (is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN))
		continue;
	      dist = cost + is_neigh->metrics.metric_default;
	      vtype = LSP_PSEUDO_ID (is_neigh->neigh_id) ? VTYPE_PSEUDO_IS
		: VTYPE_NONPSEUDO_IS;
	      process_N (spftree, vtype, (void *) is_neigh->neigh_id, dist,
			 depth + 1, lsp->adj, family);
	    }
	}
      if (lsp->tlv_data.te_is_neighs)
	{
	  for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.te_is_neighs, node,
				     te_is_neigh))
	    {
	      uint32_t metric;
	      if (!memcmp (te_is_neigh->neigh_id, isis->sysid, ISIS_SYS_ID_LEN))
		continue;
	      memcpy (&metric, te_is_neigh->te_metric, 3);
	      dist = cost + ntohl (metric << 8);
	      vtype = LSP_PSEUDO_ID (te_is_neigh->neigh_id) ? VTYPE_PSEUDO_TE_IS
		: VTYPE_NONPSEUDO_TE_IS;
	      process_N (spftree, vtype, (void *) te_is_neigh->neigh_id, dist,
			 depth + 1, lsp->adj, family);
	    }
	}
      if (family == AF_INET && lsp->tlv_data.ipv4_int_reachs)
	{
	  prefix.family = AF_INET;
          for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_int_reachs, 
                                     node, ipreach))
	    {
	      dist = cost + ipreach->metrics.metric_default;
	      vtype = VTYPE_IPREACH_INTERNAL;
	      prefix.u.prefix4 = ipreach->prefix;
	      prefix.prefixlen = ip_masklen (ipreach->mask);
	      process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
			 lsp->adj, family);
	    }
	}

      if (family == AF_INET && lsp->tlv_data.ipv4_ext_reachs)
	{
	  prefix.family = AF_INET;
          for (ALL_LIST_ELEMENTS_RO (lsp->tlv_data.ipv4_ext_reachs,
                                     node, ipreach))
	    {
	      dist = cost + ipreach->metrics.metric_default;
	      vtype = VTYPE_IPREACH_EXTERNAL;
	      prefix.u.prefix4 = ipreach->prefix;
	      prefix.prefixlen = ip_masklen (ipreach->mask);
	      process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
			 lsp->adj, family);
	    }
	}