bgp_unlink_nexthop(path);
bgp_path_info_extra_free(&path->extra);
bgp_path_info_mpath_free(&path->mpath);
- bgp_addpath_free_info_data(&path->tx_addpath,
- path->net ? &path->net->tx_addpath : NULL);
+ if (path->net)
+ bgp_addpath_free_info_data(&path->tx_addpath,
+ &path->net->tx_addpath);
peer_unlock(path->peer); /* bgp_path_info peer reference */
}
}
+ /* RFC 8212 to prevent route leaks.
+ * This specification intends to improve this situation by requiring the
+ * explicit configuration of both BGP Import and Export Policies for any
+ * External BGP (EBGP) session such as customers, peers, or
+ * confederation boundaries for all enabled address families. Through
+ * codification of the aforementioned requirement, operators will
+ * benefit from consistent behavior across different BGP
+ * implementations.
+ */
+ if (peer->bgp->ebgp_requires_policy
+ == DEFAULT_EBGP_POLICY_ENABLED)
+ if (!bgp_inbound_policy_exists(peer, filter))
+ return RMAP_DENY;
+
/* Route map apply. */
if (rmap) {
memset(&rmap_path, 0, sizeof(struct bgp_path_info));
}
}
+ /* RFC 8212 to prevent route leaks.
+ * This specification intends to improve this situation by requiring the
+ * explicit configuration of both BGP Import and Export Policies for any
+ * External BGP (EBGP) session such as customers, peers, or
+ * confederation boundaries for all enabled address families. Through
+ * codification of the aforementioned requirement, operators will
+ * benefit from consistent behavior across different BGP
+ * implementations.
+ */
+ if (peer->bgp->ebgp_requires_policy
+ == DEFAULT_EBGP_POLICY_ENABLED)
+ if (!bgp_outbound_policy_exists(peer, filter))
+ return 0;
+
if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
if (peer->sort == BGP_PEER_IBGP
|| peer->sort == BGP_PEER_CONFED) {
/* advertise/withdraw type-5 routes */
if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
- if (advertise_type5_routes(bgp, afi) && new_select &&
- (!new_select->extra || !new_select->extra->parent)) {
+ if (advertise_type5_routes(bgp, afi) &&
+ new_select &&
+ is_route_injectable_into_evpn(new_select)) {
/* apply the route-map */
if (bgp->adv_cmd_rmap[afi][safi].map) {
bgp_evpn_advertise_type5_route(
bgp, &rn->p, new_select->attr,
afi, safi);
+ else
+ bgp_evpn_withdraw_type5_route(
+ bgp, &rn->p, afi, safi);
} else {
bgp_evpn_advertise_type5_route(bgp,
&rn->p,
afi, safi);
}
- } else if (advertise_type5_routes(bgp, afi) && old_select &&
- (!old_select->extra || !old_select->extra->parent))
+ } else if (advertise_type5_routes(bgp, afi) &&
+ old_select &&
+ is_route_injectable_into_evpn(old_select))
bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
}
goto filtered;
}
- if (bgp_mac_entry_exists(p)) {
+ if (bgp_mac_entry_exists(p) || bgp_mac_exist(&attr->rmac)) {
reason = "self mac;";
goto filtered;
}
extra = bgp_path_info_extra_get(pi);
if (extra->label != label) {
memcpy(&extra->label, label,
- num_labels * sizeof(mpls_label_t));
+ num_labels * sizeof(mpls_label_t));
extra->num_labels = num_labels;
}
if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
if (has_valid_label) {
extra = bgp_path_info_extra_get(new);
if (extra->label != label) {
- memcpy(&extra->label, label, num_labels * sizeof(mpls_label_t));
+ memcpy(&extra->label, label,
+ num_labels * sizeof(mpls_label_t));
extra->num_labels = num_labels;
}
if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
}
}
+int bgp_outbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
+{
+ if (peer->sort == BGP_PEER_EBGP
+ && (ROUTE_MAP_OUT_NAME(filter) || PREFIX_LIST_OUT_NAME(filter)
+ || FILTER_LIST_OUT_NAME(filter)
+ || DISTRIBUTE_OUT_NAME(filter)))
+ return 1;
+ return 0;
+}
+
+int bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
+{
+ if (peer->sort == BGP_PEER_EBGP
+ && (ROUTE_MAP_IN_NAME(filter) || PREFIX_LIST_IN_NAME(filter)
+ || FILTER_LIST_IN_NAME(filter)
+ || DISTRIBUTE_IN_NAME(filter)))
+ return 1;
+ return 0;
+}
+
static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
safi_t safi)
{
static void bgp_static_free(struct bgp_static *bgp_static)
{
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
- if (bgp_static->eth_s_id)
- XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
+ XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
+ route_map_counter_decrement(bgp_static->rmap.map);
+
+ XFREE(MTYPE_ATTR, bgp_static->eth_s_id);
XFREE(MTYPE_BGP_STATIC, bgp_static);
}
bgp_static->backdoor = backdoor;
if (rmap) {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ route_map_counter_decrement(
+ bgp_static->rmap.map);
bgp_static->rmap.name =
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
bgp_static->rmap.map =
route_map_lookup_by_name(rmap);
+ route_map_counter_increment(
+ bgp_static->rmap.map);
} else {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ route_map_counter_decrement(
+ bgp_static->rmap.map);
bgp_static->rmap.name = NULL;
bgp_static->rmap.map = NULL;
bgp_static->valid = 0;
bgp_static->label_index = label_index;
if (rmap) {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME,
+ bgp_static->rmap.name);
+ route_map_counter_decrement(
+ bgp_static->rmap.map);
bgp_static->rmap.name =
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap);
bgp_static->rmap.map =
route_map_lookup_by_name(rmap);
+ route_map_counter_increment(
+ bgp_static->rmap.map);
}
bgp_node_set_bgp_static_info(rn, bgp_static);
}
bgp_static->prd = prd;
if (rmap_str) {
- if (bgp_static->rmap.name)
- XFREE(MTYPE_ROUTE_MAP_NAME,
- bgp_static->rmap.name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, bgp_static->rmap.name);
+ route_map_counter_decrement(bgp_static->rmap.map);
bgp_static->rmap.name =
XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_str);
bgp_static->rmap.map =
route_map_lookup_by_name(rmap_str);
+ route_map_counter_increment(bgp_static->rmap.map);
}
if (safi == SAFI_EVPN) {
rmap = &bgp->table_map[afi][safi];
if (rmap_name) {
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ route_map_counter_decrement(rmap->map);
rmap->name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, rmap_name);
rmap->map = route_map_lookup_by_name(rmap_name);
+ route_map_counter_increment(rmap->map);
} else {
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ route_map_counter_decrement(rmap->map);
rmap->name = NULL;
rmap->map = NULL;
}
struct bgp_rmap *rmap;
rmap = &bgp->table_map[afi][safi];
- if (rmap->name)
- XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ XFREE(MTYPE_ROUTE_MAP_NAME, rmap->name);
+ route_map_counter_decrement(rmap->map);
rmap->name = NULL;
rmap->map = NULL;
label_index ? (uint32_t)label_index : BGP_INVALID_LABEL_INDEX);
}
-/* Aggreagete address:
-
- advertise-map Set condition to advertise attribute
- as-set Generate AS set path information
- attribute-map Set attributes of aggregate
- route-map Set parameters of aggregate
- summary-only Filter more specific routes from updates
- suppress-map Conditionally filter more specific routes from updates
- <cr>
- */
-struct bgp_aggregate {
- /* Summary-only flag. */
- uint8_t summary_only;
-
- /* AS set generation. */
- uint8_t as_set;
-
- /* Route-map for aggregated route. */
- struct route_map *map;
-
- /* Suppress-count. */
- unsigned long count;
-
- /* SAFI configuration. */
- safi_t safi;
-};
-
static struct bgp_aggregate *bgp_aggregate_new(void)
{
return XCALLOC(MTYPE_BGP_AGGREGATE, sizeof(struct bgp_aggregate));
/* Update an aggregate as routes are added/removed from the BGP table */
static void bgp_aggregate_route(struct bgp *bgp, struct prefix *p,
- struct bgp_path_info *pinew, afi_t afi,
- safi_t safi, struct bgp_path_info *del,
+ afi_t afi, safi_t safi,
struct bgp_aggregate *aggregate)
{
struct bgp_table *table;
struct bgp_node *rn;
uint8_t origin;
struct aspath *aspath = NULL;
- struct aspath *asmerge = NULL;
struct community *community = NULL;
- struct community *commerge = NULL;
struct ecommunity *ecommunity = NULL;
- struct ecommunity *ecommerge = NULL;
struct lcommunity *lcommunity = NULL;
- struct lcommunity *lcommerge = NULL;
struct bgp_path_info *pi;
unsigned long match = 0;
uint8_t atomic_aggregate = 0;
if (BGP_PATH_HOLDDOWN(pi))
continue;
- if (del && pi == del)
- continue;
-
if (pi->attr->flag
& ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
atomic_aggregate = 1;
* route MUST have the ORIGIN attribute with the value
* EGP.
*/
- if (origin < pi->attr->origin)
- origin = pi->attr->origin;
+ switch (pi->attr->origin) {
+ case BGP_ORIGIN_INCOMPLETE:
+ aggregate->incomplete_origin_count++;
+ break;
+ case BGP_ORIGIN_EGP:
+ aggregate->egp_origin_count++;
+ break;
+ default:
+ /*Do nothing.
+ */
+ break;
+ }
if (!aggregate->as_set)
continue;
* as-set aggregate route generate origin, as path,
* and community aggregation.
*/
- if (aspath) {
- asmerge = aspath_aggregate(aspath,
- pi->attr->aspath);
- aspath_free(aspath);
- aspath = asmerge;
- } else
- aspath = aspath_dup(pi->attr->aspath);
-
- if (pi->attr->community) {
- if (community) {
- commerge = community_merge(
- community, pi->attr->community);
- community =
- community_uniq_sort(commerge);
- community_free(&commerge);
- } else
- community = community_dup(
- pi->attr->community);
- }
-
- if (pi->attr->ecommunity) {
- if (ecommunity) {
- ecommerge = ecommunity_merge(
- ecommunity,
- pi->attr->ecommunity);
- ecommunity =
- ecommunity_uniq_sort(ecommerge);
- ecommunity_free(&ecommerge);
- } else
- ecommunity = ecommunity_dup(
- pi->attr->ecommunity);
- }
-
- if (pi->attr->lcommunity) {
- if (lcommunity) {
- lcommerge = lcommunity_merge(
- lcommunity,
- pi->attr->lcommunity);
- lcommunity =
- lcommunity_uniq_sort(lcommerge);
- lcommunity_free(&lcommerge);
- } else
- lcommunity = lcommunity_dup(
- pi->attr->lcommunity);
- }
+ /* Compute aggregate route's as-path.
+ */
+ bgp_compute_aggregate_aspath(aggregate,
+ pi->attr->aspath);
+
+ /* Compute aggregate route's community.
+ */
+ if (pi->attr->community)
+ bgp_compute_aggregate_community(
+ aggregate,
+ pi->attr->community);
+
+ /* Compute aggregate route's extended community.
+ */
+ if (pi->attr->ecommunity)
+ bgp_compute_aggregate_ecommunity(
+ aggregate,
+ pi->attr->ecommunity);
+
+ /* Compute aggregate route's large community.
+ */
+ if (pi->attr->lcommunity)
+ bgp_compute_aggregate_lcommunity(
+ aggregate,
+ pi->attr->lcommunity);
}
if (match)
bgp_process(bgp, rn, afi, safi);
}
bgp_unlock_node(top);
- if (pinew) {
- aggregate->count++;
- if (aggregate->summary_only)
- (bgp_path_info_extra_get(pinew))->suppress++;
+ if (aggregate->incomplete_origin_count > 0)
+ origin = BGP_ORIGIN_INCOMPLETE;
+ else if (aggregate->egp_origin_count > 0)
+ origin = BGP_ORIGIN_EGP;
- if (origin < pinew->attr->origin)
- origin = pinew->attr->origin;
+ if (aggregate->as_set) {
+ if (aggregate->aspath)
+ /* Retrieve aggregate route's as-path.
+ */
+ aspath = aspath_dup(aggregate->aspath);
- if (aggregate->as_set) {
- if (aspath) {
- asmerge = aspath_aggregate(aspath,
- pinew->attr->aspath);
- aspath_free(aspath);
- aspath = asmerge;
- } else
- aspath = aspath_dup(pinew->attr->aspath);
+ if (aggregate->community)
+ /* Retrieve aggregate route's community.
+ */
+ community = community_dup(aggregate->community);
- if (pinew->attr->community) {
- if (community) {
- commerge = community_merge(
- community,
- pinew->attr->community);
- community =
- community_uniq_sort(commerge);
- community_free(&commerge);
- } else
- community = community_dup(
- pinew->attr->community);
- }
+ if (aggregate->ecommunity)
+ /* Retrieve aggregate route's ecommunity.
+ */
+ ecommunity = ecommunity_dup(aggregate->ecommunity);
- if (pinew->attr->ecommunity) {
- if (ecommunity) {
- ecommerge = ecommunity_merge(
- ecommunity,
- pinew->attr->ecommunity);
- ecommunity =
- ecommunity_uniq_sort(ecommerge);
- ecommunity_free(&ecommerge);
- } else
- ecommunity = ecommunity_dup(
- pinew->attr->ecommunity);
- }
-
- if (pinew->attr->lcommunity) {
- if (lcommunity) {
- lcommerge = lcommunity_merge(
- lcommunity,
- pinew->attr->lcommunity);
- lcommunity =
- lcommunity_uniq_sort(lcommerge);
- lcommunity_free(&lcommerge);
- } else
- lcommunity = lcommunity_dup(
- pinew->attr->lcommunity);
- }
- }
+ if (aggregate->lcommunity)
+ /* Retrieve aggregate route's lcommunity.
+ */
+ lcommunity = lcommunity_dup(aggregate->lcommunity);
}
bgp_aggregate_install(bgp, afi, safi, p, origin, aspath, community,
ecommunity, lcommunity, atomic_aggregate,
aggregate);
-
- if (aggregate->count == 0) {
- if (aspath)
- aspath_free(aspath);
- if (community)
- community_free(&community);
- if (ecommunity)
- ecommunity_free(&ecommunity);
- if (lcommunity)
- lcommunity_free(&lcommunity);
- }
}
static void bgp_aggregate_delete(struct bgp *bgp, struct prefix *p, afi_t afi,
}
}
aggregate->count--;
+
+ if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
+ aggregate->incomplete_origin_count--;
+ else if (pi->attr->origin == BGP_ORIGIN_EGP)
+ aggregate->egp_origin_count--;
+
+ if (aggregate->as_set) {
+ /* Remove as-path from aggregate.
+ */
+ bgp_remove_aspath_from_aggregate(
+ aggregate,
+ pi->attr->aspath);
+
+ if (pi->attr->community)
+ /* Remove community from aggregate.
+ */
+ bgp_remove_community_from_aggregate(
+ aggregate,
+ pi->attr->community);
+
+ if (pi->attr->ecommunity)
+ /* Remove ecommunity from aggregate.
+ */
+ bgp_remove_ecommunity_from_aggregate(
+ aggregate,
+ pi->attr->ecommunity);
+
+ if (pi->attr->lcommunity)
+ /* Remove lcommunity from aggregate.
+ */
+ bgp_remove_lcommunity_from_aggregate(
+ aggregate,
+ pi->attr->lcommunity);
+ }
+
}
/* If this node was suppressed, process the change. */
bgp_unlock_node(top);
}
+static void bgp_add_route_to_aggregate(struct bgp *bgp, struct prefix *aggr_p,
+ struct bgp_path_info *pinew, afi_t afi,
+ safi_t safi,
+ struct bgp_aggregate *aggregate)
+{
+ uint8_t origin;
+ struct aspath *aspath = NULL;
+ uint8_t atomic_aggregate = 0;
+ struct community *community = NULL;
+ struct ecommunity *ecommunity = NULL;
+ struct lcommunity *lcommunity = NULL;
+
+ /* ORIGIN attribute: If at least one route among routes that are
+ * aggregated has ORIGIN with the value INCOMPLETE, then the
+ * aggregated route must have the ORIGIN attribute with the value
+ * INCOMPLETE. Otherwise, if at least one route among routes that
+ * are aggregated has ORIGIN with the value EGP, then the aggregated
+ * route must have the origin attribute with the value EGP. In all
+ * other case the value of the ORIGIN attribute of the aggregated
+ * route is INTERNAL.
+ */
+ origin = BGP_ORIGIN_IGP;
+
+ aggregate->count++;
+
+ if (aggregate->summary_only)
+ (bgp_path_info_extra_get(pinew))->suppress++;
+
+ switch (pinew->attr->origin) {
+ case BGP_ORIGIN_INCOMPLETE:
+ aggregate->incomplete_origin_count++;
+ break;
+ case BGP_ORIGIN_EGP:
+ aggregate->egp_origin_count++;
+ break;
+ default:
+ /* Do nothing.
+ */
+ break;
+ }
+
+ if (aggregate->incomplete_origin_count > 0)
+ origin = BGP_ORIGIN_INCOMPLETE;
+ else if (aggregate->egp_origin_count > 0)
+ origin = BGP_ORIGIN_EGP;
+
+ if (aggregate->as_set) {
+ /* Compute aggregate route's as-path.
+ */
+ bgp_compute_aggregate_aspath(aggregate,
+ pinew->attr->aspath);
+
+ /* Compute aggregate route's community.
+ */
+ if (pinew->attr->community)
+ bgp_compute_aggregate_community(
+ aggregate,
+ pinew->attr->community);
+
+ /* Compute aggregate route's extended community.
+ */
+ if (pinew->attr->ecommunity)
+ bgp_compute_aggregate_ecommunity(
+ aggregate,
+ pinew->attr->ecommunity);
+
+ /* Compute aggregate route's large community.
+ */
+ if (pinew->attr->lcommunity)
+ bgp_compute_aggregate_lcommunity(
+ aggregate,
+ pinew->attr->lcommunity);
+
+ /* Retrieve aggregate route's as-path.
+ */
+ if (aggregate->aspath)
+ aspath = aspath_dup(aggregate->aspath);
+
+ /* Retrieve aggregate route's community.
+ */
+ if (aggregate->community)
+ community = community_dup(aggregate->community);
+
+ /* Retrieve aggregate route's ecommunity.
+ */
+ if (aggregate->ecommunity)
+ ecommunity = ecommunity_dup(aggregate->ecommunity);
+
+ /* Retrieve aggregate route's lcommunity.
+ */
+ if (aggregate->lcommunity)
+ lcommunity = lcommunity_dup(aggregate->lcommunity);
+ }
+
+ bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
+ aspath, community, ecommunity,
+ lcommunity, atomic_aggregate, aggregate);
+}
+
+static void bgp_remove_route_from_aggregate(struct bgp *bgp, afi_t afi,
+ safi_t safi,
+ struct bgp_path_info *pi,
+ struct bgp_aggregate *aggregate,
+ struct prefix *aggr_p)
+{
+ uint8_t origin;
+ struct aspath *aspath = NULL;
+ uint8_t atomic_aggregate = 0;
+ struct community *community = NULL;
+ struct ecommunity *ecommunity = NULL;
+ struct lcommunity *lcommunity = NULL;
+ unsigned long match = 0;
+
+ if (BGP_PATH_HOLDDOWN(pi))
+ return;
+
+ if (pi->sub_type == BGP_ROUTE_AGGREGATE)
+ return;
+
+ if (aggregate->summary_only
+ && pi->extra
+ && pi->extra->suppress > 0) {
+ pi->extra->suppress--;
+
+ if (pi->extra->suppress == 0) {
+ bgp_path_info_set_flag(pi->net, pi,
+ BGP_PATH_ATTR_CHANGED);
+ match++;
+ }
+ }
+
+ if (aggregate->count > 0)
+ aggregate->count--;
+
+ if (pi->attr->origin == BGP_ORIGIN_INCOMPLETE)
+ aggregate->incomplete_origin_count--;
+ else if (pi->attr->origin == BGP_ORIGIN_EGP)
+ aggregate->egp_origin_count--;
+
+ if (aggregate->as_set) {
+ /* Remove as-path from aggregate.
+ */
+ bgp_remove_aspath_from_aggregate(aggregate,
+ pi->attr->aspath);
+
+ if (pi->attr->community)
+ /* Remove community from aggregate.
+ */
+ bgp_remove_community_from_aggregate(
+ aggregate,
+ pi->attr->community);
+
+ if (pi->attr->ecommunity)
+ /* Remove ecommunity from aggregate.
+ */
+ bgp_remove_ecommunity_from_aggregate(
+ aggregate,
+ pi->attr->ecommunity);
+
+ if (pi->attr->lcommunity)
+ /* Remove lcommunity from aggregate.
+ */
+ bgp_remove_lcommunity_from_aggregate(
+ aggregate,
+ pi->attr->lcommunity);
+ }
+
+ /* If this node was suppressed, process the change. */
+ if (match)
+ bgp_process(bgp, pi->net, afi, safi);
+
+ origin = BGP_ORIGIN_IGP;
+ if (aggregate->incomplete_origin_count > 0)
+ origin = BGP_ORIGIN_INCOMPLETE;
+ else if (aggregate->egp_origin_count > 0)
+ origin = BGP_ORIGIN_EGP;
+
+ if (aggregate->as_set) {
+ /* Retrieve aggregate route's as-path.
+ */
+ if (aggregate->aspath)
+ aspath = aspath_dup(aggregate->aspath);
+
+ /* Retrieve aggregate route's community.
+ */
+ if (aggregate->community)
+ community = community_dup(aggregate->community);
+
+ /* Retrieve aggregate route's ecommunity.
+ */
+ if (aggregate->ecommunity)
+ ecommunity = ecommunity_dup(aggregate->ecommunity);
+
+ /* Retrieve aggregate route's lcommunity.
+ */
+ if (aggregate->lcommunity)
+ lcommunity = lcommunity_dup(aggregate->lcommunity);
+ }
+
+ bgp_aggregate_install(bgp, afi, safi, aggr_p, origin,
+ aspath, community, ecommunity,
+ lcommunity, atomic_aggregate, aggregate);
+}
+
void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
struct bgp_path_info *pi, afi_t afi, safi_t safi)
{
for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
aggregate = bgp_node_get_bgp_aggregate_info(rn);
if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
- bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
- bgp_aggregate_route(bgp, &rn->p, pi, afi, safi, NULL,
- aggregate);
+ bgp_add_route_to_aggregate(bgp, &rn->p, pi, afi,
+ safi, aggregate);
}
}
bgp_unlock_node(child);
for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
aggregate = bgp_node_get_bgp_aggregate_info(rn);
if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
- bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
- bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
- aggregate);
+ bgp_remove_route_from_aggregate(bgp, afi, safi,
+ del, aggregate, &rn->p);
}
}
bgp_unlock_node(child);
/* Unlock aggregate address configuration. */
bgp_node_set_bgp_aggregate_info(rn, NULL);
+
+ if (aggregate->community)
+ community_free(&aggregate->community);
+
+ if (aggregate->community_hash) {
+ /* Delete all communities in the hash.
+ */
+ hash_clean(aggregate->community_hash,
+ bgp_aggr_community_remove);
+ /* Free up the community_hash.
+ */
+ hash_free(aggregate->community_hash);
+ }
+
+ if (aggregate->ecommunity)
+ ecommunity_free(&aggregate->ecommunity);
+
+ if (aggregate->ecommunity_hash) {
+ /* Delete all ecommunities in the hash.
+ */
+ hash_clean(aggregate->ecommunity_hash,
+ bgp_aggr_ecommunity_remove);
+ /* Free up the ecommunity_hash.
+ */
+ hash_free(aggregate->ecommunity_hash);
+ }
+
+ if (aggregate->lcommunity)
+ lcommunity_free(&aggregate->lcommunity);
+
+ if (aggregate->lcommunity_hash) {
+ /* Delete all lcommunities in the hash.
+ */
+ hash_clean(aggregate->lcommunity_hash,
+ bgp_aggr_lcommunity_remove);
+ /* Free up the lcommunity_hash.
+ */
+ hash_free(aggregate->lcommunity_hash);
+ }
+
+ if (aggregate->aspath)
+ aspath_free(aggregate->aspath);
+
+ if (aggregate->aspath_hash) {
+ /* Delete all as-paths in the hash.
+ */
+ hash_clean(aggregate->aspath_hash,
+ bgp_aggr_aspath_remove);
+ /* Free up the aspath_hash.
+ */
+ hash_free(aggregate->aspath_hash);
+ }
+
bgp_aggregate_free(aggregate);
bgp_unlock_node(rn);
bgp_unlock_node(rn);
bgp_node_set_bgp_aggregate_info(rn, aggregate);
/* Aggregate address insert into BGP routing table. */
- bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
+ bgp_aggregate_route(bgp, &p, afi, safi, aggregate);
return CMD_SUCCESS;
}
json_pmsi = json_object_new_object();
json_object_string_add(json_pmsi,
"tunnelType", str);
+ json_object_int_add(json_pmsi,
+ "label",
+ label2vni(&attr->label));
json_object_object_add(json_path, "pmsi",
json_pmsi);
} else
- vty_out(vty, " PMSI Tunnel Type: %s\n",
- str);
+ vty_out(vty,
+ " PMSI Tunnel Type: %s, label: %d\n",
+ str, label2vni(&attr->label));
}
}
return CMD_WARNING_CONFIG_FAILED;
}
- if (bdistance->access_list)
- XFREE(MTYPE_AS_LIST, bdistance->access_list);
+ XFREE(MTYPE_AS_LIST, bdistance->access_list);
bgp_distance_free(bdistance);
bgp_node_set_bgp_path_info(rn, NULL);
NULL, 0);
}
-static void show_bgp_peerhash_entry(struct hash_backet *backet, void *arg)
+static void show_bgp_peerhash_entry(struct hash_bucket *bucket, void *arg)
{
struct vty *vty = arg;
- struct peer *peer = backet->data;
+ struct peer *peer = bucket->data;
char buf[SU_ADDRSTRLEN];
vty_out(vty, "\tPeer: %s %s\n", peer->host,
decode_label(&bgp_static->label), esi, buf2,
macrouter);
- if (macrouter)
- XFREE(MTYPE_TMP, macrouter);
- if (esi)
- XFREE(MTYPE_TMP, esi);
+ XFREE(MTYPE_TMP, macrouter);
+ XFREE(MTYPE_TMP, esi);
}
}
}