forked from Mirror/frr
bgpd: add EVPN reimport handler for martian change
Adds a generalized martian reimport function used for triggering a relearn/reimport of EVPN routes that were previously filtered/deleted as a result of a "self" check (either during import or by a martian change handler). The MAC-VRF SoO is the first consumer of this function, but can be expanded for use with Martian Tunnel-IPs, Interface-IPs, Interface-MACs, and RMACs. Signed-off-by: Trey Aspelund <taspelund@nvidia.com>
This commit is contained in:
parent
67b493a5b3
commit
badc4857aa
|
@ -5185,3 +5185,18 @@ enum bgp_attr_parse_ret bgp_attr_ignore(struct peer *peer, uint8_t type)
|
||||||
|
|
||||||
return withdraw ? BGP_ATTR_PARSE_WITHDRAW : BGP_ATTR_PARSE_PROCEED;
|
return withdraw ? BGP_ATTR_PARSE_WITHDRAW : BGP_ATTR_PARSE_PROCEED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool route_matches_soo(struct bgp_path_info *pi, struct ecommunity *soo)
|
||||||
|
{
|
||||||
|
struct attr *attr = pi->attr;
|
||||||
|
struct ecommunity *ecom;
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ecom = attr->ecommunity;
|
||||||
|
if (!ecom || !ecom->size)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return soo_in_ecom(ecom, soo);
|
||||||
|
}
|
||||||
|
|
|
@ -637,4 +637,6 @@ bgp_attr_set_vnc_subtlvs(struct attr *attr,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern bool route_matches_soo(struct bgp_path_info *pi, struct ecommunity *soo);
|
||||||
|
|
||||||
#endif /* _QUAGGA_BGP_ATTR_H */
|
#endif /* _QUAGGA_BGP_ATTR_H */
|
||||||
|
|
279
bgpd/bgp_evpn.c
279
bgpd/bgp_evpn.c
|
@ -41,6 +41,7 @@
|
||||||
#include "bgpd/bgp_nht.h"
|
#include "bgpd/bgp_nht.h"
|
||||||
#include "bgpd/bgp_trace.h"
|
#include "bgpd/bgp_trace.h"
|
||||||
#include "bgpd/bgp_mpath.h"
|
#include "bgpd/bgp_mpath.h"
|
||||||
|
#include "bgpd/bgp_packet.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Definitions and external declarations.
|
* Definitions and external declarations.
|
||||||
|
@ -2688,6 +2689,21 @@ int update_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update Type-2/3 Routes for L2VNI.
|
||||||
|
* Called by hash_iterate()
|
||||||
|
*/
|
||||||
|
static void update_routes_for_vni_hash(struct hash_bucket *bucket,
|
||||||
|
struct bgp *bgp)
|
||||||
|
{
|
||||||
|
struct bgpevpn *vpn;
|
||||||
|
|
||||||
|
if (!bucket)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vpn = (struct bgpevpn *)bucket->data;
|
||||||
|
update_routes_for_vni(bgp, vpn);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delete (and withdraw) local routes for specified VNI from the global
|
* Delete (and withdraw) local routes for specified VNI from the global
|
||||||
* table and per-VNI table. After this, remove all other routes from
|
* table and per-VNI table. After this, remove all other routes from
|
||||||
|
@ -3530,19 +3546,12 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool route_matches_macvrf_soo(struct bgp_path_info *pi,
|
static bool bgp_evpn_route_matches_macvrf_soo(struct bgp_path_info *pi,
|
||||||
const struct prefix_evpn *evp)
|
const struct prefix_evpn *evp)
|
||||||
{
|
{
|
||||||
struct bgp *bgp_evpn = bgp_get_evpn();
|
struct bgp *bgp_evpn = bgp_get_evpn();
|
||||||
struct attr *attr = pi->attr;
|
struct ecommunity *macvrf_soo;
|
||||||
struct ecommunity *ecom, *macvrf_soo;
|
bool ret = false;
|
||||||
|
|
||||||
if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ecom = attr->ecommunity;
|
|
||||||
if (!ecom || !ecom->size)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (!bgp_evpn->evpn_info)
|
if (!bgp_evpn->evpn_info)
|
||||||
return false;
|
return false;
|
||||||
|
@ -3556,23 +3565,20 @@ static bool route_matches_macvrf_soo(struct bgp_path_info *pi,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
macvrf_soo = bgp_evpn->evpn_info->soo;
|
macvrf_soo = bgp_evpn->evpn_info->soo;
|
||||||
|
ret = route_matches_soo(pi, macvrf_soo);
|
||||||
|
|
||||||
/* Fail import check if route is carrying the MAC-VRF SoO */
|
if (ret && bgp_debug_zebra(NULL)) {
|
||||||
if (soo_in_ecom(ecom, macvrf_soo)) {
|
char *ecom_str;
|
||||||
if (bgp_debug_zebra(NULL)) {
|
|
||||||
char *ecom_str;
|
|
||||||
|
|
||||||
ecom_str = ecommunity_ecom2str(
|
ecom_str = ecommunity_ecom2str(macvrf_soo,
|
||||||
macvrf_soo, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"import of evpn prefix %pFX skipped, local mac-vrf soo %s",
|
"import of evpn prefix %pFX skipped, local mac-vrf soo %s",
|
||||||
evp, ecom_str);
|
evp, ecom_str);
|
||||||
ecommunity_strfree(&ecom_str);
|
ecommunity_strfree(&ecom_str);
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This API will scan evpn routes for checking attribute's rmac
|
/* This API will scan evpn routes for checking attribute's rmac
|
||||||
|
@ -3662,7 +3668,7 @@ int bgp_evpn_route_entry_install_if_vrf_match(struct bgp *bgp_vrf,
|
||||||
/* don't import hosts that are locally attached */
|
/* don't import hosts that are locally attached */
|
||||||
if (install && (bgp_evpn_skip_vrf_import_of_local_es(
|
if (install && (bgp_evpn_skip_vrf_import_of_local_es(
|
||||||
bgp_vrf, evp, pi, install) ||
|
bgp_vrf, evp, pi, install) ||
|
||||||
route_matches_macvrf_soo(pi, evp)))
|
bgp_evpn_route_matches_macvrf_soo(pi, evp)))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (install)
|
if (install)
|
||||||
|
@ -3795,7 +3801,8 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (install) {
|
if (install) {
|
||||||
if (route_matches_macvrf_soo(pi, evp))
|
if (bgp_evpn_route_matches_macvrf_soo(
|
||||||
|
pi, evp))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = install_evpn_route_entry(bgp, vpn,
|
ret = install_evpn_route_entry(bgp, vpn,
|
||||||
|
@ -4027,7 +4034,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi,
|
||||||
/* Filter routes carrying a Site-of-Origin that matches our
|
/* Filter routes carrying a Site-of-Origin that matches our
|
||||||
* local MAC-VRF SoO.
|
* local MAC-VRF SoO.
|
||||||
*/
|
*/
|
||||||
if (import && route_matches_macvrf_soo(pi, evp))
|
if (import && bgp_evpn_route_matches_macvrf_soo(pi, evp))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* An EVPN route belongs to a VNI or a VRF or an ESI based on the RTs
|
/* An EVPN route belongs to a VNI or a VRF or an ESI based on the RTs
|
||||||
|
@ -5577,65 +5584,44 @@ void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
|
||||||
update_advertise_vni_routes(bgp, vpn);
|
update_advertise_vni_routes(bgp, vpn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/* "mac-vrf soo" vty handler
|
||||||
* Handle change to the global MAC-VRF Site-of-Origin:
|
* Handle change to the global MAC-VRF Site-of-Origin:
|
||||||
* - Unimport routes with new SoO from VNI/VRF
|
* - Unimport routes with new SoO from VNI/VRF
|
||||||
* - Import routes with old SoO into VNI/VRF
|
* - Import routes with old SoO into VNI/VRF
|
||||||
* - Update SoO on local VNI routes + re-advertise
|
* - Update SoO on local VNI routes + re-advertise
|
||||||
*/
|
*/
|
||||||
static void bgp_evpn_update_vni_macvrf_soo(struct hash_bucket *bucket,
|
|
||||||
struct bgp *bgp)
|
|
||||||
{
|
|
||||||
struct bgpevpn *vpn;
|
|
||||||
|
|
||||||
if (bucket) {
|
|
||||||
/* L2VNI */
|
|
||||||
vpn = (struct bgpevpn *)bucket->data;
|
|
||||||
if (is_vni_live(vpn)) {
|
|
||||||
/* TODO: handle updates more gracefully */
|
|
||||||
bgp_evpn_uninstall_routes(bgp, vpn);
|
|
||||||
bgp_evpn_install_routes(bgp, vpn);
|
|
||||||
update_routes_for_vni(bgp, vpn);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* L3VNI */
|
|
||||||
if (is_l3vni_live(bgp)) {
|
|
||||||
/* TODO: handle updates more gracefully */
|
|
||||||
uninstall_routes_for_vrf(bgp);
|
|
||||||
install_routes_for_vrf(bgp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* global "mac-vrf soo" vty handler */
|
|
||||||
void bgp_evpn_handle_global_macvrf_soo_change(struct bgp *bgp,
|
void bgp_evpn_handle_global_macvrf_soo_change(struct bgp *bgp,
|
||||||
struct ecommunity *new_soo)
|
struct ecommunity *new_soo)
|
||||||
{
|
{
|
||||||
struct ecommunity *old_soo;
|
struct ecommunity *old_soo;
|
||||||
struct listnode *node, *nnode;
|
|
||||||
struct bgp *tmp_bgp_vrf;
|
|
||||||
|
|
||||||
old_soo = bgp->evpn_info->soo;
|
old_soo = bgp->evpn_info->soo;
|
||||||
|
|
||||||
/* cleanup and bail out if old/new soo are the same */
|
/* cleanup and bail out if old_soo == new_soo */
|
||||||
if (ecommunity_match(old_soo, new_soo)) {
|
if (ecommunity_match(old_soo, new_soo)) {
|
||||||
ecommunity_free(&new_soo);
|
ecommunity_free(&new_soo);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* clear old soo + set new soo */
|
/* set new_soo */
|
||||||
ecommunity_free(&bgp->evpn_info->soo);
|
|
||||||
bgp->evpn_info->soo = new_soo;
|
bgp->evpn_info->soo = new_soo;
|
||||||
|
|
||||||
/* walk L2VNIs */
|
/* Unimport routes matching the new_soo */
|
||||||
|
bgp_filter_evpn_routes_upon_martian_change(bgp, BGP_MARTIAN_SOO);
|
||||||
|
|
||||||
|
/* Reimport routes with old_soo and !new_soo.
|
||||||
|
*/
|
||||||
|
bgp_reimport_evpn_routes_upon_martian_change(
|
||||||
|
bgp, BGP_MARTIAN_SOO, (void *)old_soo, (void *)new_soo);
|
||||||
|
|
||||||
|
/* Update locally originated routes for all L2VNIs */
|
||||||
hash_iterate(bgp->vnihash,
|
hash_iterate(bgp->vnihash,
|
||||||
(void (*)(struct hash_bucket *,
|
(void (*)(struct hash_bucket *,
|
||||||
void *))bgp_evpn_update_vni_macvrf_soo,
|
void *))update_routes_for_vni_hash,
|
||||||
bgp);
|
bgp);
|
||||||
|
|
||||||
/* walk L3VNIs */
|
/* clear old_soo */
|
||||||
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, tmp_bgp_vrf))
|
ecommunity_free(&old_soo);
|
||||||
bgp_evpn_update_vni_macvrf_soo(NULL, tmp_bgp_vrf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6205,7 +6191,84 @@ int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
return install_uninstall_evpn_route(bgp, afi, safi, p, pi, 0);
|
return install_uninstall_evpn_route(bgp, afi, safi, p, pi, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Filter learned (!local) EVPN routes carrying attributes pointing to "self".
|
/* Refresh previously-discarded EVPN routes carrying "self" MAC-VRF SoO.
|
||||||
|
* Walk global EVPN rib + import remote routes with old_soo && !new_soo.
|
||||||
|
*/
|
||||||
|
void bgp_reimport_evpn_routes_upon_macvrf_soo_change(struct bgp *bgp,
|
||||||
|
struct ecommunity *old_soo,
|
||||||
|
struct ecommunity *new_soo)
|
||||||
|
{
|
||||||
|
afi_t afi;
|
||||||
|
safi_t safi;
|
||||||
|
struct bgp_dest *rd_dest, *dest;
|
||||||
|
struct bgp_table *table;
|
||||||
|
struct bgp_path_info *pi;
|
||||||
|
|
||||||
|
afi = AFI_L2VPN;
|
||||||
|
safi = SAFI_EVPN;
|
||||||
|
|
||||||
|
/* EVPN routes are a 2-level table: outer=prefix_rd, inner=prefix_evpn.
|
||||||
|
* A remote route could have any RD, so we need to walk them all.
|
||||||
|
*/
|
||||||
|
for (rd_dest = bgp_table_top(bgp->rib[afi][safi]); rd_dest;
|
||||||
|
rd_dest = bgp_route_next(rd_dest)) {
|
||||||
|
table = bgp_dest_get_bgp_table_info(rd_dest);
|
||||||
|
if (!table)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (dest = bgp_table_top(table); dest;
|
||||||
|
dest = bgp_route_next(dest)) {
|
||||||
|
const struct prefix *p;
|
||||||
|
struct prefix_evpn *evp;
|
||||||
|
|
||||||
|
p = bgp_dest_get_prefix(dest);
|
||||||
|
evp = (struct prefix_evpn *)p;
|
||||||
|
|
||||||
|
/* On export we only add MAC-VRF SoO to RT-2/3, so we
|
||||||
|
* can skip evaluation of other RTs.
|
||||||
|
*/
|
||||||
|
if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE &&
|
||||||
|
evp->prefix.route_type != BGP_EVPN_IMET_ROUTE)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (pi = bgp_dest_get_bgp_path_info(dest); pi;
|
||||||
|
pi = pi->next) {
|
||||||
|
bool old_soo_fnd = false;
|
||||||
|
bool new_soo_fnd = false;
|
||||||
|
|
||||||
|
/* Only consider routes learned from peers */
|
||||||
|
if (!(pi->type == ZEBRA_ROUTE_BGP &&
|
||||||
|
pi->sub_type == BGP_ROUTE_NORMAL))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
old_soo_fnd = route_matches_soo(pi, old_soo);
|
||||||
|
new_soo_fnd = route_matches_soo(pi, new_soo);
|
||||||
|
|
||||||
|
if (old_soo_fnd && !new_soo_fnd) {
|
||||||
|
if (bgp_debug_update(pi->peer, p, NULL,
|
||||||
|
1)) {
|
||||||
|
char attr_str[BUFSIZ] = {0};
|
||||||
|
|
||||||
|
bgp_dump_attr(pi->attr,
|
||||||
|
attr_str, BUFSIZ);
|
||||||
|
|
||||||
|
zlog_debug(
|
||||||
|
"mac-vrf soo changed: evaluating reimport of prefix %pBD with attr %s",
|
||||||
|
dest, attr_str);
|
||||||
|
}
|
||||||
|
|
||||||
|
bgp_evpn_import_route(bgp, afi, safi, p,
|
||||||
|
pi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Filter learned (!local) EVPN routes carrying "self" attributes.
|
||||||
* Walk the Global EVPN loc-rib unimporting martian routes from the appropriate
|
* Walk the Global EVPN loc-rib unimporting martian routes from the appropriate
|
||||||
* L2VNIs (MAC-VRFs) / L3VNIs (IP-VRFs), and deleting them from the Global
|
* L2VNIs (MAC-VRFs) / L3VNIs (IP-VRFs), and deleting them from the Global
|
||||||
* loc-rib when applicable (based on martian_type).
|
* loc-rib when applicable (based on martian_type).
|
||||||
|
@ -6234,9 +6297,11 @@ void bgp_filter_evpn_routes_upon_martian_change(
|
||||||
struct bgp_dest *rd_dest, *dest;
|
struct bgp_dest *rd_dest, *dest;
|
||||||
struct bgp_table *table;
|
struct bgp_table *table;
|
||||||
struct bgp_path_info *pi;
|
struct bgp_path_info *pi;
|
||||||
|
struct ecommunity *macvrf_soo;
|
||||||
|
|
||||||
afi = AFI_L2VPN;
|
afi = AFI_L2VPN;
|
||||||
safi = SAFI_EVPN;
|
safi = SAFI_EVPN;
|
||||||
|
macvrf_soo = bgp->evpn_info->soo;
|
||||||
|
|
||||||
/* EVPN routes are a 2-level table: outer=prefix_rd, inner=prefix_evpn.
|
/* EVPN routes are a 2-level table: outer=prefix_rd, inner=prefix_evpn.
|
||||||
* A remote route could have any RD, so we need to walk them all.
|
* A remote route could have any RD, so we need to walk them all.
|
||||||
|
@ -6269,8 +6334,8 @@ void bgp_filter_evpn_routes_upon_martian_change(
|
||||||
pi->sub_type, pi->attr, dest);
|
pi->sub_type, pi->attr, dest);
|
||||||
break;
|
break;
|
||||||
case BGP_MARTIAN_SOO:
|
case BGP_MARTIAN_SOO:
|
||||||
affected = route_matches_macvrf_soo(
|
affected = route_matches_soo(
|
||||||
pi, (struct prefix_evpn *)p);
|
pi, macvrf_soo);
|
||||||
break;
|
break;
|
||||||
case BGP_MARTIAN_IF_IP:
|
case BGP_MARTIAN_IF_IP:
|
||||||
case BGP_MARTIAN_IF_MAC:
|
case BGP_MARTIAN_IF_MAC:
|
||||||
|
@ -6318,6 +6383,88 @@ void bgp_filter_evpn_routes_upon_martian_change(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Refresh previously-discarded EVPN routes carrying "self" attributes.
|
||||||
|
* This function is the handler for deleted martian entries, which is triggered
|
||||||
|
* by events occurring on the local system,
|
||||||
|
* e.g.
|
||||||
|
* - Del MAC-VRF Site-of-Origin
|
||||||
|
* + bgp_evpn_handle_global_macvrf_soo_change
|
||||||
|
* This will likely be extended in the future to cover these events too:
|
||||||
|
* - Del VTEP-IP
|
||||||
|
* + bgp_zebra_process_local_vni
|
||||||
|
* + bgp_zebra_process_local_l3vni
|
||||||
|
* - Del Interface IP
|
||||||
|
* + bgp_interface_address_delete
|
||||||
|
* - Del Interface MAC
|
||||||
|
* + bgp_ifp_down
|
||||||
|
* + bgp_ifp_destroy
|
||||||
|
* - Del RMAC
|
||||||
|
* + bgp_zebra_process_local_l3vni
|
||||||
|
*/
|
||||||
|
void bgp_reimport_evpn_routes_upon_martian_change(
|
||||||
|
struct bgp *bgp, enum bgp_martian_type martian_type, void *old_martian,
|
||||||
|
void *new_martian)
|
||||||
|
{
|
||||||
|
struct listnode *node;
|
||||||
|
struct peer *peer;
|
||||||
|
safi_t safi;
|
||||||
|
afi_t afi;
|
||||||
|
struct ecommunity *old_soo, *new_soo;
|
||||||
|
|
||||||
|
afi = AFI_L2VPN;
|
||||||
|
safi = SAFI_EVPN;
|
||||||
|
|
||||||
|
/* Self-SoO routes are held in the global EVPN loc-rib, so we can
|
||||||
|
* reimport routes w/o triggering soft-reconfig/route-refresh.
|
||||||
|
*/
|
||||||
|
if (martian_type == BGP_MARTIAN_SOO) {
|
||||||
|
old_soo = (struct ecommunity *)old_martian;
|
||||||
|
new_soo = (struct ecommunity *)new_martian;
|
||||||
|
|
||||||
|
/* If !old_soo, then we can skip the reimport because we
|
||||||
|
* wouldn't have filtered anything via the self-SoO import check
|
||||||
|
*/
|
||||||
|
if (old_martian)
|
||||||
|
bgp_reimport_evpn_routes_upon_macvrf_soo_change(
|
||||||
|
bgp, old_soo, new_soo);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Self-TIP/IP/MAC/RMAC routes are deleted from the global EVPN
|
||||||
|
* loc-rib, so we need to re-learn the routes via soft-reconfig/
|
||||||
|
* route-refresh.
|
||||||
|
*/
|
||||||
|
for (ALL_LIST_ELEMENTS_RO(bgp->peer, node, peer)) {
|
||||||
|
|
||||||
|
if (CHECK_FLAG(peer->sflags, PEER_STATUS_GROUP))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (peer->status != Established)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (CHECK_FLAG(peer->af_flags[afi][safi],
|
||||||
|
PEER_FLAG_SOFT_RECONFIG)) {
|
||||||
|
if (bgp_debug_update(peer, NULL, NULL, 1))
|
||||||
|
zlog_debug(
|
||||||
|
"Processing EVPN Martian/%s change on peer %s (inbound, soft-reconfig)",
|
||||||
|
bgp_martian_type2str(martian_type),
|
||||||
|
peer->host);
|
||||||
|
|
||||||
|
bgp_soft_reconfig_in(peer, afi, safi);
|
||||||
|
} else {
|
||||||
|
if (bgp_debug_update(peer, NULL, NULL, 1))
|
||||||
|
zlog_debug(
|
||||||
|
"Processing EVPN Martian/%s change on peer %s",
|
||||||
|
bgp_martian_type2str(martian_type),
|
||||||
|
peer->host);
|
||||||
|
bgp_route_refresh_send(peer, afi, safi, 0,
|
||||||
|
REFRESH_IMMEDIATE, 0,
|
||||||
|
BGP_ROUTE_REFRESH_NORMAL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Handle del of a local MACIP.
|
* Handle del of a local MACIP.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -158,6 +158,13 @@ extern int bgp_evpn_unimport_route(struct bgp *bgp, afi_t afi, safi_t safi,
|
||||||
const struct prefix *p,
|
const struct prefix *p,
|
||||||
struct bgp_path_info *ri);
|
struct bgp_path_info *ri);
|
||||||
extern void
|
extern void
|
||||||
|
bgp_reimport_evpn_routes_upon_macvrf_soo_change(struct bgp *bgp,
|
||||||
|
struct ecommunity *old_soo,
|
||||||
|
struct ecommunity *new_soo);
|
||||||
|
extern void bgp_reimport_evpn_routes_upon_martian_change(
|
||||||
|
struct bgp *bgp, enum bgp_martian_type martian_type, void *old_martian,
|
||||||
|
void *new_martian);
|
||||||
|
extern void
|
||||||
bgp_filter_evpn_routes_upon_martian_change(struct bgp *bgp,
|
bgp_filter_evpn_routes_upon_martian_change(struct bgp *bgp,
|
||||||
enum bgp_martian_type martian_type);
|
enum bgp_martian_type martian_type);
|
||||||
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
extern int bgp_evpn_local_macip_del(struct bgp *bgp, vni_t vni,
|
||||||
|
|
Loading…
Reference in a new issue