Esempio n. 1
0
/* Utility function of convert between struct isis_prefix <=> union sockunion.
 * FIXME This function isn't used anywhere. */
struct isis_prefix *
sockunion2prefix (const union sockunion *dest,
		  const union sockunion *mask)
{
  if (dest->sa.sa_family == AF_INET)
    {
      struct prefix_ipv4 *p;

      p = isis_prefix_ipv4_new ();
      p->family = AF_INET;
      p->prefix = dest->sin.sin_addr;
      p->prefixlen = isis_ip_masklen (mask->sin.sin_addr);
      return (struct isis_prefix *) p;
    }
#ifdef ENABLE_IPV6
  if (dest->sa.sa_family == AF_INET6)
    {
      struct prefix_ipv6 *p;

      p = isis_prefix_ipv6_new ();
      p->family = AF_INET6;
      p->prefixlen = isis_ip6_masklen (mask->sin6.sin6_addr);
      memcpy (&p->prefix, &dest->sin6.sin6_addr, sizeof (struct in6_addr));
      return (struct isis_prefix *) p;
    }
#endif /* ENABLE_IPV6 */
  return NULL;
}
Esempio n. 2
0
/* Utility function to convert ipv4 netmask to prefixes 
   ex.) "1.1.0.0" "255.255.0.0" => "1.1.0.0/16"
   ex.) "1.0.0.0" NULL => "1.0.0.0/8"                   */
int
netmask_isis_str2prefix_str (const char *net_str, const char *mask_str,
			char *prefix_str)
{
  struct in_addr network;
  struct in_addr mask;
  u_char prefixlen;
  u_int32_t destination;
  int ret;

  ret = inet_aton (net_str, &network);
  if (! ret)
    return 0;

  if (mask_str)
    {
      ret = inet_aton (mask_str, &mask);
      if (! ret)
        return 0;

      prefixlen = isis_ip_masklen (mask);
    }
  else 
    {
      destination = ntohl (network.s_addr);

      if (network.s_addr == 0)
	prefixlen = 0;
      else if (IN_CLASSC (destination))
	prefixlen = 24;
      else if (IN_CLASSB (destination))
	prefixlen = 16;
      else if (IN_CLASSA (destination))
	prefixlen = 8;
      else
	return 0;
    }

  sprintf (prefix_str, "%s/%d", net_str, prefixlen);

  return 1;
}
Esempio n. 3
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 isis_prefix prefix;
#ifdef ENABLE_IPV6
  struct ipv6_reachability *ip6reach;
#endif /* ENABLE_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)
    {
      Log(LOG_WARNING, "WARN ( default/core/ISIS ): isis_spf_process_lsp(): lsp with 0 seq_num - do not process\n");
      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 = isis_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;

              /* Set advertising router to the first IP address */
              if (lsp->tlv_data.ipv4_addrs) {
                memcpy(&prefix.adv_router, listnode_head(lsp->tlv_data.ipv4_addrs), sizeof(struct in_addr));
              }
	      prefix.u.prefix4 = ipreach->prefix;
	      prefix.prefixlen = isis_ip_masklen (ipreach->mask);
	      process_N (spftree, vtype, (void *) &prefix, dist, depth + 1,
			 lsp->adj, family);
	    }
	}