コード例 #1
0
ファイル: router-id.c プロジェクト: AT-Corp/quagga-atc
void
router_id_get (struct prefix *p, vrf_id_t vrf_id)
{
  struct listnode *node;
  struct connected *c;
  struct zebra_vrf *zvrf = vrf_info_get (vrf_id);

  p->u.prefix4.s_addr = 0;
  p->family = AF_INET;
  p->prefixlen = 32;

  if (zvrf->rid_user_assigned.u.prefix4.s_addr)
    p->u.prefix4.s_addr = zvrf->rid_user_assigned.u.prefix4.s_addr;
  else if (!list_isempty (zvrf->rid_lo_sorted_list))
    {
      node = listtail (zvrf->rid_lo_sorted_list);
      c = listgetdata (node);
      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
    }
  else if (!list_isempty (zvrf->rid_all_sorted_list))
    {
      node = listtail (zvrf->rid_all_sorted_list);
      c = listgetdata (node);
      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
    }
}
コード例 #2
0
ファイル: router-id.c プロジェクト: Balaji-Parasuram/quagga
void
router_id_get (struct prefix *p)
{
  struct listnode *node;
  struct connected *c;

  p->u.prefix4.s_addr = 0;
  p->family = AF_INET;
  p->prefixlen = 32;

  if (rid_user_assigned.u.prefix4.s_addr)
    p->u.prefix4.s_addr = rid_user_assigned.u.prefix4.s_addr;
  else if (!list_isempty (&rid_lo_sorted_list))
    {
      node = listtail (&rid_lo_sorted_list);
      c = listgetdata (node);
      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
    }
  else if (!list_isempty (&rid_all_sorted_list))
    {
      node = listtail (&rid_all_sorted_list);
      c = listgetdata (node);
      p->u.prefix4.s_addr = c->address->u.prefix4.s_addr;
    }
}
コード例 #3
0
ファイル: isis_spf.c プロジェクト: AT-Corp/quagga-atc
void
isis_spftree_adj_del (struct isis_spftree *spftree, struct isis_adjacency *adj)
{
  struct listnode *node;
  if (!adj)
    return;
  for (node = listhead (spftree->tents); node; node = listnextnode (node))
    isis_vertex_adj_del (listgetdata (node), adj);
  for (node = listhead (spftree->paths); node; node = listnextnode (node))
    isis_vertex_adj_del (listgetdata (node), adj);
  return;
}
コード例 #4
0
ファイル: impl_ifmgr.c プロジェクト: MichaelQQ/Quagga-PE
mpls_return_enum mpls_ifmgr_getnext_address(mpls_ifmgr_handle ifmgr_handle,
  mpls_if_handle *handle, mpls_inet_addr *addr)
{
  struct connected *ifc;
  struct listnode *node;
  int next = 0;

  while ((*handle)) {
    for (node = listhead((*handle)->connected); node; listnextnode(node)) {
      ifc = listgetdata(node);
      if (ifc->address->family == AF_INET &&
	ifc->address->u.prefix4.s_addr != htonl(INADDR_LOOPBACK)) {
        if (next) {
          addr->type = MPLS_FAMILY_IPV4;
          addr->u.ipv4 = ntohl(ifc->address->u.prefix4.s_addr);
          return MPLS_SUCCESS;
        } else if (addr->u.ipv4 == ntohl(ifc->address->u.prefix4.s_addr)) {
          next = 1;
        }
      }
    }
    (*handle) = if_getnext(*handle);
    next = 1;
  }
  return MPLS_END_OF_LIST;
}
コード例 #5
0
ファイル: sv_sisis.c プロジェクト: ecks/sis-is
unsigned int
are_checksums_same (void)
{
  int same = 0;
  struct listnode * node, * nnode;
  struct sisis_listener * listener;
  struct sisis_listener * listener_swp = (struct sisis_listener *)listgetdata(listhead(sm->listen_sockets));
  u_int16_t chsum_swp = listener_swp->chksum;

  for(ALL_LIST_ELEMENTS (sm->listen_sockets, node, nnode, listener))
  {
    zlog_debug("checksum: %d\n", listener->chksum);
    if(listener->chksum == chsum_swp)
    {
      same = 1;
      chsum_swp = listener->chksum;
    }
    else
    {
      return 0;
     }
  }

  return same;
}
コード例 #6
0
ファイル: rip_zebra.c プロジェクト: KeremSaka/i2rsCode
/* Send ECMP routes to zebra. */
static void
rip_zebra_ipv4_send (struct route_node *rp, u_char cmd)
{
  static struct in_addr **nexthops = NULL;
  static unsigned int nexthops_len = 0;

  struct list *list = (struct list *)rp->info;
  struct zapi_ipv4 api;
  struct listnode *listnode = NULL;
  struct rip_info *rinfo = NULL;
  int count = 0;

  if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIP], VRF_DEFAULT))
    {
      api.vrf_id = VRF_DEFAULT;
      api.type = ZEBRA_ROUTE_RIP;
      api.flags = 0;
      api.message = 0;
      api.safi = SAFI_UNICAST;

      if (nexthops_len < listcount (list))
        {
          nexthops_len = listcount (list);
          nexthops = XREALLOC (MTYPE_TMP, nexthops,
                               nexthops_len * sizeof (struct in_addr *));
        }

      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
        {
          nexthops[count++] = &rinfo->nexthop;
          if (cmd == ZEBRA_IPV4_ROUTE_ADD)
            SET_FLAG (rinfo->flags, RIP_RTF_FIB);
          else
            UNSET_FLAG (rinfo->flags, RIP_RTF_FIB);
        }

      api.nexthop = nexthops;
      api.nexthop_num = count;
      api.ifindex_num = 0;

      rinfo = listgetdata (listhead (list));

      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = rinfo->metric;

      if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT)
        {
          SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE);
          api.distance = rinfo->distance;
        }

      zapi_ipv4_route (cmd, zclient,
                       (struct prefix_ipv4 *)&rp->p, &api);

      rip_global_route_changes++;
    }
コード例 #7
0
ファイル: isis_spf.c プロジェクト: kkcloudy/daemongroup
/* 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;
}
コード例 #8
0
ファイル: isis_spf.c プロジェクト: AT-Corp/quagga-atc
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;
}
コード例 #9
0
ファイル: interface.c プロジェクト: edderick/quagga_zOSPF
/* Untie an interface address from its derived subnet list of addresses. */
int
if_subnet_delete (struct interface *ifp, struct connected *ifc)
{
  struct route_node *rn;
  struct zebra_if *zebra_if;
  struct list *addr_list;

  assert (ifp && ifp->info && ifc);
  zebra_if = ifp->info;

  /* Get address derived subnet node. */
  rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
  if (! (rn && rn->info))
    return -1;
  route_unlock_node (rn);
  
  /* Untie address from subnet's address list. */
  addr_list = rn->info;
  listnode_delete (addr_list, ifc);
  route_unlock_node (rn);

  /* Return list element count, if not empty. */
  if (addr_list->count)
    {
      /* If deleted address is primary, mark subsequent one as such and distribute. */
      if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
	{
	  ifc = listgetdata (listhead (addr_list));
	  zebra_interface_address_delete_update (ifp, ifc);
	  UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
	  zebra_interface_address_add_update (ifp, ifc);
	}
      
      return addr_list->count;
    }
  
  /* Otherwise, free list and route node. */
  list_free (addr_list);
  rn->info = NULL;
  route_unlock_node (rn);

  return 0;
}
コード例 #10
0
ファイル: isis_flags.c プロジェクト: Quagga/people-jcollie
int
flags_get_index (struct flags *flags)
{
  struct listnode *node;
  int index;

  if (flags->free_idcs == NULL || flags->free_idcs->count == 0)
    {
      flags->maxindex++;
      index = flags->maxindex;
    }
  else
    {
      node = listhead (flags->free_idcs);
      index = (int) listgetdata (node);
      listnode_delete (flags->free_idcs, (void *) index);
    }

  return index;
}
コード例 #11
0
ファイル: if.c プロジェクト: balajig/Layer3Switch
struct connected *
connected_delete_by_prefix (struct interface *ifp, struct prefix *p)
{
  struct listnode *node;
  struct listnode *next;
  struct connected *ifc;

  /* In case of same prefix come, replace it with new one. */
  for (node = listhead (ifp->connected); node; node = next)
    {
      ifc = listgetdata (node);
      next = node->next;

      if (connected_same_prefix (ifc->address, p))
	{
	  listnode_delete (ifp->connected, ifc);
	  return ifc;
	}
    }
  return NULL;
}
コード例 #12
0
ファイル: bgp_mpath.c プロジェクト: millken/zhuxianB30
/*******************************************************************************
 函数名称  : 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);
        }
	}
}
コード例 #13
0
ファイル: isis_te.c プロジェクト: KaloNK/quagga
/* Call when interface TE Link parameters are modified */
void
isis_link_params_update (struct isis_circuit *circuit, struct interface *ifp)
{
  int i;
  struct prefix_ipv4 *addr;
  struct mpls_te_circuit *mtc;

  /* Sanity Check */
  if ((circuit == NULL) || (ifp == NULL))
      return;

  zlog_info ("MPLS-TE: Initialize circuit parameters for interface %s", ifp->name);
  
  /* Check if MPLS TE Circuit context has not been already created */
  if (circuit->mtc == NULL)
      circuit->mtc = mpls_te_circuit_new();

  mtc = circuit->mtc;

  /* Fulfil MTC TLV from ifp TE Link parameters */
  if (HAS_LINK_PARAMS(ifp))
    {
      mtc->status = enable;
      /* STD_TE metrics */
      if (IS_PARAM_SET(ifp->link_params, LP_ADM_GRP))
        set_circuitparams_admin_grp (mtc, ifp->link_params->admin_grp);
      else
        SUBTLV_TYPE(mtc->admin_grp) = 0;

      /* If not already set, register local IP addr from ip_addr list if it exists */
      if (SUBTLV_TYPE(mtc->local_ipaddr) == 0)
        {
          if (circuit->ip_addrs != NULL && listcount(circuit->ip_addrs) != 0)
            {
              addr = (struct prefix_ipv4 *)listgetdata ((struct listnode *)listhead (circuit->ip_addrs));
              set_circuitparams_local_ipaddr (mtc, addr->prefix);
            }
        }

      /* If not already set, try to determine Remote IP addr if circuit is P2P */
      if ((SUBTLV_TYPE(mtc->rmt_ipaddr) == 0) && (circuit->circ_type == CIRCUIT_T_P2P))
        {
          struct isis_adjacency *adj = circuit->u.p2p.neighbor;
          if (adj->ipv4_addrs != NULL && listcount(adj->ipv4_addrs) != 0)
            {
              struct in_addr *ip_addr;
              ip_addr = (struct in_addr *)listgetdata ((struct listnode *)listhead (adj->ipv4_addrs));
              set_circuitparams_rmt_ipaddr (mtc, *ip_addr);
            }
        }

      if (IS_PARAM_SET(ifp->link_params, LP_MAX_BW))
        set_circuitparams_max_bw (mtc, ifp->link_params->max_bw);
      else
        SUBTLV_TYPE(mtc->max_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_MAX_RSV_BW))
        set_circuitparams_max_rsv_bw (mtc, ifp->link_params->max_rsv_bw);
      else
        SUBTLV_TYPE(mtc->max_rsv_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_UNRSV_BW))
        for (i = 0; i < MAX_CLASS_TYPE; i++)
          set_circuitparams_unrsv_bw (mtc, i, ifp->link_params->unrsv_bw[i]);
      else
        SUBTLV_TYPE(mtc->unrsv_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_TE))
        set_circuitparams_te_metric(mtc, ifp->link_params->te_metric);
      else
        SUBTLV_TYPE(mtc->te_metric) = 0;

      /* TE metric Extensions */
      if (IS_PARAM_SET(ifp->link_params, LP_DELAY))
        set_circuitparams_av_delay(mtc, ifp->link_params->av_delay, 0);
      else
        SUBTLV_TYPE(mtc->av_delay) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_MM_DELAY))
        set_circuitparams_mm_delay(mtc, ifp->link_params->min_delay, ifp->link_params->max_delay, 0);
      else
        SUBTLV_TYPE(mtc->mm_delay) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_DELAY_VAR))
        set_circuitparams_delay_var(mtc, ifp->link_params->delay_var);
      else
        SUBTLV_TYPE(mtc->delay_var) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_PKT_LOSS))
        set_circuitparams_pkt_loss(mtc, ifp->link_params->pkt_loss, 0);
      else
        SUBTLV_TYPE(mtc->pkt_loss) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_RES_BW))
        set_circuitparams_res_bw(mtc, ifp->link_params->res_bw);
      else
        SUBTLV_TYPE(mtc->res_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_AVA_BW))
        set_circuitparams_ava_bw(mtc, ifp->link_params->ava_bw);
      else
        SUBTLV_TYPE(mtc->ava_bw) = 0;

      if (IS_PARAM_SET(ifp->link_params, LP_USE_BW))
        set_circuitparams_use_bw(mtc, ifp->link_params->use_bw);
      else
        SUBTLV_TYPE(mtc->use_bw) = 0;

      /* INTER_AS */
      if (IS_PARAM_SET(ifp->link_params, LP_RMT_AS))
        set_circuitparams_inter_as(mtc, ifp->link_params->rmt_ip, ifp->link_params->rmt_as);
      else
        /* reset inter-as TE params */
        unset_circuitparams_inter_as (mtc);

      /* Compute total length of SUB TLVs */
      mtc->length = subtlvs_len(mtc);

    }
  else
    mtc->status = disable;

  /* Finally Update LSP */
#if 0
  if (IS_MPLS_TE(isisMplsTE) && circuit->area)
       lsp_regenerate_schedule (circuit->area, circuit->is_type, 0);
#endif
  return;
}
コード例 #14
0
ファイル: isis_spf.c プロジェクト: kkcloudy/daemongroup
/*
 * Add a vertex to TENT sorted by cost and by vertextype on tie break situation
 */
static struct isis_vertex *
isis_spf_add2tent (struct isis_spftree *spftree, enum vertextype vtype,
		   void *id, struct isis_adjacency *adj, u_int32_t cost,
		   int depth, int family)
{
  struct isis_vertex *vertex, *v;
  struct listnode *node;
#ifdef EXTREME_DEBUG
  u_char buff[BUFSIZ];
#endif

  vertex = isis_vertex_new (id, vtype);
  vertex->d_N = cost;
  vertex->depth = depth;

  if (adj)
    listnode_add (vertex->Adj_N, adj);
#ifdef EXTREME_DEBUG
  zlog_debug ("ISIS-Spf: add to TENT  %s %s depth %d dist %d",
	      vtype2string (vertex->type), vid2string (vertex, buff),
	      vertex->depth, vertex->d_N);
#endif /* EXTREME_DEBUG */
  listnode_add (spftree->tents, vertex);
  if (list_isempty (spftree->tents))
    {
      listnode_add (spftree->tents, vertex);
      return vertex;
    }
  
  /* XXX: This cant use the standard ALL_LIST_ELEMENT macro */
  for (node = listhead (spftree->tents); node; node = listnextnode (node))
    {
      v = listgetdata (node);
      if (v->d_N > vertex->d_N)
	{
	  list_add_node_prev (spftree->tents, node, vertex);
	  break;
	}
      else if (v->d_N == vertex->d_N)
	{
	  /*  Tie break, add according to type */
	  while (v && v->d_N == vertex->d_N && v->type > vertex->type)
	    {
	      if (v->type > vertex->type)
		{
		  break;
		}
              /* XXX: this seems dubious, node is the loop iterator */
	      node = listnextnode (node);
	      (node) ? (v = listgetdata (node)) : (v = NULL);
	    }
	  list_add_node_prev (spftree->tents, node, vertex);
	  break;
	}
      else if (node->next == NULL)
	{
	  list_add_node_next (spftree->tents, node, vertex);
	  break;
	}
    }
  return vertex;
}
コード例 #15
0
ファイル: interface.c プロジェクト: edderick/quagga_zOSPF
/* 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;
}
コード例 #16
0
ファイル: interface.c プロジェクト: ColinBS/quagga-rtrlib
/* Untie an interface address from its derived subnet list of addresses. */
int
if_subnet_delete (struct interface *ifp, struct connected *ifc)
{
  struct route_node *rn;
  struct zebra_if *zebra_if;
  struct list *addr_list;

  assert (ifp && ifp->info && ifc);
  zebra_if = ifp->info;

  /* Get address derived subnet node. */
  rn = route_node_lookup (zebra_if->ipv4_subnets, ifc->address);
  if (! (rn && rn->info))
    {
      zlog_warn("Trying to remove an address from an unknown subnet."
                " (please report this bug)");
      return -1;
    }
  route_unlock_node (rn);
  
  /* Untie address from subnet's address list. */
  addr_list = rn->info;

  /* Deleting an address that is not registered is a bug.
   * In any case, we shouldn't decrement the lock counter if the address
   * is unknown. */
  if (!listnode_lookup(addr_list, ifc))
    {
      zlog_warn("Trying to remove an address from a subnet where it is not"
                " currently registered. (please report this bug)");
      return -1;
    }

  listnode_delete (addr_list, ifc);
  route_unlock_node (rn);

  /* Return list element count, if not empty. */
  if (addr_list->count)
    {
      /* If deleted address is primary, mark subsequent one as such and distribute. */
      if (! CHECK_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY))
	{
	  ifc = listgetdata (listhead (addr_list));
	  zebra_interface_address_delete_update (ifp, ifc);
	  UNSET_FLAG (ifc->flags, ZEBRA_IFA_SECONDARY);
	  /* XXX: Linux kernel removes all the secondary addresses when the primary
	   * address is removed. We could try to work around that, though this is
	   * non-trivial. */
	  zebra_interface_address_add_update (ifp, ifc);
	}
      
      return addr_list->count;
    }
  
  /* Otherwise, free list and route node. */
  list_free (addr_list);
  rn->info = NULL;
  route_unlock_node (rn);

  return 0;
}
コード例 #17
0
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf,
				       const uint8_t *buf_pastend,
				       struct list *ifconnected)
{
  struct listnode *node;
  uint16_t option_len = 0;

  uint8_t *curr;

  node = listhead(ifconnected);

  /* Empty address list ? */
  if (!node) {
    return buf;
  }

  /* Skip first address (primary) */
  node = listnextnode(node);

  /* Scan secondary address list */
  curr = buf + 4; /* skip T and L */
  for (; node; node = listnextnode(node)) {
    struct connected *ifc = listgetdata(node);
    struct prefix *p = ifc->address;
    
    if (p->family != AF_INET)
      continue;

    if ((curr + ucast_ipv4_encoding_len) > buf_pastend) {
      zlog_warn("%s: buffer overflow: left=%zd needed=%zu",
		__PRETTY_FUNCTION__,
		buf_pastend - curr, ucast_ipv4_encoding_len);
      return 0;
    }

    /* Write encoded unicast IPv4 address */
    *(uint8_t *) curr = PIM_MSG_ADDRESS_FAMILY_IPV4; /* notice: AF_INET != PIM_MSG_ADDRESS_FAMILY_IPV4 */
    ++curr;
    *(uint8_t *) curr = 0; /* ucast IPv4 native encoding type (RFC 4601: 4.9.1) */
    ++curr;
    memcpy(curr, &p->u.prefix4, sizeof(struct in_addr));
    curr += sizeof(struct in_addr);

    option_len += ucast_ipv4_encoding_len; 
  }

  if (PIM_DEBUG_PIM_TRACE) {
    zlog_warn("%s: number of encoded secondary unicast IPv4 addresses: %zu",
	      __PRETTY_FUNCTION__,
	      option_len / ucast_ipv4_encoding_len);
  }

  if (option_len < 1) {
    /* Empty secondary unicast IPv4 address list */
    return buf;
  }

  /*
   * Write T and L
   */
  *(uint16_t *) buf       = htons(PIM_MSG_OPTION_TYPE_ADDRESS_LIST);
  *(uint16_t *) (buf + 2) = htons(option_len);

  return curr;
}
コード例 #18
0
ファイル: rip_zebra.c プロジェクト: ton31337/frr
/* Send ECMP routes to zebra. */
static void rip_zebra_ipv4_send(struct rip *rip, struct route_node *rp,
				uint8_t cmd)
{
	struct list *list = (struct list *)rp->info;
	struct zapi_route api;
	struct zapi_nexthop *api_nh;
	struct listnode *listnode = NULL;
	struct rip_info *rinfo = NULL;
	int count = 0;

	memset(&api, 0, sizeof(api));
	api.vrf_id = rip->vrf->vrf_id;
	api.type = ZEBRA_ROUTE_RIP;
	api.safi = SAFI_UNICAST;

	SET_FLAG(api.message, ZAPI_MESSAGE_NEXTHOP);
	for (ALL_LIST_ELEMENTS_RO(list, listnode, rinfo)) {
		if (count >= MULTIPATH_NUM)
			break;
		api_nh = &api.nexthops[count];
		api_nh->vrf_id = rip->vrf->vrf_id;
		api_nh->gate = rinfo->nh.gate;
		api_nh->type = NEXTHOP_TYPE_IPV4;
		if (cmd == ZEBRA_ROUTE_ADD)
			SET_FLAG(rinfo->flags, RIP_RTF_FIB);
		else
			UNSET_FLAG(rinfo->flags, RIP_RTF_FIB);
		count++;
	}

	api.prefix = rp->p;
	api.nexthop_num = count;

	rinfo = listgetdata(listhead(list));

	SET_FLAG(api.message, ZAPI_MESSAGE_METRIC);
	api.metric = rinfo->metric;

	if (rinfo->distance && rinfo->distance != ZEBRA_RIP_DISTANCE_DEFAULT) {
		SET_FLAG(api.message, ZAPI_MESSAGE_DISTANCE);
		api.distance = rinfo->distance;
	}

	if (rinfo->tag) {
		SET_FLAG(api.message, ZAPI_MESSAGE_TAG);
		api.tag = rinfo->tag;
	}

	zclient_route_send(cmd, zclient, &api);

	if (IS_RIP_DEBUG_ZEBRA) {
		if (rip->ecmp)
			zlog_debug("%s: %s/%d nexthops %d",
				   (cmd == ZEBRA_ROUTE_ADD)
					   ? "Install into zebra"
					   : "Delete from zebra",
				   inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen,
				   count);
		else
			zlog_debug("%s: %s/%d",
				   (cmd == ZEBRA_ROUTE_ADD)
					   ? "Install into zebra"
					   : "Delete from zebra",
				   inet_ntoa(rp->p.u.prefix4), rp->p.prefixlen);
	}

	rip->counters.route_changes++;
}
コード例 #19
0
ファイル: ripng_zebra.c プロジェクト: AT-Corp/quagga-atc
/* Send ECMP routes to zebra. */
static void
ripng_zebra_ipv6_send (struct route_node *rp, u_char cmd)
{
  static struct in6_addr **nexthops = NULL;
  static unsigned int *ifindexes = NULL;
  static unsigned int nexthops_len = 0;

  struct list *list = (struct list *)rp->info;
  struct zapi_ipv6 api;
  struct listnode *listnode = NULL;
  struct ripng_info *rinfo = NULL;
  int count = 0;

  if (vrf_bitmap_check (zclient->redist[ZEBRA_ROUTE_RIPNG], VRF_DEFAULT))
    {
      api.vrf_id = VRF_DEFAULT;
      api.type = ZEBRA_ROUTE_RIPNG;
      api.flags = 0;
      api.message = 0;
      api.safi = SAFI_UNICAST;

      if (nexthops_len < listcount (list))
        {
          nexthops_len = listcount (list);
          nexthops = XREALLOC (MTYPE_TMP, nexthops,
                               nexthops_len * sizeof (struct in6_addr *));
          ifindexes = XREALLOC (MTYPE_TMP, ifindexes,
                                nexthops_len * sizeof (unsigned int));
        }

      SET_FLAG (api.message, ZAPI_MESSAGE_NEXTHOP);
      SET_FLAG (api.message, ZAPI_MESSAGE_IFINDEX);
      for (ALL_LIST_ELEMENTS_RO (list, listnode, rinfo))
        {
          nexthops[count] = &rinfo->nexthop;
          ifindexes[count] = rinfo->ifindex;
          count++;
          if (cmd == ZEBRA_IPV6_ROUTE_ADD)
            SET_FLAG (rinfo->flags, RIPNG_RTF_FIB);
          else
            UNSET_FLAG (rinfo->flags, RIPNG_RTF_FIB);
        }

      api.nexthop = nexthops;
      api.nexthop_num = count;
      api.ifindex = ifindexes;
      api.ifindex_num = count;

      rinfo = listgetdata (listhead (list));

      SET_FLAG (api.message, ZAPI_MESSAGE_METRIC);
      api.metric = rinfo->metric;

      zapi_ipv6_route (cmd, zclient,
                       (struct prefix_ipv6 *)&rp->p, &api);

      if (IS_RIPNG_DEBUG_ZEBRA)
        {
          if (ripng->ecmp)
            zlog_debug ("%s: %s/%d nexthops %d",
                        (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \
                            "Install into zebra" : "Delete from zebra",
                        inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen, count);
          else
            zlog_debug ("%s: %s/%d",
                        (cmd == ZEBRA_IPV6_ROUTE_ADD) ? \
                            "Install into zebra" : "Delete from zebra",
                        inet6_ntoa (rp->p.u.prefix6), rp->p.prefixlen);
        }
    }