Skip to content

Commit a07df6f

Browse files
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 ccfe452) but to handle evpn part of the code. Ticket: #3390099 Signed-off-by: Rajasekar Raja <rajasekarr@nvidia.com>
1 parent 4989677 commit a07df6f

File tree

9 files changed

+300
-142
lines changed

9 files changed

+300
-142
lines changed

bgpd/bgp_evpn.c

Lines changed: 130 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -892,28 +892,31 @@ struct bgp_dest *bgp_evpn_vni_node_lookup(const struct bgpevpn *vpn,
892892
/*
893893
* Add (update) or delete MACIP from zebra.
894894
*/
895-
static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
896-
const struct prefix_evpn *p,
897-
const struct ethaddr *mac,
898-
struct in_addr remote_vtep_ip, int add,
899-
uint8_t flags, uint32_t seq, esi_t *esi)
895+
static enum zclient_send_status bgp_zebra_send_remote_macip(
896+
struct bgp *bgp, struct bgpevpn *vpn, const struct prefix_evpn *p,
897+
const struct ethaddr *mac, struct in_addr remote_vtep_ip, int add,
898+
uint8_t flags, uint32_t seq, esi_t *esi)
900899
{
901900
struct stream *s;
902901
uint16_t ipa_len;
903902
static struct in_addr zero_remote_vtep_ip;
904903
bool esi_valid;
905904

906905
/* Check socket. */
907-
if (!zclient || zclient->sock < 0)
908-
return 0;
906+
if (!zclient || zclient->sock < 0) {
907+
if (BGP_DEBUG(zebra, ZEBRA))
908+
zlog_debug("%s: No zclient or zclient->sock exists",
909+
__func__);
910+
return ZCLIENT_SEND_SUCCESS;
911+
}
909912

910913
/* Don't try to register if Zebra doesn't know of this instance. */
911914
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
912915
if (BGP_DEBUG(zebra, ZEBRA))
913916
zlog_debug(
914917
"%s: No zebra instance to talk to, not installing remote macip",
915918
__func__);
916-
return 0;
919+
return ZCLIENT_SEND_SUCCESS;
917920
}
918921

919922
if (!esi)
@@ -979,32 +982,34 @@ static int bgp_zebra_send_remote_macip(struct bgp *bgp, struct bgpevpn *vpn,
979982
frrtrace(5, frr_bgp, evpn_mac_ip_zsend, add, vpn, p, remote_vtep_ip,
980983
esi);
981984

982-
if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
983-
return -1;
984-
985-
return 0;
985+
return zclient_send_message(zclient);
986986
}
987987

988988
/*
989989
* Add (update) or delete remote VTEP from zebra.
990990
*/
991-
static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
992-
const struct prefix_evpn *p,
993-
int flood_control, int add)
991+
static enum zclient_send_status
992+
bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
993+
const struct prefix_evpn *p, int flood_control,
994+
int add)
994995
{
995996
struct stream *s;
996997

997998
/* Check socket. */
998-
if (!zclient || zclient->sock < 0)
999-
return 0;
999+
if (!zclient || zclient->sock < 0) {
1000+
if (BGP_DEBUG(zebra, ZEBRA))
1001+
zlog_debug("%s: No zclient or zclient->sock exists",
1002+
__func__);
1003+
return ZCLIENT_SEND_SUCCESS;
1004+
}
10001005

10011006
/* Don't try to register if Zebra doesn't know of this instance. */
10021007
if (!IS_BGP_INST_KNOWN_TO_ZEBRA(bgp)) {
10031008
if (BGP_DEBUG(zebra, ZEBRA))
10041009
zlog_debug(
10051010
"%s: No zebra instance to talk to, not installing remote vtep",
10061011
__func__);
1007-
return 0;
1012+
return ZCLIENT_SEND_SUCCESS;
10081013
}
10091014

10101015
s = zclient->obuf;
@@ -1021,7 +1026,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
10211026
EC_BGP_VTEP_INVALID,
10221027
"Bad remote IP when trying to %s remote VTEP for VNI %u",
10231028
add ? "ADD" : "DEL", (vpn ? vpn->vni : 0));
1024-
return -1;
1029+
return ZCLIENT_SEND_FAILURE;
10251030
}
10261031
stream_putl(s, flood_control);
10271032

@@ -1034,10 +1039,7 @@ static int bgp_zebra_send_remote_vtep(struct bgp *bgp, struct bgpevpn *vpn,
10341039

10351040
frrtrace(3, frr_bgp, evpn_bum_vtep_zsend, add, vpn, p);
10361041

1037-
if (zclient_send_message(zclient) == ZCLIENT_SEND_FAILURE)
1038-
return -1;
1039-
1040-
return 0;
1042+
return zclient_send_message(zclient);
10411043
}
10421044

10431045
/*
@@ -1263,14 +1265,14 @@ static void add_mac_mobility_to_attr(uint32_t seq_num, struct attr *attr)
12631265
}
12641266

12651267
/* Install EVPN route into zebra. */
1266-
static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
1267-
const struct prefix_evpn *p,
1268-
struct bgp_path_info *pi)
1268+
enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
1269+
const struct prefix_evpn *p,
1270+
struct bgp_path_info *pi)
12691271
{
1270-
int ret;
12711272
uint8_t flags;
12721273
int flood_control = VXLAN_FLOOD_DISABLED;
12731274
uint32_t seq;
1275+
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
12741276

12751277
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
12761278
flags = 0;
@@ -1348,18 +1350,21 @@ static int evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn,
13481350
flood_control = VXLAN_FLOOD_DISABLED;
13491351
break;
13501352
}
1353+
13511354
ret = bgp_zebra_send_remote_vtep(bgp, vpn, p, flood_control, 1);
13521355
}
13531356

13541357
return ret;
13551358
}
13561359

13571360
/* Uninstall EVPN route from zebra. */
1358-
static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
1359-
const struct prefix_evpn *p,
1360-
struct bgp_path_info *pi, bool is_sync)
1361+
enum zclient_send_status evpn_zebra_uninstall(struct bgp *bgp,
1362+
struct bgpevpn *vpn,
1363+
const struct prefix_evpn *p,
1364+
struct bgp_path_info *pi,
1365+
bool is_sync)
13611366
{
1362-
int ret;
1367+
enum zclient_send_status ret = ZCLIENT_SEND_SUCCESS;
13631368

13641369
if (p->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE)
13651370
ret = bgp_zebra_send_remote_macip(
@@ -1374,7 +1379,7 @@ static int evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
13741379
ret = bgp_evpn_remote_es_evi_del(bgp, vpn, p);
13751380
else
13761381
ret = bgp_zebra_send_remote_vtep(bgp, vpn, p,
1377-
VXLAN_FLOOD_DISABLED, 0);
1382+
VXLAN_FLOOD_DISABLED, 0);
13781383

13791384
return ret;
13801385
}
@@ -1465,12 +1470,18 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
14651470
&& !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR)
14661471
&& !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED)
14671472
&& !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) {
1468-
if (bgp_zebra_has_route_changed(old_select))
1469-
ret = evpn_zebra_install(
1470-
bgp, vpn,
1471-
(const struct prefix_evpn *)bgp_dest_get_prefix(
1472-
dest),
1473-
old_select);
1473+
if (bgp_zebra_has_route_changed(old_select)) {
1474+
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
1475+
evpn_zebra_install(bgp, vpn,
1476+
(const struct prefix_evpn *)
1477+
bgp_dest_get_prefix(
1478+
dest),
1479+
old_select);
1480+
else
1481+
bgp_zebra_route_install(dest, old_select, bgp,
1482+
true, vpn, false);
1483+
}
1484+
14741485
UNSET_FLAG(old_select->flags, BGP_PATH_MULTIPATH_CHG);
14751486
UNSET_FLAG(old_select->flags, BGP_PATH_LINK_BW_CHG);
14761487
bgp_zebra_clear_route_change_flags(dest);
@@ -1502,10 +1513,14 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
15021513
if (new_select && new_select->type == ZEBRA_ROUTE_BGP
15031514
&& (new_select->sub_type == BGP_ROUTE_IMPORTED ||
15041515
bgp_evpn_attr_is_sync(new_select->attr))) {
1505-
ret = evpn_zebra_install(
1506-
bgp, vpn,
1507-
(struct prefix_evpn *)bgp_dest_get_prefix(dest),
1508-
new_select);
1516+
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
1517+
evpn_zebra_install(bgp, vpn,
1518+
(const struct prefix_evpn *)
1519+
bgp_dest_get_prefix(dest),
1520+
new_select);
1521+
else
1522+
bgp_zebra_route_install(dest, new_select, bgp, true,
1523+
vpn, false);
15091524

15101525
/* If an old best existed and it was a "local" route, the only
15111526
* reason
@@ -1522,13 +1537,19 @@ int evpn_route_select_install(struct bgp *bgp, struct bgpevpn *vpn,
15221537
evpn_delete_old_local_route(bgp, vpn, dest,
15231538
old_select, new_select);
15241539
} else {
1525-
if (old_select && old_select->type == ZEBRA_ROUTE_BGP
1526-
&& old_select->sub_type == BGP_ROUTE_IMPORTED)
1527-
ret = evpn_zebra_uninstall(
1528-
bgp, vpn,
1529-
(const struct prefix_evpn *)bgp_dest_get_prefix(
1530-
dest),
1531-
old_select, false);
1540+
if (old_select && old_select->type == ZEBRA_ROUTE_BGP &&
1541+
old_select->sub_type == BGP_ROUTE_IMPORTED) {
1542+
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS) ||
1543+
CHECK_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN))
1544+
evpn_zebra_uninstall(bgp, vpn,
1545+
(const struct prefix_evpn *)
1546+
bgp_dest_get_prefix(
1547+
dest),
1548+
old_select, false);
1549+
else
1550+
bgp_zebra_route_install(dest, old_select, bgp,
1551+
false, vpn, false);
1552+
}
15321553
}
15331554

15341555
/* Clear any route change flags. */
@@ -2062,9 +2083,19 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp,
20622083
if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP
20632084
&& (curr_select->sub_type == BGP_ROUTE_IMPORTED ||
20642085
bgp_evpn_attr_is_sync(curr_select->attr)))
2065-
evpn_zebra_install(bgp, vpn,
2066-
(const struct prefix_evpn *)bgp_dest_get_prefix(dest),
2067-
curr_select);
2086+
if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP &&
2087+
(curr_select->sub_type == BGP_ROUTE_IMPORTED ||
2088+
bgp_evpn_attr_is_sync(curr_select->attr))) {
2089+
if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
2090+
evpn_zebra_install(bgp, vpn,
2091+
(const struct prefix_evpn *)
2092+
bgp_dest_get_prefix(
2093+
dest),
2094+
curr_select);
2095+
else
2096+
bgp_zebra_route_install(dest, curr_select, bgp,
2097+
true, vpn, false);
2098+
}
20682099
}
20692100

20702101
/*
@@ -2245,8 +2276,16 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
22452276
* has been removed.
22462277
*/
22472278
new_is_sync = bgp_evpn_attr_is_sync(pi->attr);
2248-
if (!new_is_sync && old_is_sync)
2249-
evpn_zebra_uninstall(bgp, vpn, p, pi, true);
2279+
if (!new_is_sync && old_is_sync) {
2280+
if (CHECK_FLAG(bgp->flags,
2281+
BGP_FLAG_DELETE_IN_PROGRESS))
2282+
evpn_zebra_uninstall(bgp, vpn, p, pi,
2283+
true);
2284+
else
2285+
bgp_zebra_route_install(dest, pi, bgp,
2286+
false, vpn,
2287+
true);
2288+
}
22502289
}
22512290
}
22522291
bgp_path_info_unlock(pi);
@@ -2512,8 +2551,17 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
25122551
* has been removed.
25132552
*/
25142553
new_is_sync = bgp_evpn_attr_is_sync(pi->attr);
2515-
if (!new_is_sync && old_is_sync)
2516-
evpn_zebra_uninstall(bgp, vpn, &evp, pi, true);
2554+
if (!new_is_sync && old_is_sync) {
2555+
if (CHECK_FLAG(bgp->flags,
2556+
BGP_FLAG_DELETE_IN_PROGRESS))
2557+
(void)evpn_zebra_uninstall(bgp, vpn,
2558+
&evp, pi,
2559+
true);
2560+
else
2561+
bgp_zebra_route_install(dest, pi, bgp,
2562+
false, vpn,
2563+
true);
2564+
}
25172565
}
25182566
}
25192567

@@ -2795,7 +2843,22 @@ static int delete_routes_for_vni(struct bgp *bgp, struct bgpevpn *vpn)
27952843
delete_all_type2_routes(bgp, vpn);
27962844

27972845
build_evpn_type3_prefix(&p, vpn->originator_ip);
2846+
2847+
/*
2848+
* To handle the following scenario:
2849+
* - Say, the new zebra announce fifo list has few vni Evpn prefixes yet
2850+
* to be sent to zebra.
2851+
* - At this point if we have triggers like "no advertise-all-vni" or
2852+
* "networking restart", where a vni is going down.
2853+
*
2854+
* Perform the below
2855+
* 1) send withdraw routes to zebra immediately in case it is installed.
2856+
* 2) before we blow up the vni table, we need to walk the list and
2857+
* pop all the dest whose za_vpn points to this vni.
2858+
*/
2859+
SET_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN);
27982860
ret = delete_evpn_route(bgp, vpn, &p);
2861+
UNSET_FLAG(bgp->flags, BGP_FLAG_VNI_DOWN);
27992862
if (ret)
28002863
return ret;
28012864

@@ -6262,6 +6325,17 @@ struct bgpevpn *bgp_evpn_new(struct bgp *bgp, vni_t vni,
62626325
*/
62636326
void bgp_evpn_free(struct bgp *bgp, struct bgpevpn *vpn)
62646327
{
6328+
struct bgp_dest *dest = NULL;
6329+
6330+
while (zebra_announce_count(&bm->zebra_announce_head)) {
6331+
dest = zebra_announce_pop(&bm->zebra_announce_head);
6332+
if (dest->za_vpn == vpn) {
6333+
bgp_path_info_unlock(dest->za_bgp_pi);
6334+
bgp_dest_unlock_node(dest);
6335+
} else
6336+
zebra_announce_add_tail(&bm->zebra_announce_head, dest);
6337+
}
6338+
62656339
bgp_evpn_remote_ip_hash_destroy(vpn);
62666340
bgp_evpn_vni_es_cleanup(vpn);
62676341
bgpevpn_unlink_from_l3vni(vpn);

bgpd/bgp_evpn.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,4 +186,12 @@ extern bool is_route_injectable_into_evpn_non_supp(struct bgp_path_info *pi);
186186
extern void bgp_aggr_supp_withdraw_from_evpn(struct bgp *bgp, afi_t afi,
187187
safi_t safi);
188188

189+
extern enum zclient_send_status evpn_zebra_install(struct bgp *bgp,
190+
struct bgpevpn *vpn,
191+
const struct prefix_evpn *p,
192+
struct bgp_path_info *pi);
193+
extern enum zclient_send_status
194+
evpn_zebra_uninstall(struct bgp *bgp, struct bgpevpn *vpn,
195+
const struct prefix_evpn *p, struct bgp_path_info *pi,
196+
bool is_sync);
189197
#endif /* _QUAGGA_BGP_EVPN_H */

0 commit comments

Comments
 (0)