Beispiel #1
0
/* 7.2.7 */
static void
remove_excess_adjs (struct list *adjs)
{
  struct listnode *node, *excess = NULL;
  struct isis_adjacency *adj, *candidate = NULL;
  int comp;

  for (ALL_LIST_ELEMENTS_RO (adjs, node, adj)) 
    {
      if (excess == NULL)
	excess = node;
      candidate = listgetdata (excess);

      if (candidate->sys_type < adj->sys_type)
	{
	  excess = node;
	  candidate = adj;
	  continue;
	}
      if (candidate->sys_type > adj->sys_type)
	continue;

      comp = memcmp (candidate->sysid, adj->sysid, ISIS_SYS_ID_LEN);
      if (comp > 0)
	{
	  excess = node;
	  candidate = adj;
	  continue;
	}
      if (comp < 0)
	continue;

      if (candidate->circuit->circuit_id > adj->circuit->circuit_id)
	{
	  excess = node;
	  candidate = adj;
	  continue;
	}

      if (candidate->circuit->circuit_id < adj->circuit->circuit_id)
	continue;

      comp = memcmp (candidate->snpa, adj->snpa, ETH_ALEN);
      if (comp > 0)
	{
	  excess = node;
	  candidate = adj;
	  continue;
	}
    }

  list_delete_node (adjs, excess);

  return;
}
Beispiel #2
0
static int ldp_out_segment_read(int cmd, struct zclient *client,
    zebra_size_t size) {
    struct zapi_mpls_out_segment api;
    struct listnode *n;
    struct listnode *nn;
    mpls_outsegment *o;
    struct pending_ftn_data *fn;
    struct pending_xc_data *x;

    mpls_out_segment_stream_read(client->ibuf, &api);

    for (ALL_LIST_ELEMENTS(pending_out_segment, n, nn, o)) {
	if (api.req == o->handle) {
	    zlog_info("found pending NHLFE: %p", o);
	    o->handle = api.index;
	    list_delete_node(pending_out_segment,n);
	    goto ftn;
	}
    }
    zlog_info("requested out segment %d not in list", api.req);
    return 0;

ftn:
    /* if we've gotten this for then the o->handle is not the proper index */
    for (ALL_LIST_ELEMENTS(pending_ftn, n, nn, fn)) {
	if (api.index == fn->o->handle) {
	    mpls_mpls_fec2out_add(fn->h, fn->f, fn->o);
	    list_delete_node(pending_ftn,n);
	    break;
	}
    }
    for (ALL_LIST_ELEMENTS(pending_xc, n, nn, x)) {
	if (api.index == x->o->handle) {
	    mpls_mpls_xconnect_add(x->h, x->i, x->o);
	    list_delete_node(pending_xc,n);
	    break;
	}
    }
    return 0;
}
Beispiel #3
0
static void
isis_vertex_adj_del (struct isis_vertex *vertex, struct isis_adjacency *adj)
{
  struct listnode *node, *nextnode;
  if (!vertex)
    return;
  for (node = listhead (vertex->Adj_N); node; node = nextnode)
  {
    nextnode = listnextnode(node);
    if (listgetdata(node) == adj)
      list_delete_node(vertex->Adj_N, node);
  }
  return;
}
Beispiel #4
0
static void pim_vxlan_del_work(struct pim_vxlan_sg *vxlan_sg)
{
	if (!vxlan_sg->work_node)
		return;

	if (PIM_DEBUG_VXLAN)
		zlog_debug("vxlan SG %s work list del",
				vxlan_sg->sg_str);

	if (vxlan_sg->work_node == vxlan_info.next_work)
		vxlan_info.next_work = vxlan_sg->work_node->next;

	list_delete_node(vxlan_info.work_list, vxlan_sg->work_node);
	vxlan_sg->work_node = NULL;
}
Beispiel #5
0
/**
 * @param system a pointer to a  ppd_system struct that contains 
 * all the information for managing the system.
 * @return true when removing an item succeeds and false when it does not
 **/
BOOLEAN remove_item(struct ppd_system * system)
{
    char input[IDLEN + EXTRA_CHARS];
    BOOLEAN inputSuccess = FALSE;

    /**
     * Loop until ID in correct format is found, and the ID is found in the
     * linked list.
     **/
    printf("Press crtl + d or enter on a new line at any time to cancel.\n");
    printf("Please enter the ID of the item you wish to delete: ");
    while(!inputSuccess) {
        if(fgets(input, IDLEN + EXTRA_CHARS, stdin) == NULL) {
            printf("Returning to the menu.\n");
            return FALSE;
        }
        if (input[0] == '\n') {
            printf("Returning to the menu.\n");
            return FALSE;
        }
        else if(input[strlen(input)-1] != '\n') {
            printf("Error: input to long.\n");
            printf("Please enter the letter 'I' followed by 4 digits: ");
            read_rest_of_line();
            continue;
        }
        if(input[0] != 'I') {
            printf("Error: incorrect ID format\n");
            printf("Please enter the letter 'I' followed by 4 digits: ");
            continue;
        }
        input[strlen(input)-1] = '\0';
        if(list_delete_node(system->item_list, input) == FALSE) {
            printf("Please enter an existing ID: ");
            continue;
        }
        else {
            printf("Success! returning to the menu\n");
            return TRUE;
        }
    }

    return FALSE;
}
Beispiel #6
0
static int
dyn_cache_cleanup (struct thread *thread)
{
  struct listnode *node, *nnode;
  struct isis_dynhn *dyn;
  time_t now = time (NULL);

  isis->t_dync_clean = NULL;

  for (ALL_LIST_ELEMENTS (dyn_cache, node, nnode, dyn))
    {
      if ((now - dyn->refresh) < (MAX_AGE + 120))
	continue;

      list_delete_node (dyn_cache, node);
      XFREE (MTYPE_ISIS_DYNHN, dyn);
    }

  THREAD_TIMER_ON (master, isis->t_dync_clean, dyn_cache_cleanup, NULL, 120);
  return ISIS_OK;
}
Beispiel #7
0
/*******************************************************************************
 函数名称  : bgp_info_mpath_update
 功能描述  : mpath队列更新
 输入参数  : 
 输出参数  : 
 返 回 值  : 无
--------------------------------------------------------------------------------
 最近一次修改记录 :
 修改作者   :      
 修改目的   :      新添加函数
 修改日期   :       2012-8-15
*******************************************************************************/
void bgp_info_mpath_update (struct bgp_node *rn, struct bgp_info *new_best,
               struct bgp_info *old_best, struct list *mp_list, struct bgp_maxpaths_cfg *mpath_cfg)
{
	u16 maxpaths, mpath_count, old_mpath_count;
	struct listnode *mp_node, *mp_next_node;
	struct bgp_info *cur_mpath, *new_mpath, *next_mpath, *prev_mpath;
	s32 mpath_changed;
	
	mpath_changed = 0;
	maxpaths = BGP_DEFAULT_MAXPATHS;
	mpath_count = 0;
	cur_mpath = NULL;
	old_mpath_count = 0;
	prev_mpath = new_best;
	mp_node = listhead (mp_list);
	
	if (new_best)
    {
		mpath_count++;
		if (new_best != old_best)
		{
	        bgp_info_mpath_dequeue (new_best);
        }
		maxpaths = (peer_sort (new_best->peer) == BGP_PEER_IBGP) ?
		        mpath_cfg->maxpaths_ibgp : mpath_cfg->maxpaths_ebgp;
    }
    
	if (old_best)
	{
		cur_mpath = bgp_info_mpath_first (old_best);
		old_mpath_count = bgp_info_mpath_count (old_best);
		bgp_info_mpath_count_set (old_best, 0);
		bgp_info_mpath_dequeue (old_best);
	}

	while (mp_node || cur_mpath)
    {
		if (!cur_mpath && (mpath_count >= maxpaths))
		{
	        break;
		}
		mp_next_node = mp_node ? listnextnode (mp_node) : NULL;
		next_mpath = cur_mpath ? bgp_info_mpath_next (cur_mpath) : NULL;
		if (mp_node && (listgetdata (mp_node) == cur_mpath))
        {
			list_delete_node (mp_list, mp_node);
			bgp_info_mpath_dequeue (cur_mpath);
			if ((mpath_count < maxpaths) && bgp_info_nexthop_cmp (prev_mpath, cur_mpath))
	        {
				bgp_info_mpath_enqueue (prev_mpath, cur_mpath);
				prev_mpath = cur_mpath;
				mpath_count++;
	        }
			else
	        {
				mpath_changed = 1;
	        }
			mp_node = mp_next_node;
			cur_mpath = next_mpath;
			continue;
	    }
	    
		if (cur_mpath && (!mp_node || (bgp_info_mpath_cmp (cur_mpath, listgetdata (mp_node)) < 0)))
		{
			bgp_info_mpath_dequeue (cur_mpath);
			mpath_changed = 1;
			cur_mpath = next_mpath;
		}
		else
        {
			new_mpath = listgetdata (mp_node);
			list_delete_node (mp_list, mp_node);
			if ((mpath_count < maxpaths) && (new_mpath != new_best) &&
	              bgp_info_nexthop_cmp (prev_mpath, new_mpath))
	        {
				if (new_mpath == next_mpath)
				{
					next_mpath = bgp_info_mpath_next (new_mpath);
				}	
				bgp_info_mpath_dequeue (new_mpath);

				bgp_info_mpath_enqueue (prev_mpath, new_mpath);
				prev_mpath = new_mpath;
				mpath_changed = 1;
				mpath_count++;
            }
			mp_node = mp_next_node;
	    }
	}
	
	if (new_best)
	{
		bgp_info_mpath_count_set (new_best, mpath_count-1);
		if (mpath_changed || (bgp_info_mpath_count (new_best) != old_mpath_count))
		{
	        SET_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG);
        }
	}
}
Beispiel #8
0
/* Handle an interface delete event */
void 
if_delete_update (struct interface *ifp)
{
  struct connected *ifc;
  struct prefix *p;
  struct route_node *rn;
  struct zebra_if *zebra_if;

  zebra_if = ifp->info;

  if (if_is_up(ifp))
    {
      zlog_err ("interface %s index %d is still up while being deleted.",
	    ifp->name, ifp->ifindex);
      return;
    }

  /* Mark interface as inactive */
  UNSET_FLAG (ifp->status, ZEBRA_INTERFACE_ACTIVE);
  
  if (IS_ZEBRA_DEBUG_KERNEL)
    zlog_debug ("interface %s index %d is now inactive.",
	       ifp->name, ifp->ifindex);

  /* Delete connected routes from the kernel. */
  if (ifp->connected)
    {
      struct listnode *node;
      struct listnode *last = NULL;

      while ((node = (last ? last->next : listhead (ifp->connected))))
	{
	  ifc = listgetdata (node);
	  p = ifc->address;
	  
	  if (p->family == AF_INET
	      && (rn = route_node_lookup (zebra_if->ipv4_subnets, p)))
	    {
	      struct listnode *anode;
	      struct listnode *next;
	      struct listnode *first;
	      struct list *addr_list;
	      
	      route_unlock_node (rn);
	      addr_list = (struct list *) rn->info;
	      
	      /* Remove addresses, secondaries first. */
	      first = listhead (addr_list);
	      for (anode = first->next; anode || first; anode = next)
		{
		  if (!anode)
		    {
		      anode = first;
		      first = NULL;
		    }
		  next = anode->next;

		  ifc = listgetdata (anode);
		  p = ifc->address;

		  connected_down_ipv4 (ifp, ifc);

		  zebra_interface_address_delete_update (ifp, ifc);

		  UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);

		  /* Remove from subnet chain. */
		  list_delete_node (addr_list, anode);
		  route_unlock_node (rn);
		  
		  /* Remove from interface address list (unconditionally). */
		  if (!CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
		    {
		      listnode_delete (ifp->connected, ifc);
		      connected_free (ifc);
                    }
                  else
                    last = node;
		}

	      /* Free chain list and respective route node. */
	      list_delete (addr_list);
	      rn->info = NULL;
	      route_unlock_node (rn);
	    }
#ifdef HAVE_IPV6
	  else if (p->family == AF_INET6)
	    {
	      connected_down_ipv6 (ifp, ifc);

	      zebra_interface_address_delete_update (ifp, ifc);

	      UNSET_FLAG (ifc->conf, ZEBRA_IFC_REAL);

	      if (CHECK_FLAG (ifc->conf, ZEBRA_IFC_CONFIGURED))
		last = node;
	      else
		{
		  listnode_delete (ifp->connected, ifc);
		  connected_free (ifc);
		}
	    }
#endif /* HAVE_IPV6 */
	  else
	    {
	      last = node;
	    }
	}
    }
  zebra_interface_delete_update (ifp);

  /* Update ifindex after distributing the delete message.  This is in
     case any client needs to have the old value of ifindex available
     while processing the deletion.  Each client daemon is responsible
     for setting ifindex to IFINDEX_INTERNAL after processing the
     interface deletion message. */
  ifp->ifindex = IFINDEX_INTERNAL;
}
Beispiel #9
0
static void sssp_bfs(void) {
	avl_node_t *node, *next, *to;
	edge_t *e;
	node_t *n;
	list_t *todo_list;
	list_node_t *from, *todonext;
	bool indirect;
	char *name;
	char *address, *port;
	char *envp[7];
	int i;

	todo_list = list_alloc(NULL);

	/* Clear visited status on nodes */

	for(node = node_tree->head; node; node = node->next) {
		n = node->data;
		n->status.visited = false;
		n->status.indirect = true;
	}

	/* Begin with myself */

	myself->status.visited = true;
	myself->status.indirect = false;
	myself->nexthop = myself;
	myself->prevedge = NULL;
	myself->via = myself;
	list_insert_head(todo_list, myself);

	/* Loop while todo_list is filled */

	for(from = todo_list->head; from; from = todonext) {	/* "from" is the node from which we start */
		n = from->data;

		for(to = n->edge_tree->head; to; to = to->next) {	/* "to" is the edge connected to "from" */
			e = to->data;

			if(!e->reverse)
				continue;

			/* Situation:

				   /
				  /
			   ----->(n)---e-->(e->to)
				  \
				   \

			   Where e is an edge, (n) and (e->to) are nodes.
			   n->address is set to the e->address of the edge left of n to n.
			   We are currently examining the edge e right of n from n:

			   - If edge e provides for better reachability of e->to, update
			     e->to and (re)add it to the todo_list to (re)examine the reachability
			     of nodes behind it.
			 */

			indirect = n->status.indirect || e->options & OPTION_INDIRECT;

			if(e->to->status.visited
			   && (!e->to->status.indirect || indirect))
				continue;

			e->to->status.visited = true;
			e->to->status.indirect = indirect;
			e->to->nexthop = (n->nexthop == myself) ? e->to : n->nexthop;
			e->to->prevedge = e;
			e->to->via = indirect ? n->via : e->to;
			e->to->options = e->options;

			if(e->to->address.sa.sa_family == AF_UNSPEC && e->address.sa.sa_family != AF_UNKNOWN)
				update_node_udp(e->to, &e->address);

			list_insert_tail(todo_list, e->to);
		}

		todonext = from->next;
		list_delete_node(todo_list, from);
	}

	list_free(todo_list);

	/* Check reachability status. */

	for(node = node_tree->head; node; node = next) {
		next = node->next;
		n = node->data;

		if(n->status.visited != n->status.reachable) {
			n->status.reachable = !n->status.reachable;

			if(n->status.reachable) {
				ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became reachable",
					   n->name, n->hostname);
			} else {
				ifdebug(TRAFFIC) logger(LOG_DEBUG, "Node %s (%s) became unreachable",
					   n->name, n->hostname);
			}

			/* TODO: only clear status.validkey if node is unreachable? */

			n->status.validkey = false;
			n->last_req_key = 0;

			n->maxmtu = MTU;
			n->minmtu = 0;
			n->mtuprobes = 0;

			if(n->mtuevent) {
				event_del(n->mtuevent);
				n->mtuevent = NULL;
			}

			xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
			xasprintf(&envp[1], "DEVICE=%s", device ? : "");
			xasprintf(&envp[2], "INTERFACE=%s", iface ? : "");
			xasprintf(&envp[3], "NODE=%s", n->name);
			sockaddr2str(&n->address, &address, &port);
			xasprintf(&envp[4], "REMOTEADDRESS=%s", address);
			xasprintf(&envp[5], "REMOTEPORT=%s", port);
			envp[6] = NULL;

			execute_script(n->status.reachable ? "host-up" : "host-down", envp);

			xasprintf(&name,
					 n->status.reachable ? "hosts/%s-up" : "hosts/%s-down",
					 n->name);
			execute_script(name, envp);

			free(name);
			free(address);
			free(port);

			for(i = 0; i < 6; i++)
				free(envp[i]);

			subnet_update(n, NULL, n->status.reachable);

			if(!n->status.reachable)
				update_node_udp(n, NULL);
			else if(n->connection)
				send_ans_key(n);
		}
	}