Skip to content

Commit

Permalink
bgpd: bmp, add ref counter in bmpbgp structure
Browse files Browse the repository at this point in the history
The bmpbgp structure is used to store the mirror limit
and the bmp target config of a given bgp instance (lets say X).

It is wishable to share the bmpbgp structure with a
separate BGP instance (lets say Y) that wants to import
the BMP information from X.

In the case where Y is deleted, the reference to the bmpbgp
structure of X can be deleted, but not the bmpbgp structure of X.

Fix this by using a reference counter that will be used for each
usage: mirror limit, bmp target list, and later vrf importation.

Signed-off-by: Philippe Guibert <[email protected]>
  • Loading branch information
pguibert6WIND committed Oct 30, 2024
1 parent 533edb8 commit 6bb03c2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 20 deletions.
56 changes: 36 additions & 20 deletions bgpd/bgp_bmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ static struct bmp_bgp_peer *bmp_bgp_peer_find(uint64_t peerid);
static struct bmp_bgp_peer *bmp_bgp_peer_get(struct peer *peer);
static void bmp_active_disconnected(struct bmp_active *ba);
static void bmp_active_put(struct bmp_active *ba);
static void bmp_bgp_put(struct bmp_bgp *bmpbgp);

DEFINE_MGROUP(BMP, "BMP (BGP Monitoring Protocol)");

Expand Down Expand Up @@ -1764,6 +1765,7 @@ static void bmp_mirror_limit_set_default(struct bgp *bgp)
if (bmpbgp->mirror_qsizelimit == ~0UL)
return;
bmpbgp->mirror_qsizelimit = ~0UL;
bmp_bgp_put(bmpbgp);
}

/* read from the BMP socket to detect session termination */
Expand Down Expand Up @@ -1927,25 +1929,44 @@ static struct bmp_bgp *bmp_bgp_get(struct bgp *bgp)
struct bmp_bgp *bmpbgp;

bmpbgp = bmp_bgp_find(bgp);
if (bmpbgp)
return bmpbgp;

bmpbgp = XCALLOC(MTYPE_BMP, sizeof(*bmpbgp));
bmpbgp->bgp = bgp;
bmpbgp->vrf_state = vrf_state_unknown;
bmpbgp->mirror_qsizelimit = ~0UL;
bmp_mirrorq_init(&bmpbgp->mirrorq);
bmp_bgph_add(&bmp_bgph, bmpbgp);

if (bmpbgp == NULL) {
bmpbgp = XCALLOC(MTYPE_BMP, sizeof(*bmpbgp));
bmpbgp->refcount++;
bmpbgp->bgp = bgp;
bmpbgp->vrf_state = vrf_state_unknown;
bmpbgp->mirror_qsizelimit = ~0UL;
bmp_mirrorq_init(&bmpbgp->mirrorq);
bmp_bgph_add(&bmp_bgph, bmpbgp);
}
bmpbgp->refcount++;
return bmpbgp;
}

static void bmp_bgp_put(struct bmp_bgp *bmpbgp)
{
if (--bmpbgp->refcount)
return;

bmp_mirrorq_fini(&bmpbgp->mirrorq);

bmp_bgph_del(&bmp_bgph, bmpbgp);

XFREE(MTYPE_BMP, bmpbgp);
}
/* free the bgpbmp structure after dereferencing
* each usage: mirror_limit, bmp_targets
*/
static int bmp_bgp_del(struct bgp *bgp)
{
struct bmp_bgp *bmpbgp;
struct bmp_targets *bt;
struct bmp_listener *bl;

bmp_bgph_del(&bmp_bgph, bmpbgp);
bmp_mirror_limit_set_default(bgp);

bmpbgp = bmp_bgp_find(bgp);
if (!bmpbgp)
return 0;

frr_each_safe (bmp_targets, &bmpbgp->targets, bt) {
frr_each_safe (bmp_listeners, &bt->listeners, bl)
Expand All @@ -1954,16 +1975,9 @@ static void bmp_bgp_put(struct bmp_bgp *bmpbgp)
bmp_targets_put(bt);
}

bmp_mirrorq_fini(&bmpbgp->mirrorq);
XFREE(MTYPE_BMP, bmpbgp);
}

static int bmp_bgp_del(struct bgp *bgp)
{
struct bmp_bgp *bmpbgp = bmp_bgp_find(bgp);
/* free the bgpbmp structure */
bmp_bgp_put(bmpbgp);

if (bmpbgp)
bmp_bgp_put(bmpbgp);
return 0;
}

Expand Down Expand Up @@ -2130,6 +2144,8 @@ static void bmp_targets_put(struct bmp_targets *bt)
bmp_session_fini(&bt->sessions);

XFREE(MTYPE_BMP_TARGETSNAME, bt->name);
bmp_bgp_put(bt->bmpbgp);
bt->bmpbgp = NULL;
XFREE(MTYPE_BMP_TARGETS, bt);
}

Expand Down
2 changes: 2 additions & 0 deletions bgpd/bgp_bmp.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,8 @@ struct bmp_bgp {
size_t mirror_qsize, mirror_qsizemax;

size_t mirror_qsizelimit;

uint8_t refcount;
};

extern bool bmp_bgp_update_vrf_status(struct bmp_bgp *bmpbgp, enum bmp_vrf_state force);
Expand Down

0 comments on commit 6bb03c2

Please sign in to comment.