mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-24 21:50:42 +00:00
bgpd : backpressure - Handle BGP-Zebra(EPVN) Install evt Creation
Current changes deals with EVPN routes installation to zebra.
In evpn_route_select_install() we invoke evpn_zebra_install/uninstall
which sends zclient_send_message().
This is a continuation of code changes (similar to
ccfe452763
) but to handle evpn part
of the code.
Ticket: #3390099
Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
This commit is contained in:
parent
498967799d
commit
a07df6f754
186
bgpd/bgp_evpn.c
186
bgpd/bgp_evpn.c
@ -892,11 +892,10 @@ struct bgp_dest *bgp_evpn_vni_node_lookup(const struct bgpevpn *vpn,
|
||||
/*
|
||||
* Add (update) or delete MACIP from zebra.
|
||||
*/
|
||||
static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
const struct ethaddr *mac,
|
||||
struct in_addr remote_vtep_ip, int add,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi)
|
||||
static enum zclient_send_status bgp_zebra_send_remote_macip(
|
||||
struct bgp *bgp, struct bgpevpn *vpn, const struct prefix_evpn *p,
|
||||
const struct ethaddr *mac, struct in_addr remote_vtep_ip, int add,
|
||||
uint8_t flags, uint32_t seq, esi_t *esi)
|
||||
{
|
||||
struct stream *s;
|
||||
uint16_t ipa_len;
|
||||
@ -904,8 +903,12 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
bool esi_valid;
|
||||
|
||||
/* Check socket. */
|
||||
if (!zclient || zclient->sock < 0)
|
||||
return 0;
|
||||
if (!zclient || zclient->sock < 0) {
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: No zclient or zclient->sock exists",
|
||||
__func__);
|
||||
return ZCLIENT_SEND_SUCCESS;
|
||||
}
|
||||
|
||||
/* Don't try to register if Zebra doesn't know of this instance. */
|
||||
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
|
||||
@ -913,7 +916,7 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
zlog_debug(
|
||||
"%s: No zebra instance to talk to, not installing remote macip",
|
||||
__func__);
|
||||
return 0;
|
||||
return ZCLIENT_SEND_SUCCESS;
|
||||
}
|
||||
|
||||
if (!esi)
|
||||
@ -979,24 +982,26 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
frrtrace(5, frr_bgp, evpn_mac_ip_zsend, add, vpn, p, remote_vtep_ip,
|
||||
esi);
|
||||
|
||||
if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add (update) or delete remote VTEP from zebra.
|
||||
*/
|
||||
static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
int flood_control, int add)
|
||||
static enum zclient_send_status
|
||||
bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p, int flood_control,
|
||||
int add)
|
||||
{
|
||||
struct stream *s;
|
||||
|
||||
/* Check socket. */
|
||||
if (!zclient || zclient->sock < 0)
|
||||
return 0;
|
||||
if (!zclient || zclient->sock < 0) {
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: No zclient or zclient->sock exists",
|
||||
__func__);
|
||||
return ZCLIENT_SEND_SUCCESS;
|
||||
}
|
||||
|
||||
/* Don't try to register if Zebra doesn't know of this instance. */
|
||||
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
|
||||
@ -1004,7 +1009,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
zlog_debug(
|
||||
"%s: No zebra instance to talk to, not installing remote vtep",
|
||||
__func__);
|
||||
return 0;
|
||||
return ZCLIENT_SEND_SUCCESS;
|
||||
}
|
||||
|
||||
s = zclient->obuf;
|
||||
@ -1021,7 +1026,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
EC_BGP_VTEP_INVALID,
|
||||
"Bad remote IP when trying to %s remote VTEP for VNI %u",
|
||||
add ? "ADD" : "DEL", (vpn ? vpn->vni : 0));
|
||||
return -1;
|
||||
return ZCLIENT_SEND_FAILURE;
|
||||
}
|
||||
stream_putl(s, flood_control);
|
||||
|
||||
@ -1034,10 +1039,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
|
||||
frrtrace(3, frr_bgp, evpn_bum_vtep_zsend, add, vpn, p);
|
||||
|
||||
if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
return zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1263,14 +1265,14 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
|
||||
}
|
||||
|
||||
/* Install EVPN route into zebra. */
|
||||
static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
struct bgp_path_info *pi)
|
||||
enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
struct bgp_path_info *pi)
|
||||
{
|
||||
int ret;
|
||||
uint8_t flags;
|
||||
int flood_control = VXLAN_FLOOD_DISABLED;
|
||||
uint32_t seq;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
|
||||
flags = 0;
|
||||
@ -1348,6 +1350,7 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
flood_control = VXLAN_FLOOD_DISABLED;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, flood_control, 1);
|
||||
}
|
||||
|
||||
@ -1355,11 +1358,13 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
}
|
||||
|
||||
/* Uninstall EVPN route from zebra. */
|
||||
static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
struct bgp_path_info *pi, bool is_sync)
|
||||
enum zclient_send_status evpn_zebra_uninstall(struct bgp *bgp,
|
||||
struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
struct bgp_path_info *pi,
|
||||
bool is_sync)
|
||||
{
|
||||
int ret;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
|
||||
ret = bgp_zebra_send_remote_macip(
|
||||
@ -1374,7 +1379,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
ret = bgp_evpn_remote_es_evi_del(bgp, vpn, p);
|
||||
else
|
||||
ret = bgp_zebra_send_remote_vtep(bgp, vpn, p,
|
||||
VXLAN_FLOOD_DISABLED, 0);
|
||||
VXLAN_FLOOD_DISABLED, 0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -1465,12 +1470,18 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
&& !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
|
||||
&& !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
|
||||
&& !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
|
||||
if (bgp_zebra_has_route_changed(old_select))
|
||||
ret = evpn_zebra_install(
|
||||
bgp, vpn,
|
||||
(const struct prefix_evpn *)bgp_dest_get_prefix(
|
||||
dest),
|
||||
old_select);
|
||||
if (bgp_zebra_has_route_changed(old_select)) {
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
|
||||
evpn_zebra_install(bgp, vpn,
|
||||
(const struct prefix_evpn *)
|
||||
bgp_dest_get_prefix(
|
||||
dest),
|
||||
old_select);
|
||||
else
|
||||
bgp_zebra_route_install(dest, old_select, bgp,
|
||||
true, vpn, false);
|
||||
}
|
||||
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
|
||||
bgp_zebra_clear_route_change_flags(dest);
|
||||
@ -1502,10 +1513,14 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
if (new_select && new_select->type == ZEBRA_ROUTE_BGP
|
||||
&& (new_select->sub_type == BGP_ROUTE_IMPORTED ||
|
||||
bgp_evpn_attr_is_sync(new_select->attr))) {
|
||||
ret = evpn_zebra_install(
|
||||
bgp, vpn,
|
||||
(struct prefix_evpn *)bgp_dest_get_prefix(dest),
|
||||
new_select);
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
|
||||
evpn_zebra_install(bgp, vpn,
|
||||
(const struct prefix_evpn *)
|
||||
bgp_dest_get_prefix(dest),
|
||||
new_select);
|
||||
else
|
||||
bgp_zebra_route_install(dest, new_select, bgp, true,
|
||||
vpn, false);
|
||||
|
||||
/* If an old best existed and it was a "local" route, the only
|
||||
* reason
|
||||
@ -1522,13 +1537,19 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
evpn_delete_old_local_route(bgp, vpn, dest,
|
||||
old_select, new_select);
|
||||
} else {
|
||||
if (old_select && old_select->type == ZEBRA_ROUTE_BGP
|
||||
&& old_select->sub_type == BGP_ROUTE_IMPORTED)
|
||||
ret = evpn_zebra_uninstall(
|
||||
bgp, vpn,
|
||||
(const struct prefix_evpn *)bgp_dest_get_prefix(
|
||||
dest),
|
||||
old_select, false);
|
||||
if (old_select && old_select->type == ZEBRA_ROUTE_BGP &&
|
||||
old_select->sub_type == BGP_ROUTE_IMPORTED) {
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
|
||||
CHECK_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN))
|
||||
evpn_zebra_uninstall(bgp, vpn,
|
||||
(const struct prefix_evpn *)
|
||||
bgp_dest_get_prefix(
|
||||
dest),
|
||||
old_select, false);
|
||||
else
|
||||
bgp_zebra_route_install(dest, old_select, bgp,
|
||||
false, vpn, false);
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear any route change flags. */
|
||||
@ -2062,9 +2083,19 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp,
|
||||
if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP
|
||||
&& (curr_select->sub_type == BGP_ROUTE_IMPORTED ||
|
||||
bgp_evpn_attr_is_sync(curr_select->attr)))
|
||||
evpn_zebra_install(bgp, vpn,
|
||||
(const struct prefix_evpn *)bgp_dest_get_prefix(dest),
|
||||
curr_select);
|
||||
if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP &&
|
||||
(curr_select->sub_type == BGP_ROUTE_IMPORTED ||
|
||||
bgp_evpn_attr_is_sync(curr_select->attr))) {
|
||||
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
|
||||
evpn_zebra_install(bgp, vpn,
|
||||
(const struct prefix_evpn *)
|
||||
bgp_dest_get_prefix(
|
||||
dest),
|
||||
curr_select);
|
||||
else
|
||||
bgp_zebra_route_install(dest, curr_select, bgp,
|
||||
true, vpn, false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@ -2245,8 +2276,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
* has been removed.
|
||||
*/
|
||||
new_is_sync = bgp_evpn_attr_is_sync(pi->attr);
|
||||
if (!new_is_sync && old_is_sync)
|
||||
evpn_zebra_uninstall(bgp, vpn, p, pi, true);
|
||||
if (!new_is_sync && old_is_sync) {
|
||||
if (CHECK_FLAG(bgp->flags,
|
||||
BGP_FLAG_DELETE_IN_PROGRESS))
|
||||
evpn_zebra_uninstall(bgp, vpn, p, pi,
|
||||
true);
|
||||
else
|
||||
bgp_zebra_route_install(dest, pi, bgp,
|
||||
false, vpn,
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
bgp_path_info_unlock(pi);
|
||||
@ -2512,8 +2551,17 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
* has been removed.
|
||||
*/
|
||||
new_is_sync = bgp_evpn_attr_is_sync(pi->attr);
|
||||
if (!new_is_sync && old_is_sync)
|
||||
evpn_zebra_uninstall(bgp, vpn, &evp, pi, true);
|
||||
if (!new_is_sync && old_is_sync) {
|
||||
if (CHECK_FLAG(bgp->flags,
|
||||
BGP_FLAG_DELETE_IN_PROGRESS))
|
||||
(void)evpn_zebra_uninstall(bgp, vpn,
|
||||
&evp, pi,
|
||||
true);
|
||||
else
|
||||
bgp_zebra_route_install(dest, pi, bgp,
|
||||
false, vpn,
|
||||
true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2795,7 +2843,22 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
delete_all_type2_routes(bgp, vpn);
|
||||
|
||||
build_evpn_type3_prefix(&p, vpn->originator_ip);
|
||||
|
||||
/*
|
||||
* To handle the following scenario:
|
||||
* - Say, the new zebra announce fifo list has few vni Evpn prefixes yet
|
||||
* to be sent to zebra.
|
||||
* - At this point if we have triggers like "no advertise-all-vni" or
|
||||
* "networking restart", where a vni is going down.
|
||||
*
|
||||
* Perform the below
|
||||
* 1) send withdraw routes to zebra immediately in case it is installed.
|
||||
* 2) before we blow up the vni table, we need to walk the list and
|
||||
* pop all the dest whose za_vpn points to this vni.
|
||||
*/
|
||||
SET_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN);
|
||||
ret = delete_evpn_route(bgp, vpn, &p);
|
||||
UNSET_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
@ -6262,6 +6325,17 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
|
||||
*/
|
||||
void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
{
|
||||
struct bgp_dest *dest = NULL;
|
||||
|
||||
while (zebra_announce_count(&bm->zebra_announce_head)) {
|
||||
dest = zebra_announce_pop(&bm->zebra_announce_head);
|
||||
if (dest->za_vpn == vpn) {
|
||||
bgp_path_info_unlock(dest->za_bgp_pi);
|
||||
bgp_dest_unlock_node(dest);
|
||||
} else
|
||||
zebra_announce_add_tail(&bm->zebra_announce_head, dest);
|
||||
}
|
||||
|
||||
bgp_evpn_remote_ip_hash_destroy(vpn);
|
||||
bgp_evpn_vni_es_cleanup(vpn);
|
||||
bgpevpn_unlink_from_l3vni(vpn);
|
||||
|
@ -186,4 +186,12 @@ extern bool is_route_injectable_into_evpn_non_supp(struct bgp_path_info *pi);
|
||||
extern void bgp_aggr_supp_withdraw_from_evpn(struct bgp *bgp, afi_t afi,
|
||||
safi_t safi);
|
||||
|
||||
extern enum zclient_send_status evpn_zebra_install(struct bgp *bgp,
|
||||
struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p,
|
||||
struct bgp_path_info *pi);
|
||||
extern enum zclient_send_status
|
||||
evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p, struct bgp_path_info *pi,
|
||||
bool is_sync);
|
||||
#endif /* _QUAGGA_BGP_EVPN_H */
|
||||
|
@ -45,13 +45,14 @@ static void bgp_evpn_local_es_down(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es);
|
||||
static void bgp_evpn_local_type1_evi_route_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es);
|
||||
static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
|
||||
static struct bgp_evpn_es_vtep *
|
||||
bgp_evpn_es_vtep_add(struct bgp *bgp, struct bgp_evpn_es *es,
|
||||
struct in_addr vtep_ip, bool esr, uint8_t df_alg,
|
||||
uint16_t df_pref, int *zret);
|
||||
static enum zclient_send_status bgp_evpn_es_vtep_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es,
|
||||
struct in_addr vtep_ip,
|
||||
bool esr, uint8_t df_alg,
|
||||
uint16_t df_pref);
|
||||
static void bgp_evpn_es_vtep_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr);
|
||||
bool esr);
|
||||
static void bgp_evpn_es_cons_checks_pend_add(struct bgp_evpn_es *es);
|
||||
static void bgp_evpn_es_cons_checks_pend_del(struct bgp_evpn_es *es);
|
||||
static struct bgp_evpn_es_evi *
|
||||
@ -94,6 +95,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
|
||||
struct bgp_dest *dest)
|
||||
{
|
||||
int ret = 0;
|
||||
int zret = 0;
|
||||
afi_t afi = AFI_L2VPN;
|
||||
safi_t safi = SAFI_EVPN;
|
||||
struct bgp_path_info *old_select; /* old best */
|
||||
@ -120,7 +122,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
|
||||
bgp_evpn_es_vtep_add(bgp, es, old_select->attr->nexthop,
|
||||
true /*esr*/,
|
||||
old_select->attr->df_alg,
|
||||
old_select->attr->df_pref);
|
||||
old_select->attr->df_pref, &zret);
|
||||
}
|
||||
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
|
||||
bgp_zebra_clear_route_change_flags(dest);
|
||||
@ -149,7 +151,7 @@ static int bgp_evpn_es_route_select_install(struct bgp *bgp,
|
||||
&& new_select->sub_type == BGP_ROUTE_IMPORTED) {
|
||||
bgp_evpn_es_vtep_add(bgp, es, new_select->attr->nexthop,
|
||||
true /*esr */, new_select->attr->df_alg,
|
||||
new_select->attr->df_pref);
|
||||
new_select->attr->df_pref, &zret);
|
||||
} else {
|
||||
if (old_select && old_select->type == ZEBRA_ROUTE_BGP
|
||||
&& old_select->sub_type == BGP_ROUTE_IMPORTED)
|
||||
@ -447,7 +449,7 @@ int bgp_evpn_mh_route_update(struct bgp *bgp, struct bgp_evpn_es *es,
|
||||
attr->mp_nexthop_global_in);
|
||||
}
|
||||
|
||||
/* Return back the route entry. */
|
||||
/* Return back th*e route entry. */
|
||||
*ri = tmp_pi;
|
||||
return 0;
|
||||
}
|
||||
@ -1371,23 +1373,28 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_find(struct bgp_evpn_es *es,
|
||||
}
|
||||
|
||||
/* Send the remote ES to zebra for NHG programming */
|
||||
static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp,
|
||||
struct bgp_evpn_es_vtep *es_vtep, bool add)
|
||||
static enum zclient_send_status
|
||||
bgp_zebra_send_remote_es_vtep(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep,
|
||||
bool add)
|
||||
{
|
||||
struct bgp_evpn_es *es = es_vtep->es;
|
||||
struct stream *s;
|
||||
uint32_t flags = 0;
|
||||
|
||||
/* Check socket. */
|
||||
if (!zclient || zclient->sock < 0)
|
||||
return 0;
|
||||
if (!zclient || zclient->sock < 0) {
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("%s: No zclient or zclient->sock exists",
|
||||
__func__);
|
||||
return ZCLIENT_SEND_SUCCESS;
|
||||
}
|
||||
|
||||
/* Don't try to register if Zebra doesn't know of this instance. */
|
||||
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
|
||||
if (BGP_DEBUG(zebra, ZEBRA))
|
||||
zlog_debug("No zebra instance, not installing remote es %s",
|
||||
es->esi_str);
|
||||
return 0;
|
||||
return ZCLIENT_SEND_SUCCESS;
|
||||
}
|
||||
|
||||
if (es_vtep->flags & BGP_EVPNES_VTEP_ESR)
|
||||
@ -1418,12 +1425,12 @@ static int bgp_zebra_send_remote_es_vtep(struct bgp *bgp,
|
||||
return zclient_send_message(zclient);
|
||||
}
|
||||
|
||||
static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
|
||||
struct bgp_evpn_es_vtep *es_vtep,
|
||||
bool param_change)
|
||||
static enum zclient_send_status bgp_evpn_es_vtep_re_eval_active(
|
||||
struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep, bool param_change)
|
||||
{
|
||||
bool old_active;
|
||||
bool new_active;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
old_active = CHECK_FLAG(es_vtep->flags, BGP_EVPNES_VTEP_ACTIVE);
|
||||
/* currently we need an active EVI reference to use the VTEP as
|
||||
@ -1445,7 +1452,7 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
|
||||
es_vtep->df_alg, es_vtep->df_pref);
|
||||
|
||||
/* send remote ES to zebra */
|
||||
bgp_zebra_send_remote_es_vtep(bgp, es_vtep, new_active);
|
||||
ret = bgp_zebra_send_remote_es_vtep(bgp, es_vtep, new_active);
|
||||
|
||||
/* The NHG is updated first for efficient failover handling.
|
||||
* Note the NHG can be de-activated while there are bgp
|
||||
@ -1457,13 +1464,14 @@ static void bgp_evpn_es_vtep_re_eval_active(struct bgp *bgp,
|
||||
/* queue up the es for background consistency checks */
|
||||
bgp_evpn_es_cons_checks_pend_add(es_vtep->es);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es,
|
||||
struct in_addr vtep_ip,
|
||||
bool esr, uint8_t df_alg,
|
||||
uint16_t df_pref)
|
||||
static struct bgp_evpn_es_vtep *
|
||||
bgp_evpn_es_vtep_add(struct bgp *bgp, struct bgp_evpn_es *es,
|
||||
struct in_addr vtep_ip, bool esr, uint8_t df_alg,
|
||||
uint16_t df_pref, int *zret)
|
||||
{
|
||||
struct bgp_evpn_es_vtep *es_vtep;
|
||||
bool param_change = false;
|
||||
@ -1490,15 +1498,17 @@ static struct bgp_evpn_es_vtep *bgp_evpn_es_vtep_add(struct bgp *bgp,
|
||||
++es_vtep->evi_cnt;
|
||||
}
|
||||
|
||||
bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change);
|
||||
*zret = bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change);
|
||||
|
||||
return es_vtep;
|
||||
}
|
||||
|
||||
static void bgp_evpn_es_vtep_do_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es_vtep *es_vtep, bool esr)
|
||||
static enum zclient_send_status
|
||||
bgp_evpn_es_vtep_do_del(struct bgp *bgp, struct bgp_evpn_es_vtep *es_vtep,
|
||||
bool esr)
|
||||
{
|
||||
bool param_change = false;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
|
||||
zlog_debug("es %s vtep %pI4 del %s", es_vtep->es->esi_str,
|
||||
@ -1515,18 +1525,25 @@ static void bgp_evpn_es_vtep_do_del(struct bgp *bgp,
|
||||
--es_vtep->evi_cnt;
|
||||
}
|
||||
|
||||
bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change);
|
||||
ret = bgp_evpn_es_vtep_re_eval_active(bgp, es_vtep, param_change);
|
||||
bgp_evpn_es_vtep_free(es_vtep);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bgp_evpn_es_vtep_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es, struct in_addr vtep_ip, bool esr)
|
||||
static enum zclient_send_status bgp_evpn_es_vtep_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es *es,
|
||||
struct in_addr vtep_ip,
|
||||
bool esr)
|
||||
{
|
||||
struct bgp_evpn_es_vtep *es_vtep;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
es_vtep = bgp_evpn_es_vtep_find(es, vtep_ip);
|
||||
if (es_vtep)
|
||||
bgp_evpn_es_vtep_do_del(bgp, es_vtep, esr);
|
||||
ret = bgp_evpn_es_vtep_do_del(bgp, es_vtep, esr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/********************** ES MAC-IP paths *************************************
|
||||
@ -3399,12 +3416,14 @@ static struct bgp_evpn_es_evi_vtep *bgp_evpn_es_evi_vtep_find(
|
||||
/* A VTEP can be added as "active" attach to an ES if EAD-per-ES and
|
||||
* EAD-per-EVI routes are rxed from it.
|
||||
*/
|
||||
static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
|
||||
struct bgp_evpn_es_evi_vtep *evi_vtep)
|
||||
static enum zclient_send_status
|
||||
bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
|
||||
struct bgp_evpn_es_evi_vtep *evi_vtep)
|
||||
{
|
||||
bool old_active;
|
||||
bool new_active;
|
||||
uint32_t ead_activity_flags;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
old_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
|
||||
|
||||
@ -3425,7 +3444,7 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
|
||||
new_active = CHECK_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_ACTIVE);
|
||||
|
||||
if (old_active == new_active)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
|
||||
zlog_debug("es %s evi %u vtep %pI4 %s",
|
||||
@ -3434,24 +3453,27 @@ static void bgp_evpn_es_evi_vtep_re_eval_active(struct bgp *bgp,
|
||||
new_active ? "active" : "inactive");
|
||||
|
||||
/* add VTEP to parent es */
|
||||
if (new_active)
|
||||
evi_vtep->es_vtep = bgp_evpn_es_vtep_add(
|
||||
bgp, evi_vtep->es_evi->es, evi_vtep->vtep_ip,
|
||||
false /*esr*/, 0, 0);
|
||||
else {
|
||||
if (new_active) {
|
||||
evi_vtep->es_vtep =
|
||||
bgp_evpn_es_vtep_add(bgp, evi_vtep->es_evi->es,
|
||||
evi_vtep->vtep_ip, false /*esr*/,
|
||||
0, 0, &ret);
|
||||
} else {
|
||||
if (evi_vtep->es_vtep) {
|
||||
bgp_evpn_es_vtep_do_del(bgp, evi_vtep->es_vtep,
|
||||
false /*esr*/);
|
||||
ret = bgp_evpn_es_vtep_do_del(bgp, evi_vtep->es_vtep,
|
||||
false /*esr*/);
|
||||
evi_vtep->es_vtep = NULL;
|
||||
}
|
||||
}
|
||||
/* queue up the parent es for background consistency checks */
|
||||
bgp_evpn_es_cons_checks_pend_add(evi_vtep->es_evi->es);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp,
|
||||
struct bgp_evpn_es_evi *es_evi, struct in_addr vtep_ip,
|
||||
bool ead_es)
|
||||
static enum zclient_send_status
|
||||
bgp_evpn_es_evi_vtep_add(struct bgp *bgp, struct bgp_evpn_es_evi *es_evi,
|
||||
struct in_addr vtep_ip, bool ead_es)
|
||||
{
|
||||
struct bgp_evpn_es_evi_vtep *evi_vtep;
|
||||
|
||||
@ -3475,18 +3497,19 @@ static void bgp_evpn_es_evi_vtep_add(struct bgp *bgp,
|
||||
else
|
||||
SET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_EVI);
|
||||
|
||||
bgp_evpn_es_evi_vtep_re_eval_active(bgp, evi_vtep);
|
||||
return bgp_evpn_es_evi_vtep_re_eval_active(bgp, evi_vtep);
|
||||
}
|
||||
|
||||
static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp,
|
||||
struct bgp_evpn_es_evi *es_evi, struct in_addr vtep_ip,
|
||||
bool ead_es)
|
||||
static enum zclient_send_status
|
||||
bgp_evpn_es_evi_vtep_del(struct bgp *bgp, struct bgp_evpn_es_evi *es_evi,
|
||||
struct in_addr vtep_ip, bool ead_es)
|
||||
{
|
||||
struct bgp_evpn_es_evi_vtep *evi_vtep;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
evi_vtep = bgp_evpn_es_evi_vtep_find(es_evi, vtep_ip);
|
||||
if (!evi_vtep)
|
||||
return;
|
||||
return ret;
|
||||
|
||||
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
|
||||
zlog_debug("del es %s evi %u vtep %pI4 %s",
|
||||
@ -3503,8 +3526,10 @@ static void bgp_evpn_es_evi_vtep_del(struct bgp *bgp,
|
||||
else
|
||||
UNSET_FLAG(evi_vtep->flags, BGP_EVPN_EVI_VTEP_EAD_PER_EVI);
|
||||
|
||||
bgp_evpn_es_evi_vtep_re_eval_active(bgp, evi_vtep);
|
||||
ret = bgp_evpn_es_evi_vtep_re_eval_active(bgp, evi_vtep);
|
||||
bgp_evpn_es_evi_vtep_free(evi_vtep);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* compare ES-IDs for the ES-EVI RB tree maintained per-VNI */
|
||||
@ -3780,18 +3805,20 @@ int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni)
|
||||
/* Add remote ES-EVI entry. This is actually the remote VTEP add and the
|
||||
* ES-EVI is implicity created on first VTEP's reference.
|
||||
*/
|
||||
int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p)
|
||||
enum zclient_send_status bgp_evpn_remote_es_evi_add(struct bgp *bgp,
|
||||
struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p)
|
||||
{
|
||||
char buf[ESI_STR_LEN];
|
||||
struct bgp_evpn_es *es;
|
||||
struct bgp_evpn_es_evi *es_evi;
|
||||
bool ead_es;
|
||||
const esi_t *esi = &p->prefix.ead_addr.esi;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
if (!vpn)
|
||||
/* local EAD-ES need not be sent back to zebra */
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
|
||||
zlog_debug("add remote %s es %s evi %u vtep %pI4",
|
||||
@ -3808,27 +3835,29 @@ int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
es_evi = bgp_evpn_es_evi_new(es, vpn);
|
||||
|
||||
ead_es = !!p->prefix.ead_addr.eth_tag;
|
||||
bgp_evpn_es_evi_vtep_add(bgp, es_evi, p->prefix.ead_addr.ip.ipaddr_v4,
|
||||
ead_es);
|
||||
ret = bgp_evpn_es_evi_vtep_add(bgp, es_evi,
|
||||
p->prefix.ead_addr.ip.ipaddr_v4, ead_es);
|
||||
|
||||
bgp_evpn_es_evi_remote_info_re_eval(es_evi);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* A remote VTEP has withdrawn. The es-evi-vtep will be deleted and the
|
||||
* parent es-evi freed up implicitly in last VTEP's deref.
|
||||
*/
|
||||
int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p)
|
||||
enum zclient_send_status bgp_evpn_remote_es_evi_del(struct bgp *bgp,
|
||||
struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p)
|
||||
{
|
||||
char buf[ESI_STR_LEN];
|
||||
struct bgp_evpn_es *es;
|
||||
struct bgp_evpn_es_evi *es_evi;
|
||||
bool ead_es;
|
||||
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
|
||||
|
||||
if (!vpn)
|
||||
/* local EAD-ES need not be sent back to zebra */
|
||||
return 0;
|
||||
return ret;
|
||||
|
||||
if (BGP_DEBUG(evpn_mh, EVPN_MH_ES))
|
||||
zlog_debug(
|
||||
@ -3847,7 +3876,7 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
esi_to_str(&p->prefix.ead_addr.esi, buf,
|
||||
sizeof(buf)),
|
||||
vpn->vni, &p->prefix.ead_addr.ip.ipaddr_v4);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
es_evi = bgp_evpn_es_evi_find(es, vpn);
|
||||
if (!es_evi) {
|
||||
@ -3860,14 +3889,15 @@ int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
sizeof(buf)),
|
||||
vpn->vni,
|
||||
&p->prefix.ead_addr.ip.ipaddr_v4);
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
ead_es = !!p->prefix.ead_addr.eth_tag;
|
||||
bgp_evpn_es_evi_vtep_del(bgp, es_evi, p->prefix.ead_addr.ip.ipaddr_v4,
|
||||
ead_es);
|
||||
ret = bgp_evpn_es_evi_vtep_del(bgp, es_evi,
|
||||
p->prefix.ead_addr.ip.ipaddr_v4, ead_es);
|
||||
bgp_evpn_es_evi_remote_info_re_eval(es_evi);
|
||||
return 0;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* If a VNI is being deleted we need to force del all remote VTEPs */
|
||||
|
@ -418,10 +418,12 @@ extern int bgp_evpn_local_es_add(struct bgp *bgp, esi_t *esi,
|
||||
extern int bgp_evpn_local_es_del(struct bgp *bgp, esi_t *esi);
|
||||
extern int bgp_evpn_local_es_evi_add(struct bgp *bgp, esi_t *esi, vni_t vni);
|
||||
extern int bgp_evpn_local_es_evi_del(struct bgp *bgp, esi_t *esi, vni_t vni);
|
||||
extern int bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p);
|
||||
extern int bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p);
|
||||
extern enum zclient_send_status
|
||||
bgp_evpn_remote_es_evi_add(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p);
|
||||
extern enum zclient_send_status
|
||||
bgp_evpn_remote_es_evi_del(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
const struct prefix_evpn *p);
|
||||
extern void bgp_evpn_mh_init(void);
|
||||
extern void bgp_evpn_mh_finish(void);
|
||||
void bgp_evpn_vni_es_init(struct bgpevpn *vpn);
|
||||
|
@ -3402,9 +3402,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
|
||||
&& (new_select->sub_type == BGP_ROUTE_NORMAL
|
||||
|| new_select->sub_type
|
||||
== BGP_ROUTE_IMPORTED))
|
||||
|
||||
bgp_zebra_route_install(dest, old_select,
|
||||
bgp, true);
|
||||
bgp, true, NULL,
|
||||
false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3522,9 +3522,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
|
||||
if (old_select &&
|
||||
is_route_parent_evpn(old_select))
|
||||
bgp_zebra_route_install(dest, old_select, bgp,
|
||||
false);
|
||||
false, NULL, false);
|
||||
|
||||
bgp_zebra_route_install(dest, new_select, bgp, true);
|
||||
bgp_zebra_route_install(dest, new_select, bgp, true,
|
||||
NULL, false);
|
||||
} else {
|
||||
/* Withdraw the route from the kernel. */
|
||||
if (old_select && old_select->type == ZEBRA_ROUTE_BGP
|
||||
@ -3533,7 +3534,7 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
|
||||
|| old_select->sub_type == BGP_ROUTE_IMPORTED))
|
||||
|
||||
bgp_zebra_route_install(dest, old_select, bgp,
|
||||
false);
|
||||
false, NULL, false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4430,7 +4431,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
|
||||
if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
|
||||
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
|
||||
/* remove from RIB previous entry */
|
||||
bgp_zebra_route_install(dest, pi, bgp, false);
|
||||
bgp_zebra_route_install(dest, pi, bgp, false, NULL,
|
||||
false);
|
||||
}
|
||||
|
||||
if (peer->sort == BGP_PEER_EBGP) {
|
||||
|
@ -78,6 +78,8 @@ struct bgp_dest {
|
||||
|
||||
struct zebra_announce_item zai;
|
||||
struct bgp_path_info *za_bgp_pi;
|
||||
struct bgpevpn *za_vpn;
|
||||
bool za_is_sync;
|
||||
|
||||
uint64_t version;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -30,7 +30,8 @@ extern int bgp_zebra_get_table_range(struct zclient *zc, uint32_t chunk_size,
|
||||
extern int bgp_if_update_all(void);
|
||||
extern void bgp_zebra_route_install(struct bgp_dest *dest,
|
||||
struct bgp_path_info *path, struct bgp *bgp,
|
||||
bool install);
|
||||
bool install, struct bgpevpn *vpn,
|
||||
bool is_sync);
|
||||
extern void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi);
|
||||
|
||||
/* Announce routes of any bgp subtype of a table to zebra */
|
||||
|
@ -530,6 +530,7 @@ struct bgp {
|
||||
#define BGP_FLAG_SOFT_VERSION_CAPABILITY (1ULL << 35)
|
||||
#define BGP_FLAG_ENFORCE_FIRST_AS (1ULL << 36)
|
||||
#define BGP_FLAG_DYNAMIC_CAPABILITY (1ULL << 37)
|
||||
#define BGP_FLAG_VNI_DOWN (1ULL << 38)
|
||||
|
||||
/* BGP default address-families.
|
||||
* New peers inherit enabled afi/safis from bgp instance.
|
||||
|
Loading…
Reference in New Issue
Block a user