diff options
Diffstat (limited to 'bgpd/bgp_zebra.c')
| -rw-r--r-- | bgpd/bgp_zebra.c | 64 |
1 files changed, 51 insertions, 13 deletions
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 04d520a923..95c89869a2 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -1687,12 +1687,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 +1713,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 +1767,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 +1782,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 && 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 +1791,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 +1876,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 +1895,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 +1905,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 +1925,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 +1933,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 +1968,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); } } } |
