summaryrefslogtreecommitdiff
path: root/bgpd/bgp_zebra.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_zebra.c')
-rw-r--r--bgpd/bgp_zebra.c81
1 files changed, 59 insertions, 22 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index fda92270a8..15ed98933e 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -1211,7 +1211,7 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
}
static bool bgp_zebra_use_nhop_weighted(struct bgp *bgp, struct attr *attr,
- uint32_t *nh_weight)
+ uint64_t *nh_weight)
{
/* zero link-bandwidth and link-bandwidth not present are treated
* as the same situation.
@@ -1273,7 +1273,7 @@ static void bgp_zebra_announce_parse_nexthop(
for (; mpinfo; mpinfo = bgp_path_info_mpath_next(mpinfo)) {
labels = NULL;
num_labels = 0;
- uint32_t nh_weight;
+ uint64_t nh_weight;
bool is_evpn;
bool is_parent_evpn;
@@ -1308,9 +1308,7 @@ static void bgp_zebra_announce_parse_nexthop(
else
api_nh = &api->backup_nexthops[*valid_nh_count];
- if (CHECK_FLAG(info->attr->flag,
- ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR)))
- api_nh->srte_color = bgp_attr_get_color(info->attr);
+ api_nh->srte_color = bgp_attr_get_color(info->attr);
if (bgp_debug_zebra(&api->prefix)) {
if (mpinfo->extra) {
@@ -1518,8 +1516,9 @@ static void bgp_debug_zebra_nh(struct zapi_route *api)
snprintf(eth_buf, sizeof(eth_buf), " RMAC %s",
prefix_mac2str(&api_nh->rmac, buf1,
sizeof(buf1)));
- zlog_debug(" nhop [%d]: %s if %u VRF %u wt %u %s %s %s", i + 1,
- nh_buf, api_nh->ifindex, api_nh->vrf_id,
+ zlog_debug(" nhop [%d]: %s if %u VRF %u wt %" PRIu64
+ " %s %s %s",
+ i + 1, nh_buf, api_nh->ifindex, api_nh->vrf_id,
api_nh->weight, label_buf, segs_buf, eth_buf);
}
}
@@ -1581,7 +1580,7 @@ bgp_zebra_announce_actual(struct bgp_dest *dest, struct bgp_path_info *info,
api.tableid = info->attr->rmap_table_id;
}
- if (CHECK_FLAG(info->attr->flag, ATTR_FLAG_BIT(BGP_ATTR_SRTE_COLOR)))
+ if (info->attr->srte_color)
SET_FLAG(api.message, ZAPI_MESSAGE_SRTE);
/* Metric is currently based on the best-path only */
@@ -1687,12 +1686,11 @@ void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi)
for (dest = bgp_table_top(table); dest; dest = bgp_route_next(dest))
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
-
(pi->type == ZEBRA_ROUTE_BGP
&& (pi->sub_type == BGP_ROUTE_NORMAL
|| pi->sub_type == BGP_ROUTE_IMPORTED)))
-
- bgp_zebra_route_install(dest, pi, bgp, true);
+ bgp_zebra_route_install(dest, pi, bgp, true,
+ NULL, false);
}
/* Announce routes of any bgp subtype of a table to zebra */
@@ -1714,7 +1712,8 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi,
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED) &&
pi->type == ZEBRA_ROUTE_BGP)
- bgp_zebra_route_install(dest, pi, bgp, true);
+ bgp_zebra_route_install(dest, pi, bgp, true,
+ NULL, false);
}
enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest,
@@ -1767,6 +1766,7 @@ enum zclient_send_status bgp_zebra_withdraw_actual(struct bgp_dest *dest,
#define ZEBRA_ANNOUNCEMENTS_LIMIT 1000
static void bgp_handle_route_announcements_to_zebra(struct event *e)
{
+ bool is_evpn = false;
uint32_t count = 0;
struct bgp_dest *dest = NULL;
struct bgp_table *table = NULL;
@@ -1781,6 +1781,8 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e)
table = bgp_dest_table(dest);
install = CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL);
+ if (table->afi == AFI_L2VPN && table->safi == SAFI_EVPN)
+ is_evpn = true;
if (BGP_DEBUG(zebra, ZEBRA))
zlog_debug("BGP %s route %pBD(%s) with dest %p and flags 0x%x to zebra",
@@ -1788,17 +1790,38 @@ static void bgp_handle_route_announcements_to_zebra(struct event *e)
table->bgp->name_pretty, dest, dest->flags);
if (install) {
- status = bgp_zebra_announce_actual(dest, dest->za_bgp_pi,
- table->bgp);
+ if (is_evpn)
+ status =
+ evpn_zebra_install(table->bgp,
+ dest->za_vpn,
+ (const struct prefix_evpn
+ *)
+ bgp_dest_get_prefix(
+ dest),
+ dest->za_bgp_pi);
+ else
+ status = bgp_zebra_announce_actual(dest,
+ dest->za_bgp_pi,
+ table->bgp);
UNSET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL);
} else {
- status = bgp_zebra_withdraw_actual(dest, dest->za_bgp_pi,
- table->bgp);
+ if (is_evpn)
+ status = evpn_zebra_uninstall(
+ table->bgp, dest->za_vpn,
+ (const struct prefix_evpn *)
+ bgp_dest_get_prefix(dest),
+ dest->za_bgp_pi, false);
+ else
+ status = bgp_zebra_withdraw_actual(dest,
+ dest->za_bgp_pi,
+ table->bgp);
+
UNSET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE);
}
bgp_path_info_unlock(dest->za_bgp_pi);
dest->za_bgp_pi = NULL;
+ dest->za_vpn = NULL;
bgp_dest_unlock_node(dest);
if (status == ZCLIENT_SEND_BUFFERED)
@@ -1852,8 +1875,16 @@ static void bgp_zebra_buffer_write_ready(void)
* withdrawn.
*/
void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info,
- struct bgp *bgp, bool install)
+ struct bgp *bgp, bool install, struct bgpevpn *vpn,
+ bool is_sync)
{
+ bool is_evpn = false;
+ struct bgp_table *table = NULL;
+
+ table = bgp_dest_table(dest);
+ if (table && table->afi == AFI_L2VPN && table->safi == SAFI_EVPN)
+ is_evpn = true;
+
/*
* BGP is installing this route and bgp has been configured
* to suppress announcements until the route has been installed
@@ -1863,7 +1894,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info,
if (BGP_SUPPRESS_FIB_ENABLED(bgp))
SET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
- if (bgp->main_zebra_update_hold)
+ if (bgp->main_zebra_update_hold && !is_evpn)
return;
} else {
UNSET_FLAG(dest->flags, BGP_NODE_FIB_INSTALL_PENDING);
@@ -1873,7 +1904,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info,
* Don't try to install if we're not connected to Zebra or Zebra doesn't
* know of this instance.
*/
- if (!bgp_install_info_to_zebra(bgp))
+ if (!bgp_install_info_to_zebra(bgp) && !is_evpn)
return;
if (!CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL) &&
@@ -1893,7 +1924,7 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info,
dest->za_bgp_pi = info;
} else if (CHECK_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE)) {
assert(dest->za_bgp_pi);
- if (install)
+ if (install & !is_evpn)
bgp_zebra_withdraw_actual(dest, dest->za_bgp_pi, bgp);
bgp_path_info_unlock(dest->za_bgp_pi);
@@ -1901,6 +1932,11 @@ void bgp_zebra_route_install(struct bgp_dest *dest, struct bgp_path_info *info,
dest->za_bgp_pi = info;
}
+ if (is_evpn) {
+ dest->za_vpn = vpn;
+ dest->za_is_sync = is_sync;
+ }
+
if (install) {
UNSET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_DELETE);
SET_FLAG(dest->flags, BGP_NODE_SCHEDULE_FOR_INSTALL);
@@ -1931,7 +1967,8 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) {
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
&& (pi->type == ZEBRA_ROUTE_BGP))
- bgp_zebra_route_install(dest, pi, bgp, false);
+ bgp_zebra_route_install(dest, pi, bgp, false,
+ NULL, false);
}
}
}
@@ -2116,7 +2153,7 @@ bool bgp_redistribute_metric_set(struct bgp *bgp, struct bgp_redist *red,
bgp_path_info_set_flag(dest, pi,
BGP_PATH_ATTR_CHANGED);
- bgp_process(bgp, dest, afi, SAFI_UNICAST);
+ bgp_process(bgp, dest, pi, afi, SAFI_UNICAST);
}
}
}