Skip to content

Commit ac31df3

Browse files
pguibert6WINDton31337
authored andcommitted
bgpd: fix duplicate BGP instance created with unified config
When running the bgp_evpn_rt5 setup with unified config, memory leak about a non deleted BGP instance happens. > root@ubuntu2204hwe:~/frr/tests/topotests/bgp_evpn_rt5# cat /tmp/topotests/bgp_evpn_rt5.test_bgp_evpn/r1.asan.bgpd.1164105 > > ================================================================= > ==1164105==ERROR: LeakSanitizer: detected memory leaks > > Indirect leak of 12496 byte(s) in 1 object(s) allocated from: > #0 0x7f358eeb4a57 in __interceptor_calloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154 > #1 0x7f358e877233 in qcalloc lib/memory.c:106 > #2 0x55d06c95680a in bgp_create bgpd/bgpd.c:3405 > #3 0x55d06c95a7b3 in bgp_get bgpd/bgpd.c:3805 > FRRouting#4 0x55d06c87a9b5 in bgp_get_vty bgpd/bgp_vty.c:603 > FRRouting#5 0x55d06c68dc71 in bgp_evpn_local_l3vni_add bgpd/bgp_evpn.c:7032 > FRRouting#6 0x55d06c92989b in bgp_zebra_process_local_l3vni bgpd/bgp_zebra.c:3204 > FRRouting#7 0x7f358e9e3feb in zclient_read lib/zclient.c:4626 > FRRouting#8 0x7f358e98082d in event_call lib/event.c:1996 > FRRouting#9 0x7f358e848931 in frr_run lib/libfrr.c:1232 > FRRouting#10 0x55d06c60eae1 in main bgpd/bgp_main.c:557 > FRRouting#11 0x7f358e229d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58 Actually, a BGP VRF Instance is created in auto mode when creating the global BGP instance for the L3 VNI. And again, an other BGP VRF instance is created. Fix this by ensuring that a non existing BGP instance is not present. If it is present, and with auto mode or in hidden mode, then override the AS value. Fixes: f153b9a ("bgpd: Ignore auto created VRF BGP instances") Signed-off-by: Philippe Guibert <[email protected]>
1 parent 7180a94 commit ac31df3

File tree

3 files changed

+27
-23
lines changed

3 files changed

+27
-23
lines changed

bgpd/bgp_vty.c

+10-8
Original file line numberDiff line numberDiff line change
@@ -1507,13 +1507,12 @@ DEFUN_NOSH (router_bgp,
15071507
int idx_asn = 2;
15081508
int idx_view_vrf = 3;
15091509
int idx_vrf = 4;
1510-
int is_new_bgp = 0;
15111510
int idx_asnotation = 3;
15121511
int idx_asnotation_kind = 4;
15131512
enum asnotation_mode asnotation = ASNOTATION_UNDEFINED;
15141513
int ret;
15151514
as_t as;
1516-
struct bgp *bgp;
1515+
struct bgp *bgp = NULL;
15171516
const char *name = NULL;
15181517
enum bgp_instance_type inst_type;
15191518

@@ -1575,11 +1574,14 @@ DEFUN_NOSH (router_bgp,
15751574
asnotation = ASNOTATION_PLAIN;
15761575
}
15771576

1578-
if (inst_type == BGP_INSTANCE_TYPE_DEFAULT)
1579-
is_new_bgp = (bgp_lookup(as, name) == NULL);
1580-
1581-
ret = bgp_get_vty(&bgp, &as, name, inst_type,
1582-
argv[idx_asn]->arg, asnotation);
1577+
ret = bgp_lookup_by_as_name_type(&bgp, &as, argv[idx_asn]->arg, asnotation, name,
1578+
inst_type, true);
1579+
if (bgp && ret == BGP_INSTANCE_EXISTS)
1580+
ret = CMD_SUCCESS;
1581+
else if (bgp == NULL && ret == CMD_SUCCESS)
1582+
/* SUCCESS and bgp is NULL */
1583+
ret = bgp_get_vty(&bgp, &as, name, inst_type, argv[idx_asn]->arg,
1584+
asnotation);
15831585
switch (ret) {
15841586
case BGP_ERR_AS_MISMATCH:
15851587
vty_out(vty, "BGP is already running; AS is %s\n",
@@ -1599,7 +1601,7 @@ DEFUN_NOSH (router_bgp,
15991601
* any pending VRF-VPN leaking that was configured via
16001602
* earlier "router bgp X vrf FOO" blocks.
16011603
*/
1602-
if (is_new_bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
1604+
if (bgp && inst_type == BGP_INSTANCE_TYPE_DEFAULT)
16031605
vpn_leak_postchange_all();
16041606

16051607
if (inst_type == BGP_INSTANCE_TYPE_VRF ||

bgpd/bgpd.c

+14-10
Original file line numberDiff line numberDiff line change
@@ -3671,13 +3671,13 @@ struct bgp *bgp_lookup(as_t as, const char *name)
36713671
}
36723672

36733673
/* Lookup BGP structure by view name. */
3674-
struct bgp *bgp_lookup_by_name(const char *name)
3674+
static struct bgp *bgp_lookup_by_name_filter(const char *name, bool filter_auto)
36753675
{
36763676
struct bgp *bgp;
36773677
struct listnode *node, *nnode;
36783678

36793679
for (ALL_LIST_ELEMENTS(bm->bgp, node, nnode, bgp)) {
3680-
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
3680+
if (filter_auto && CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO))
36813681
continue;
36823682
if ((bgp->name == NULL && name == NULL)
36833683
|| (bgp->name && name && strcmp(bgp->name, name) == 0))
@@ -3686,6 +3686,11 @@ struct bgp *bgp_lookup_by_name(const char *name)
36863686
return NULL;
36873687
}
36883688

3689+
struct bgp *bgp_lookup_by_name(const char *name)
3690+
{
3691+
return bgp_lookup_by_name_filter(name, true);
3692+
}
3693+
36893694
/* Lookup BGP instance based on VRF id. */
36903695
/* Note: Only to be used for incoming messages from Zebra. */
36913696
struct bgp *bgp_lookup_by_vrf_id(vrf_id_t vrf_id)
@@ -3771,10 +3776,9 @@ int bgp_handle_socket(struct bgp *bgp, struct vrf *vrf, vrf_id_t old_vrf_id,
37713776
return bgp_check_main_socket(create, bgp);
37723777
}
37733778

3774-
int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,
3775-
const char *as_pretty,
3779+
int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty,
37763780
enum asnotation_mode asnotation, const char *name,
3777-
enum bgp_instance_type inst_type)
3781+
enum bgp_instance_type inst_type, bool force_config)
37783782
{
37793783
struct bgp *bgp;
37803784
struct peer *peer = NULL;
@@ -3783,7 +3787,7 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,
37833787

37843788
/* Multiple instance check. */
37853789
if (name)
3786-
bgp = bgp_lookup_by_name(name);
3790+
bgp = bgp_lookup_by_name_filter(name, !force_config);
37873791
else
37883792
bgp = bgp_get_default();
37893793

@@ -3793,15 +3797,16 @@ int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,
37933797
/* Handle AS number change */
37943798
if (bgp->as != *as) {
37953799
if (hidden || CHECK_FLAG(bgp->vrf_flags, BGP_VRF_AUTO)) {
3796-
if (hidden) {
3800+
if (force_config == false && hidden) {
37973801
bgp_create(as, name, inst_type,
37983802
as_pretty, asnotation, bgp,
37993803
hidden);
38003804
UNSET_FLAG(bgp->flags,
38013805
BGP_FLAG_INSTANCE_HIDDEN);
38023806
} else {
38033807
bgp->as = *as;
3804-
UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO);
3808+
if (force_config == false)
3809+
UNSET_FLAG(bgp->vrf_flags, BGP_VRF_AUTO);
38053810
}
38063811

38073812
/* Set all peer's local AS with this ASN */
@@ -3838,8 +3843,7 @@ int bgp_get(struct bgp **bgp_val, as_t *as, const char *name,
38383843
struct vrf *vrf = NULL;
38393844
int ret = 0;
38403845

3841-
ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation,
3842-
name, inst_type);
3846+
ret = bgp_lookup_by_as_name_type(bgp_val, as, as_pretty, asnotation, name, inst_type, false);
38433847
if (ret || *bgp_val)
38443848
return ret;
38453849

bgpd/bgpd.h

+3-5
Original file line numberDiff line numberDiff line change
@@ -2828,11 +2828,9 @@ extern struct peer *peer_new(struct bgp *bgp);
28282828

28292829
extern struct peer *peer_lookup_in_view(struct vty *vty, struct bgp *bgp,
28302830
const char *ip_str, bool use_json);
2831-
extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as,
2832-
const char *as_pretty,
2833-
enum asnotation_mode asnotation,
2834-
const char *name,
2835-
enum bgp_instance_type inst_type);
2831+
extern int bgp_lookup_by_as_name_type(struct bgp **bgp_val, as_t *as, const char *as_pretty,
2832+
enum asnotation_mode asnotation, const char *name,
2833+
enum bgp_instance_type inst_type, bool force_config);
28362834

28372835
/* Hooks */
28382836
DECLARE_HOOK(bgp_vrf_status_changed, (struct bgp *bgp, struct interface *ifp),

0 commit comments

Comments
 (0)