Ejemplo n.º 1
0
/* validate the given aspath */
static int
validate (struct ecommunity *ecom, const struct test_spec *sp)
{
  int fails = 0;
  struct ecommunity *etmp;
  char *str1, *str2;
    
  printf ("got:\n  %s\n", ecommunity_str (ecom));
  str1 = ecommunity_ecom2str (ecom, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
  etmp = ecommunity_str2com (str1, 0, 1);
  if (etmp)
    str2 = ecommunity_ecom2str (etmp, ECOMMUNITY_FORMAT_COMMUNITY_LIST);
  else
    str2 = NULL;
  
  if (strcmp (sp->shouldbe, str1))
    {
      failed++;
      fails++;
      printf ("shouldbe: %s\n%s\n", str1, sp->shouldbe);
    }
  if (!etmp || strcmp (str1, str2))
    {
      failed++;
      fails++;
      printf ("dogfood: in %s\n"
              "    in->out %s\n",
              str1, 
              (etmp && str2) ? str2 : "NULL");
    }
  ecommunity_free (&etmp);
  XFREE (MTYPE_ECOMMUNITY_STR, str1);
  XFREE (MTYPE_ECOMMUNITY_STR, str2);
  
  return fails;
}
Ejemplo n.º 2
0
/*******************************************************************************
 函数名称  : bgp_info_mpath_aggregate_update
 功能描述  : mpath聚合路由更新
 输入参数  : 
 输出参数  : 
 返 回 值  : 无
--------------------------------------------------------------------------------
 最近一次修改记录 :
 修改作者   :      
 修改目的   :      新添加函数
 修改日期   :       2012-8-15
*******************************************************************************/
void bgp_info_mpath_aggregate_update (struct bgp_info *new_best, struct bgp_info *old_best)
{
	struct bgp_info *mpinfo;
	struct aspath *aspath;
	struct aspath *asmerge;
	struct attr *new_attr, *old_attr;
	u8 origin, attr_chg;
	struct community *community, *commerge;
	struct ecommunity *ecomm, *ecommerge;
	struct attr_extra *ae;
	struct attr attr = { 0 };
	
	if (old_best && (old_best != new_best) &&
	      (old_attr = bgp_info_mpath_attr (old_best)))
	{
		bgp_attr_unintern (&old_attr);
		bgp_info_mpath_attr_set (old_best, NULL);
	}
	
	if (!new_best)
	{
	    return;
	}
	if (!bgp_info_mpath_count (new_best))
	{
		if ((new_attr = bgp_info_mpath_attr (new_best)))
	    {
			bgp_attr_unintern (&new_attr);
			bgp_info_mpath_attr_set (new_best, NULL);
			SET_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED);
	    }
		return;
	}

	if (!CHECK_FLAG (new_best->flags, BGP_INFO_MULTIPATH_CHG) &&
				      (old_best == new_best))
	{
		attr_chg = 0;
		
		if (CHECK_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED))
		{
	        attr_chg = 1;
	    }    
		else
		{
			for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
			     mpinfo = bgp_info_mpath_next (mpinfo))
			{
				if (CHECK_FLAG (mpinfo->flags, BGP_INFO_ATTR_CHANGED))
				{
					attr_chg = 1;
					break;
				}
			}
		}	
		if (!attr_chg)
	    {
			return;
	    }
	}
	
	bgp_attr_dup (&attr, new_best->attr);
	
	/* aggregate attribute from multipath constituents */
	aspath = aspath_dup (attr.aspath);
	origin = attr.origin;
	community = attr.community ? community_dup (attr.community) : NULL;
	ae = attr.extra;
	ecomm = (ae && ae->ecommunity) ? ecommunity_dup (ae->ecommunity) : NULL;
	
	for (mpinfo = bgp_info_mpath_first (new_best); mpinfo;
		       mpinfo = bgp_info_mpath_next (mpinfo))
	{
		asmerge = aspath_aggregate (aspath, mpinfo->attr->aspath);
		aspath_free (aspath);
		aspath = asmerge;
		
		if (origin < mpinfo->attr->origin)
		{
	        origin = mpinfo->attr->origin;
		}
		if (mpinfo->attr->community)
	    {
			if (community)
	        {
				commerge = community_merge (community, mpinfo->attr->community);
				community = community_uniq_sort (commerge);
				community_free (&commerge);
	        }
			else
			{
				community = community_dup (mpinfo->attr->community);
			}
	    }
	    
		ae = mpinfo->attr->extra;
		if (ae && ae->ecommunity)
	    {
			if (ecomm)
			{
				ecommerge = ecommunity_merge (ecomm, ae->ecommunity);
				ecomm = ecommunity_uniq_sort (ecommerge);
				ecommunity_free (ecommerge);
			}
			else
			{
	            ecomm = ecommunity_dup (ae->ecommunity);
            }
	    }
	}

	attr.aspath = aspath;
	attr.origin = origin;
	if (community)
	{
		attr.community = community;
		attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES);
	}
	if (ecomm)
	{
		ae = bgp_attr_extra_get (&attr);
		ae->ecommunity = ecomm;
		attr.flag |= ATTR_FLAG_BIT (BGP_ATTR_EXT_COMMUNITIES);
	}

	/* Zap multipath attr nexthop so we set nexthop to self */
	attr.nexthop.s_addr = 0;
#ifdef HAVE_IPV6
	if (attr.extra)
	{
	    memset (&attr.extra->mp_nexthop_global, 0, sizeof (struct in6_addr));
    }
#endif /* HAVE_IPV6 */

	new_attr = bgp_attr_intern (&attr);
	bgp_attr_extra_free (&attr);
	
	if (new_attr != bgp_info_mpath_attr (new_best))
	{
		if ((old_attr = bgp_info_mpath_attr (new_best)))
		{
			bgp_attr_unintern (&old_attr);
		}
		bgp_info_mpath_attr_set (new_best, new_attr);
		SET_FLAG (new_best->flags, BGP_INFO_ATTR_CHANGED);
	}
	else
	{
	    bgp_attr_unintern (&new_attr);
    }
}