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; }
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; }
/* * 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; }