/* aggregation testing */ static void aggregate_test (struct tests *t) { struct aspath *asp1, *asp2, *ascratch; printf ("aggregate %s: %s\n", t->test1->name, t->test1->desc); printf ("with %s: %s\n", t->test2->name, t->test2->desc); asp1 = make_aspath (t->test1->asdata, t->test1->len, 0); asp2 = make_aspath (t->test2->asdata, t->test2->len, 0); ascratch = aspath_aggregate (asp1, asp2); if (!validate (ascratch, &t->sp)) printf (OK "\n"); else printf (FAILED "!\n"); printf ("\n"); aspath_unintern (asp1); aspath_unintern (asp2); aspath_free (ascratch); /* aspath_unintern (ascratch);*/ }
/******************************************************************************* 函数名称 : 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); } }