Example #1
0
struct isis_adjacency *
isis_new_adj (u_char * id, u_char * snpa, int level,
	      struct isis_circuit *circuit)
{
  struct isis_adjacency *adj;
  int i;

  adj = adj_alloc (id);		/* P2P kludge */

  if (adj == NULL)
    {
      zlog_err ("Out of memory!");
      return NULL;
    }

  memcpy (adj->snpa, snpa, 6);
  adj->circuit = circuit;
  adj->level = level;
  adj->flaps = 0;
  adj->last_flap = time (NULL);
  if (circuit->circ_type == CIRCUIT_T_BROADCAST)
    {
      listnode_add (circuit->u.bc.adjdb[level - 1], adj);
      adj->dischanges[level - 1] = 0;
      for (i = 0; i < DIS_RECORDS; i++)	/* clear N DIS state change records */
	{
	  adj->dis_record[(i * ISIS_LEVELS) + level - 1].dis
	    = ISIS_UNKNOWN_DIS;
	  adj->dis_record[(i * ISIS_LEVELS) + level - 1].last_dis_change
	    = time (NULL);
	}
    }

  return adj;
}
Example #2
0
struct isis_adjacency *
isis_new_adj (u_char * id, u_char * snpa, int level,
	      struct isis_circuit *circuit)
{
  struct isis_adjacency *adj;
  int i;

  adj = adj_alloc (id);		/* P2P kludge */

  if (adj == NULL)
    {
      Log(LOG_ERR, "ERROR ( default/core/ISIS ): isis_new_adj() out of memory!\n");
      return NULL;
    }

  if (snpa) {
  memcpy (adj->snpa, snpa, 6);
  } else {
      memset (adj->snpa, ' ', 6);
  }

  adj->circuit = circuit;
  adj->level = level;
  adj->flaps = 0;
  adj->last_flap = time (NULL);

  return adj;
}
Example #3
0
/*
 * adj_mcast_add_or_lock
 *
 * The next_hop address here is used for source address selection in the DP.
 * The mcast adj is added to an interface's connected prefix, the next-hop
 * passed here is the local prefix on the same interface.
 */
adj_index_t
adj_mcast_add_or_lock (fib_protocol_t proto,
                       vnet_link_t link_type,
		       u32 sw_if_index)
{
    ip_adjacency_t * adj;

    vec_validate_init_empty(adj_mcasts[proto], sw_if_index, ADJ_INDEX_INVALID);

    if (ADJ_INDEX_INVALID == adj_mcasts[proto][sw_if_index])
    {
        vnet_main_t *vnm;

        vnm = vnet_get_main();
	adj = adj_alloc(proto);

	adj->lookup_next_index = IP_LOOKUP_NEXT_MCAST;
	adj->ia_nh_proto = proto;
	adj->ia_link = link_type;
	adj_mcasts[proto][sw_if_index] = adj_get_index(adj);
        adj_lock(adj_get_index(adj));

	vnet_rewrite_init(vnm, sw_if_index, link_type,
			  adj_get_mcast_node(proto),
			  vnet_tx_node_index_for_sw_interface(vnm, sw_if_index),
			  &adj->rewrite_header);

	/*
	 * we need a rewrite where the destination IP address is converted
	 * to the appropriate link-layer address. This is interface specific.
	 * So ask the interface to do it.
	 */
	vnet_update_adjacency_for_sw_interface(vnm, sw_if_index,
                                               adj_get_index(adj));
    }
    else
    {
	adj = adj_get(adj_mcasts[proto][sw_if_index]);
        adj_lock(adj_get_index(adj));
    }

    return (adj_get_index(adj));
}
void atomic_cycle_distribution(
    vtx_t const nvtxs, 
    adj_t const * const xadj, 
    vtx_t const * const adjncy, 
    adj_t * radj, 
    size_t ** const r_cycles, 
    vtx_t * const r_maxcycle)
{
  int free_radj;
  vtx_t i, k, v, m, sq, nq, si, ni, curlen, maxlen; 
  adj_t j, l;
  vtx_t * q, * qi, * len;
  int * vvisited, * evisited, * ivisited;
  size_t * cycles;

  adj_t const nedges = xadj[nvtxs];

  q = vtx_alloc(nvtxs);
  qi = vtx_alloc(nvtxs);
  vvisited = int_calloc(nvtxs);
  evisited = int_calloc(nedges);
  ivisited = int_calloc(nvtxs);
  cycles = size_alloc(dl_min(nvtxs,nedges));
  len = vtx_alloc(nvtxs);

  if (radj) {
    free_radj = 0;
  } else {
    radj = adj_alloc(nedges);
    build_adjncy_index(nvtxs,xadj,adjncy,radj);
    free_radj = 1;
  }

  maxlen = 0;
  cycles[0] = 0;

  /* seed the queue */
  sq = nq = 0;
  v = vtx_rand(0,nvtxs);
  q[nq++] = v;
  vvisited[v] = 1;

  /* algorithm from Gashler and Martinez 2012 */
  while (sq < nq) {
    v = q[sq++];
    for (j=xadj[v];j<xadj[v+1];++j) {
      k = adjncy[j];
      if (vvisited[k]) {
        len[k] = 1;
        si = ni = 0;
        qi[ni++] = k;
        ivisited[k] = 1;
        while (si < ni) {
          i = qi[si++];
          for (l=xadj[i];l<xadj[i+1];++l) {
            m = adjncy[l];
            if (!ivisited[m] && evisited[l]) {
              len[m] = len[i]+1;
              qi[ni++] = m;
              ivisited[m] = 1;
              if (m == v) {
                curlen = len[m];
                /* zero out new cycle lengths */
                while (curlen > maxlen) {
                  cycles[++maxlen] = 0;
                }
                ++cycles[curlen];
                /* I might need to break here */
                si = ni;
                break;
              }
            }
          }
        }
        /* clear ivisited */
        if (ni < nvtxs/64) {
          for (i=0;i<ni;++i) {
            ivisited[qi[i]] = 0;
          }
        } else {
          int_set(ivisited,0,nvtxs);
        }
      } else {
        q[nq++] = k;
        vvisited[k] = 1;
      }
      evisited[j] = 1;
      evisited[radj[j]] = 1;
    }
  }

  /* hack to ignore length 2 cycles */
  cycles[2] = 0;
  
  if (r_maxcycle) {
    *r_maxcycle = maxlen;
  }

  if (r_cycles) {
    *r_cycles = cycles;
  }

  if (free_radj) {
    dl_free(radj);
  }
}
size_t count_triangles(
    vtx_t const nvtxs, 
    adj_t const * const xadj, 
    vtx_t const * const adjncy,
    adj_t * radj)
{
  int free_radj;
  vtx_t i, k, kk, maxdeg, p;
  adj_t j,jj,r,ridx;
  size_t ntriangles;
  vtx_t * mark, * perm, * deg, * madjncy;

  adj_t const nedges = xadj[nvtxs];

  ntriangles = 0;

  if (radj) {
    free_radj = 0;
  } else {
    radj = adj_alloc(nedges);
    build_adjncy_index(nvtxs,xadj,adjncy,radj);
    free_radj = 1;
  }

  deg = vtx_alloc(nvtxs);
  mark = vtx_init_alloc(0,nvtxs);
  perm = vtx_init_alloc(0,nvtxs);
  madjncy = vtx_duplicate(adjncy,nedges);

  maxdeg = 0;
  for (i=0;i<nvtxs;++i) {
    deg[i] = xadj[i+1]-xadj[i];
    if (deg[i] > maxdeg) {
      maxdeg = deg[i];
    }
  }

  __countingsort_v(deg,perm,0,maxdeg,nvtxs);

  for (p=0;p<nvtxs;++p) {
    i = perm[p];
    /* mark all vertices adjacent to i */
    for (j=xadj[i];j<xadj[i]+deg[i];++j) {
      k = madjncy[j];
      mark[k] = 1;
    }
    for (j=xadj[i];j<xadj[i]+deg[i];++j) {
      k = madjncy[j];
      if (mark[k]) {
        for (jj=xadj[k];jj<xadj[k]+deg[k];++jj) {
          kk= madjncy[jj];
          if (mark[kk]) {
            ++ntriangles;
          }
        }
        mark[k] = 0;
      }
    }
    /* remove all edges pointing to i */
    for (j=xadj[i];j<xadj[i]+deg[i];++j) {
      k = madjncy[j];
      r = radj[j];
      ridx = xadj[k]+deg[k]-1;
      /* remove the edge */
      madjncy[r] = madjncy[ridx];
      /* update the radj vector */
      radj[r] = radj[ridx];
      /* update the remote radj vector */
      radj[radj[r]] = r;
      --deg[k];
    }
  }

  dl_free(madjncy);
  dl_free(mark);
  dl_free(deg);

  if (free_radj) {
    dl_free(radj);
  }

  return ntriangles;
}