예제 #1
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);
    }
}
예제 #2
0
파일: bgp_debug.c 프로젝트: OPSF/uClinux
/* Dump attribute. */
int
bgp_dump_attr (struct peer *peer, struct attr *attr, char *buf, size_t size)
{
  if (! attr)
    return 0;

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP)))
    snprintf (buf, size, "nexthop %s", inet_ntoa (attr->nexthop));

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGIN)))
    snprintf (buf + strlen (buf), size - strlen (buf), ", origin %s",
	      bgp_origin_str[attr->origin]);

#ifdef HAVE_IPV6
  {
    char addrbuf[BUFSIZ];

    /* Add MP case. */
    if (attr->mp_nexthop_len == 16 || attr->mp_nexthop_len == 32)
      snprintf (buf + strlen (buf), size - strlen (buf), ", mp_nexthop %s",
		inet_ntop (AF_INET6, &attr->mp_nexthop_global, 
			   addrbuf, BUFSIZ));

    if (attr->mp_nexthop_len == 32)
      snprintf (buf + strlen (buf), size - strlen (buf), "(%s)",
		inet_ntop (AF_INET6, &attr->mp_nexthop_local, 
			   addrbuf, BUFSIZ));
  }
#endif /* HAVE_IPV6 */

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF)))
    snprintf (buf + strlen (buf), size - strlen (buf), ", localpref %d",
	      attr->local_pref);

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC))) 
    snprintf (buf + strlen (buf), size - strlen (buf), ", metric %d",
	      attr->med);

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES))) 
    snprintf (buf + strlen (buf), size - strlen (buf), ", community %s",
	      community_str (attr->community));

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE)))
    snprintf (buf + strlen (buf), size - strlen (buf), ", atomic-aggregate");

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR)))
    snprintf (buf + strlen (buf), size - strlen (buf), ", aggregated by %d %s",
	      attr->aggregator_as, inet_ntoa (attr->aggregator_addr));

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_ORIGINATOR_ID)))
    snprintf (buf + strlen (buf), size - strlen (buf), ", originator %s",
	      inet_ntoa (attr->originator_id));

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_CLUSTER_LIST)))
    {
      int i;

      snprintf (buf + strlen (buf), size - strlen (buf), ", clusterlist");
      for (i = 0; i < attr->cluster->length / 4; i++)
	snprintf (buf + strlen (buf), size - strlen (buf), " %s",
		  inet_ntoa (attr->cluster->list[i]));
    }

  if (CHECK_FLAG (attr->flag, ATTR_FLAG_BIT (BGP_ATTR_AS_PATH))) 
    snprintf (buf + strlen (buf), size - strlen (buf), ", path %s",
	      aspath_print (attr->aspath));

  if (strlen (buf) > 1)
    return 1;
  else
    return 0;
}
예제 #3
0
파일: readfile.cpp 프로젝트: qzm1218/bgpuma
void print_entry(char *cidr, BGPDUMP_ENTRY *entry,std::ofstream &outFile)
{

	char prefix[BGPDUMP_ADDRSTRLEN];

	outFile << entry->time << "|";
	if (entry->body.zebra_message.withdraw_count) {
		//withdrawal
		outFile << "W|";
		switch(entry->body.zebra_message.address_family) {
			case AFI_IP6:
			inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,prefix,sizeof(prefix));
			outFile << prefix << "|";
			break;
			case AFI_IP:
			default:
			if (entry->body.zebra_message.source_ip.v4_addr.s_addr != 0x00000000L)
				outFile << inet_ntoa(entry->body.zebra_message.source_ip.v4_addr) << "|";
			else
				outFile << "NA|";
		}
		outFile << "AS" << print_asn(entry->body.zebra_message.source_as) << "|";
		switch(entry->body.zebra_message.address_family) {
			case AFI_IP6:
			inet_ntop(AF_INET6,&entry->body.zebra_message.destination_ip.v6_addr,prefix,sizeof(prefix));
			outFile << prefix << "|";
			break;
			case AFI_IP:
			default:
			if (entry->body.zebra_message.destination_ip.v4_addr.s_addr != 0x00000000L)
				outFile << inet_ntoa(entry->body.zebra_message.destination_ip.v4_addr) << "|";
			else
				outFile << "NA|";
		}
		outFile << "AS" << print_asn(entry->body.zebra_message.destination_as) << "|";
		outFile << cidr << std::endl;
	}
	else if ((entry->body.zebra_message.announce_count) || (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) {
		//announce
		outFile << "A|";
		switch(entry->body.zebra_message.address_family) {
			case AFI_IP6:
			inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,prefix,sizeof(prefix));
			outFile << prefix << "|";
			break;
			case AFI_IP:
			default:
			if (entry->body.zebra_message.source_ip.v4_addr.s_addr != 0x00000000L)
				outFile << inet_ntoa(entry->body.zebra_message.source_ip.v4_addr) << "|";
			else
				outFile << "NA|";
		}
		outFile << "AS" << print_asn(entry->body.zebra_message.source_as) << "|";
		switch(entry->body.zebra_message.address_family) {
			case AFI_IP6:
			inet_ntop(AF_INET6,&entry->body.zebra_message.destination_ip.v6_addr,prefix,sizeof(prefix));
			outFile << prefix << "|";
			break;
			case AFI_IP:
			default:
			if (entry->body.zebra_message.destination_ip.v4_addr.s_addr != 0x00000000L)
				outFile << inet_ntoa(entry->body.zebra_message.destination_ip.v4_addr) << "|";
			else
				outFile << "NA|";
		}
		outFile << "AS" << print_asn(entry->body.zebra_message.destination_as) << "|";
		outFile << cidr << "|";
		
		if (entry->attr->aspath != NULL) 
			outFile << entry->attr->aspath->str;
		outFile << std::endl;
	}
}
예제 #4
0
void process_attr_read(struct mstream *s, struct attr *attr, u_int8_t asn_len, struct zebra_incomplete *incomplete, char mp_only_nexthop) {
    u_char	flag;
    u_char	type;
    u_int32_t	len, end;
    u_int32_t	truelen;
    struct unknown_attr *unknown;

    mstream_getw(s, &attr->len);
    if(attr->len == 0)
      return;

    attr->data=malloc(attr->len);

    /* Check the attributes are not truncated */
    if(attr->len > mstream_can_read(s)) {
	truelen = mstream_can_read(s);
	memset(attr->data + truelen, 0, attr->len - truelen);
    } else {
	truelen = attr->len;
    }
    memcpy(attr->data, &s->start[s->position], truelen);

    end = s->position + truelen;

    while(s->position < end) {
	mstream_getc(s,&flag);
	mstream_getc(s,&type);

	if(flag & BGP_ATTR_FLAG_EXTLEN)
	    len=mstream_getw(s,NULL);
	else
	    len=mstream_getc(s,NULL);

	/* Take note of all attributes, including unknown ones */
	if(type <= sizeof(attr->flag) * 8)
	  attr->flag = attr->flag | ATTR_FLAG_BIT (type);

	switch(type) {
	    case BGP_ATTR_ORIGIN:
		mstream_getc(s,&attr->origin);
		break;
	    case BGP_ATTR_AS_PATH:
		attr->aspath = create_aspath(len, asn_len);
		mstream_get(s,attr->aspath->data,len);
		process_attr_aspath_string(attr->aspath);
		break;
	    case BGP_ATTR_NEXT_HOP:
		mstream_get_ipv4(s,&attr->nexthop.s_addr);
		break;
	    case BGP_ATTR_MULTI_EXIT_DISC:
		mstream_getl(s,&attr->med);
		break;
	    case BGP_ATTR_LOCAL_PREF:
		mstream_getl(s,&attr->local_pref);
		break;
	    case BGP_ATTR_ATOMIC_AGGREGATE:
		break;
	    case BGP_ATTR_AGGREGATOR:
		read_asn(s, &attr->aggregator_as, asn_len);
		mstream_get_ipv4(s,&attr->aggregator_addr.s_addr);
		break;
	    case BGP_ATTR_COMMUNITIES:
		attr->community		= malloc(sizeof(struct community));
		attr->community->size	= len / 4;
		attr->community->val	= malloc(len);
		mstream_get(s,attr->community->val,len);
		attr->community->str	= NULL;
		process_attr_community_string(attr->community);
		break;
	    case BGP_ATTR_MP_REACH_NLRI:
		if(attr->mp_info == NULL) {
		    attr->mp_info = malloc(sizeof(struct mp_info));
		    memset(attr->mp_info, 0, sizeof(struct mp_info));
		}
		if(mp_only_nexthop)
			process_mp_announce_only_nexthop(s, attr->mp_info, len, incomplete);
		else
			process_mp_announce(s, attr->mp_info, len, incomplete);
		break;
	    case BGP_ATTR_MP_UNREACH_NLRI:
		if(attr->mp_info == NULL) {
		    attr->mp_info = malloc(sizeof(struct mp_info));
		    memset(attr->mp_info, 0, sizeof(struct mp_info));
		}
		process_mp_withdraw(s, attr->mp_info, len, incomplete);
	    case BGP_ATTR_NEW_AS_PATH:
		attr->new_aspath = create_aspath(len, ASN32_LEN);
		mstream_get(s,attr->new_aspath->data,len);
		process_attr_aspath_string(attr->new_aspath);
                /* AS_CONFED_SEQUENCE and AS_CONFED_SET segments invalid in NEW_AS_PATH */
                check_new_aspath(attr->new_aspath);
		break;
	    case BGP_ATTR_NEW_AGGREGATOR:
		read_asn(s, &attr->new_aggregator_as, ASN32_LEN);
		mstream_get_ipv4(s,&attr->new_aggregator_addr.s_addr);
		break;

	    case BGP_ATTR_ORIGINATOR_ID:
		mstream_get_ipv4(s,&attr->originator_id.s_addr);
		break;
	    case BGP_ATTR_CLUSTER_LIST:
		attr->cluster		= malloc(sizeof(struct cluster_list));
		attr->cluster->length	= len/4;
		attr->cluster->list = malloc((attr->cluster->length) * sizeof(struct in_addr));
	
		int cluster_index;
		for (cluster_index=0;cluster_index<attr->cluster->length;cluster_index++)
			mstream_get_ipv4(s,&attr->cluster->list[cluster_index].s_addr);
		break;

	    default:
		/* Unknown attribute. Save as is */
		attr->unknown_num++;
		attr->unknown = realloc(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr));

		/* Pointer to the unknown attribute we want to fill in */
		unknown = attr->unknown + attr->unknown_num - 1;

		/* Work around bogus attribute lengths */
		if(s->position + len > end)
		    unknown->real_len = end - s->position;
		else
		    unknown->real_len = len;

		unknown->flag = flag;
		unknown->type = type;
		unknown->len = len;

		unknown->raw = malloc(unknown->real_len + ((flag & BGP_ATTR_FLAG_EXTLEN) ? 4 : 3));

		unknown->raw[0] = flag;
		unknown->raw[1] = type;

		if(flag & BGP_ATTR_FLAG_EXTLEN) {
		    unknown->raw[2] = (len & 0xFF00) >> 8;
		    unknown->raw[3] = len & 0xFF;
		    mstream_get(s, unknown->raw + 4, unknown->real_len);
		} else {
		    unknown->raw[2] = len;
		    mstream_get(s, unknown->raw + 3, unknown->real_len);
		}
		break;
	}