summaryrefslogtreecommitdiff
path: root/bgpd/bgp_route.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_route.c')
-rw-r--r--bgpd/bgp_route.c145
1 files changed, 97 insertions, 48 deletions
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index f8a29821d8..8d87f2cd04 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -241,6 +241,9 @@ void bgp_path_info_extra_free(struct bgp_path_info_extra **extra)
if (e->bgp_orig)
bgp_unlock(e->bgp_orig);
+ if (e->aggr_suppressors)
+ list_delete(&e->aggr_suppressors);
+
if ((*extra)->bgp_fs_iprule)
list_delete(&((*extra)->bgp_fs_iprule));
if ((*extra)->bgp_fs_pbr)
@@ -1439,14 +1442,15 @@ static bool bgp_community_filter(struct peer *peer, struct attr *attr)
static bool bgp_cluster_filter(struct peer *peer, struct attr *attr)
{
struct in_addr cluster_id;
+ struct cluster_list *cluster = bgp_attr_get_cluster(attr);
- if (attr->cluster) {
+ if (cluster) {
if (peer->bgp->config & BGP_CONFIG_CLUSTER_ID)
cluster_id = peer->bgp->cluster_id;
else
cluster_id = peer->bgp->router_id;
- if (cluster_loop_check(attr->cluster, cluster_id))
+ if (cluster_loop_check(cluster, cluster_id))
return true;
}
return false;
@@ -1500,7 +1504,7 @@ static int bgp_input_modifier(struct peer *peer, const struct prefix *p,
SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN);
/* Apply BGP route map to the attribute. */
- ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
+ ret = route_map_apply(rmap, p, &rmap_path);
peer->rmap_type = 0;
@@ -1551,7 +1555,7 @@ static int bgp_output_modifier(struct peer *peer, const struct prefix *p,
SET_FLAG(peer->rmap_type, PEER_RMAP_TYPE_OUT);
/* Apply BGP route map to the attribute. */
- ret = route_map_apply(rmap, p, RMAP_BGP, &rmap_path);
+ ret = route_map_apply(rmap, p, &rmap_path);
peer->rmap_type = rmap_type;
@@ -2047,10 +2051,10 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
if (bgp_path_suppressed(pi))
ret = route_map_apply(UNSUPPRESS_MAP(filter), p,
- RMAP_BGP, &rmap_path);
+ &rmap_path);
else
ret = route_map_apply(ROUTE_MAP_OUT(filter), p,
- RMAP_BGP, &rmap_path);
+ &rmap_path);
peer->rmap_type = 0;
@@ -2497,10 +2501,13 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp,
struct attr attr;
afi_t afi;
safi_t safi;
+ struct bgp *bgp;
+ bool advertise;
p = bgp_dest_get_prefix(dest);
afi = SUBGRP_AFI(subgrp);
safi = SUBGRP_SAFI(subgrp);
+ bgp = SUBGRP_INST(subgrp);
onlypeer = ((SUBGRP_PCOUNT(subgrp) == 1) ? (SUBGRP_PFIRST(subgrp))->peer
: NULL);
@@ -2515,13 +2522,23 @@ void subgroup_process_announce_selected(struct update_subgroup *subgrp,
memset(&attr, 0, sizeof(struct attr));
/* It's initialized in bgp_announce_check() */
- /* Announcement to the subgroup. If the route is filtered withdraw it.
+ /* Announcement to the subgroup. If the route is filtered withdraw it.
+ * If BGP_NODE_FIB_INSTALL_PENDING is set and data plane install status
+ * is pending (BGP_NODE_FIB_INSTALL_PENDING), do not advertise the
+ * route
*/
+ advertise = bgp_check_advertise(bgp, dest);
+
if (selected) {
if (subgroup_announce_check(dest, selected, subgrp, p, &attr,
- false))
- bgp_adj_out_set_subgroup(dest, subgrp, &attr, selected);
- else
+ false)) {
+ /* Route is selected, if the route is already installed
+ * in FIB, then it is advertised
+ */
+ if (advertise)
+ bgp_adj_out_set_subgroup(dest, subgrp, &attr,
+ selected);
+ } else
bgp_adj_out_unset_subgroup(dest, subgrp, 1,
addpath_tx_id);
}
@@ -2620,7 +2637,7 @@ static void bgp_process_evpn_route_injection(struct bgp *bgp, afi_t afi,
RESET_FLAG(dummy_attr.rmap_change_flags);
ret = route_map_apply(bgp->adv_cmd_rmap[afi][safi].map,
- p, RMAP_BGP, &rmap_path);
+ p, &rmap_path);
if (ret == RMAP_DENYMATCH) {
bgp_attr_flush(&dummy_attr);
@@ -3370,17 +3387,22 @@ static void overlay_index_update(struct attr *attr,
if (!attr)
return;
if (gw_ip == NULL) {
- memset(&(attr->evpn_overlay.gw_ip), 0, sizeof(union gw_addr));
+ struct bgp_route_evpn eo;
+
+ memset(&eo, 0, sizeof(eo));
+ bgp_attr_set_evpn_overlay(attr, &eo);
} else {
- memcpy(&(attr->evpn_overlay.gw_ip), gw_ip,
- sizeof(union gw_addr));
+ struct bgp_route_evpn eo = {.gw_ip = *gw_ip};
+
+ bgp_attr_set_evpn_overlay(attr, &eo);
}
}
static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
union gw_addr *gw_ip)
{
- union gw_addr *path_gw_ip, *path_gw_ip_remote;
+ const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(path->attr);
+ union gw_addr path_gw_ip, *path_gw_ip_remote;
union {
esi_t esi;
union gw_addr ip;
@@ -3389,7 +3411,7 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
if (afi != AFI_L2VPN)
return true;
- path_gw_ip = &(path->attr->evpn_overlay.gw_ip);
+ path_gw_ip = eo->gw_ip;
if (gw_ip == NULL) {
memset(&temp, 0, sizeof(temp));
@@ -3397,7 +3419,7 @@ static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path,
} else
path_gw_ip_remote = gw_ip;
- return !!memcmp(path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
+ return !!memcmp(&path_gw_ip, path_gw_ip_remote, sizeof(union gw_addr));
}
/* Check if received nexthop is valid or not. */
@@ -3525,6 +3547,22 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
else
has_valid_label = bgp_is_valid_label(label);
+ if (has_valid_label)
+ assert(label != NULL);
+
+ /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following
+ * condition :
+ * Suppress fib is enabled
+ * BGP_OPT_NO_FIB is not enabled
+ * Route type is BGP_ROUTE_NORMAL (peer learnt routes)
+ * Route is being installed first time (BGP_NODE_FIB_INSTALLED not set)
+ */
+ if (BGP_SUPPRESS_FIB_ENABLED(bgp) &&
+ (sub_type == BGP_ROUTE_NORMAL) &&
+ (!bgp_option_check(BGP_OPT_NO_FIB)) &&
+ (!CHECK_FLAG(dest->flags, BGP_NODE_FIB_INSTALLED)))
+ SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
+
/* When peer's soft reconfiguration enabled. Record input packet in
Adj-RIBs-In. */
if (!soft_reconfig
@@ -4480,7 +4518,8 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
if (num_labels)
label_pnt = &pi->extra->label[0];
if (pi)
- memcpy(&evpn, &pi->attr->evpn_overlay,
+ memcpy(&evpn,
+ bgp_attr_get_evpn_overlay(pi->attr),
sizeof(evpn));
else
memset(&evpn, 0, sizeof(evpn));
@@ -5189,8 +5228,7 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
- &rmap_path);
+ ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
bgp->peer_self->rmap_type = 0;
@@ -5509,8 +5547,7 @@ static void bgp_static_update_safi(struct bgp *bgp, const struct prefix *p,
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_NETWORK);
- ret = route_map_apply(bgp_static->rmap.map, p, RMAP_BGP,
- &rmap_path);
+ ret = route_map_apply(bgp_static->rmap.map, p, &rmap_path);
bgp->peer_self->rmap_type = 0;
@@ -6361,7 +6398,7 @@ static bool aggr_suppress_map_test(struct bgp *bgp,
rmap_path.attr = &attr;
SET_FLAG(bgp->peer_self->rmap_type, PEER_RMAP_TYPE_AGGREGATE);
- rmr = route_map_apply(aggregate->suppress_map, p, RMAP_BGP, &rmap_path);
+ rmr = route_map_apply(aggregate->suppress_map, p, &rmap_path);
bgp->peer_self->rmap_type = 0;
bgp_attr_flush(&attr);
@@ -6789,6 +6826,12 @@ void bgp_aggregate_route(struct bgp *bgp, const struct prefix *p, afi_t afi,
if (dest_p->prefixlen <= p->prefixlen)
continue;
+ /* If suppress fib is enabled and route not installed
+ * in FIB, skip the route
+ */
+ if (!bgp_check_advertise(bgp, dest))
+ continue;
+
match = 0;
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
@@ -7284,6 +7327,12 @@ void bgp_aggregate_increment(struct bgp *bgp, const struct prefix *p,
if (BGP_PATH_HOLDDOWN(pi))
return;
+ /* If suppress fib is enabled and route not installed
+ * in FIB, do not update the aggregate route
+ */
+ if (!bgp_check_advertise(bgp, pi->net))
+ return;
+
child = bgp_node_get(table, p);
/* Aggregate address configuration check. */
@@ -7807,8 +7856,7 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,
SET_FLAG(bgp->peer_self->rmap_type,
PEER_RMAP_TYPE_REDISTRIBUTE);
- ret = route_map_apply(red->rmap.map, p, RMAP_BGP,
- &rmap_path);
+ ret = route_map_apply(red->rmap.map, p, &rmap_path);
bgp->peer_self->rmap_type = 0;
@@ -8926,13 +8974,12 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
}
}
- if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p)) {
- inet_ntop(AF_INET, &(attr->evpn_overlay.gw_ip.ipv4), buf,
- BUFSIZ);
- } else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p)) {
- inet_ntop(AF_INET6, &(attr->evpn_overlay.gw_ip.ipv6), buf,
- BUFSIZ);
- }
+ const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr);
+
+ if (is_evpn_prefix_ipaddr_v4((struct prefix_evpn *)p))
+ inet_ntop(AF_INET, &eo->gw_ip.ipv4, buf, BUFSIZ);
+ else if (is_evpn_prefix_ipaddr_v6((struct prefix_evpn *)p))
+ inet_ntop(AF_INET6, &eo->gw_ip.ipv6, buf, BUFSIZ);
if (!json_path)
vty_out(vty, "/%s", buf);
@@ -10018,6 +10065,8 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
}
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)) {
+ struct cluster_list *cluster =
+ bgp_attr_get_cluster(attr);
int i;
if (json_paths) {
@@ -10025,13 +10074,11 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
json_cluster_list_list =
json_object_new_array();
- for (i = 0; i < attr->cluster->length / 4;
- i++) {
+ for (i = 0; i < cluster->length / 4; i++) {
json_string = json_object_new_string(
- inet_ntop(
- AF_INET,
- &attr->cluster->list[i],
- buf, sizeof(buf)));
+ inet_ntop(AF_INET,
+ &cluster->list[i],
+ buf, sizeof(buf)));
json_object_array_add(
json_cluster_list_list,
json_string);
@@ -10043,7 +10090,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
* do. Add this someday if someone asks
* for it.
* json_object_string_add(json_cluster_list,
- * "string", attr->cluster->str);
+ * "string", cluster->str);
*/
json_object_object_add(json_cluster_list,
"list",
@@ -10053,10 +10100,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
} else {
vty_out(vty, ", Cluster list: ");
- for (i = 0; i < attr->cluster->length / 4;
- i++) {
+ for (i = 0; i < cluster->length / 4; i++) {
vty_out(vty, "%pI4 ",
- &attr->cluster->list[i]);
+ &cluster->list[i]);
}
}
}
@@ -10183,9 +10229,9 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp,
/* Line 10 display PMSI tunnel attribute, if present */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL)) {
- const char *str =
- lookup_msg(bgp_pmsi_tnltype_str, attr->pmsi_tnl_type,
- PMSI_TNLTYPE_STR_DEFAULT);
+ const char *str = lookup_msg(bgp_pmsi_tnltype_str,
+ bgp_attr_get_pmsi_tnl_type(attr),
+ PMSI_TNLTYPE_STR_DEFAULT);
if (json_paths) {
json_pmsi = json_object_new_object();
@@ -10354,8 +10400,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
path.peer = pi->peer;
path.attr = &dummy_attr;
- ret = route_map_apply(rmap, dest_p, RMAP_BGP,
- &path);
+ ret = route_map_apply(rmap, dest_p, &path);
if (ret == RMAP_DENYMATCH)
continue;
}
@@ -11168,6 +11213,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
char *str;
int first = 0;
uint8_t show_flags = 0;
+ int ret;
if (uj)
SET_FLAG(show_flags, BGP_SHOW_OPT_JSON);
@@ -11195,10 +11241,13 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
return CMD_WARNING;
}
- return bgp_show(vty, bgp, afi, safi,
+ ret = bgp_show(vty, bgp, afi, safi,
(exact ? bgp_show_type_lcommunity_exact
: bgp_show_type_lcommunity),
lcom, show_flags);
+
+ lcommunity_free(&lcom);
+ return ret;
}
static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,