Skip to content

Commit

Permalink
Merge pull request #16549 from opensourcerouting/fix/some_memory_opti…
Browse files Browse the repository at this point in the history
…mizations_for_struct_attr

bgpd: Move evpn_overlay to a pointer
  • Loading branch information
donaldsharp authored Aug 15, 2024
2 parents 4f70004 + 4ace11d commit 89a3879
Show file tree
Hide file tree
Showing 19 changed files with 265 additions and 145 deletions.
102 changes: 102 additions & 0 deletions bgpd/bgp_attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ static struct hash *vnc_hash = NULL;
#endif
static struct hash *srv6_l3vpn_hash;
static struct hash *srv6_vpn_hash;
static struct hash *evpn_overlay_hash;

struct bgp_attr_encap_subtlv *encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
{
Expand Down Expand Up @@ -549,6 +550,81 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
return true;
}

static void *evpn_overlay_hash_alloc(void *p)
{
return p;
}

static void evpn_overlay_free(struct bgp_route_evpn *bre)
{
XFREE(MTYPE_BGP_EVPN_OVERLAY, bre);
}

static struct bgp_route_evpn *evpn_overlay_intern(struct bgp_route_evpn *bre)
{
struct bgp_route_evpn *find;

find = hash_get(evpn_overlay_hash, bre, evpn_overlay_hash_alloc);
if (find != bre)
evpn_overlay_free(bre);
find->refcnt++;
return find;
}

static void evpn_overlay_unintern(struct bgp_route_evpn **brep)
{
struct bgp_route_evpn *bre = *brep;

if (!*brep)
return;

if (bre->refcnt)
bre->refcnt--;

if (bre->refcnt == 0) {
hash_release(evpn_overlay_hash, bre);
evpn_overlay_free(bre);
*brep = NULL;
}
}

static uint32_t evpn_overlay_hash_key_make(const void *p)
{
const struct bgp_route_evpn *bre = p;
uint32_t key = 0;

if (IS_IPADDR_V4(&bre->gw_ip))
key = jhash_1word(bre->gw_ip.ipaddr_v4.s_addr, 0);
else
key = jhash2(bre->gw_ip.ipaddr_v6.s6_addr32,
array_size(bre->gw_ip.ipaddr_v6.s6_addr32), 0);

key = jhash_1word(bre->type, key);
key = jhash(bre->eth_s_id.val, sizeof(bre->eth_s_id.val), 0);
return key;
}

static bool evpn_overlay_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_route_evpn *bre1 = p1;
const struct bgp_route_evpn *bre2 = p2;

return bgp_route_evpn_same(bre1, bre2);
}

static void evpn_overlay_init(void)
{
evpn_overlay_hash = hash_create(evpn_overlay_hash_key_make,
evpn_overlay_hash_cmp,
"BGP EVPN Overlay");
}

static void evpn_overlay_finish(void)
{
hash_clean_and_free(&evpn_overlay_hash,
(void (*)(void *))evpn_overlay_free);
}

static void *srv6_l3vpn_hash_alloc(void *p)
{
return p;
Expand Down Expand Up @@ -788,6 +864,8 @@ unsigned int attrhash_key_make(const void *p)
MIX(encap_hash_key_make(attr->encap_subtlvs));
if (attr->srv6_l3vpn)
MIX(srv6_l3vpn_hash_key_make(attr->srv6_l3vpn));
if (bgp_attr_get_evpn_overlay(attr))
MIX(evpn_overlay_hash_key_make(bgp_attr_get_evpn_overlay(attr)));
if (attr->srv6_vpn)
MIX(srv6_vpn_hash_key_make(attr->srv6_vpn));
#ifdef ENABLE_BGP_VNC
Expand Down Expand Up @@ -961,6 +1039,7 @@ struct attr *bgp_attr_intern(struct attr *attr)
struct ecommunity *ipv6_ecomm = NULL;
struct lcommunity *lcomm = NULL;
struct community *comm = NULL;
struct bgp_route_evpn *bre = NULL;

/* Intern referenced structure. */
if (attr->aspath) {
Expand Down Expand Up @@ -1027,6 +1106,16 @@ struct attr *bgp_attr_intern(struct attr *attr)
else
attr->encap_subtlvs->refcnt++;
}

bre = bgp_attr_get_evpn_overlay(attr);
if (bre) {
if (!bre->refcnt)
bgp_attr_set_evpn_overlay(attr,
evpn_overlay_intern(bre));
else
bre->refcnt++;
}

if (attr->srv6_l3vpn) {
if (!attr->srv6_l3vpn->refcnt)
attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
Expand Down Expand Up @@ -1216,6 +1305,7 @@ void bgp_attr_unintern_sub(struct attr *attr)
struct lcommunity *lcomm = NULL;
struct community *comm = NULL;
struct transit *transit;
struct bgp_route_evpn *bre;

/* aspath refcount shoud be decrement. */
aspath_unintern(&attr->aspath);
Expand Down Expand Up @@ -1257,6 +1347,10 @@ void bgp_attr_unintern_sub(struct attr *attr)

srv6_l3vpn_unintern(&attr->srv6_l3vpn);
srv6_vpn_unintern(&attr->srv6_vpn);

bre = bgp_attr_get_evpn_overlay(attr);
evpn_overlay_unintern(&bre);
bgp_attr_set_evpn_overlay(attr, NULL);
}

/* Free bgp attribute and aspath. */
Expand Down Expand Up @@ -1289,6 +1383,7 @@ void bgp_attr_flush(struct attr *attr)
struct cluster_list *cluster;
struct lcommunity *lcomm;
struct community *comm;
struct bgp_route_evpn *bre;

if (attr->aspath && !attr->aspath->refcnt) {
aspath_free(attr->aspath);
Expand Down Expand Up @@ -1347,6 +1442,11 @@ void bgp_attr_flush(struct attr *attr)
bgp_attr_set_vnc_subtlvs(attr, NULL);
}
#endif
bre = bgp_attr_get_evpn_overlay(attr);
if (bre && !bre->refcnt) {
evpn_overlay_free(bre);
bgp_attr_set_evpn_overlay(attr, NULL);
}
}

/* Implement draft-scudder-idr-optional-transitive behaviour and
Expand Down Expand Up @@ -5006,6 +5106,7 @@ void bgp_attr_init(void)
transit_init();
encap_init();
srv6_init();
evpn_overlay_init();
}

void bgp_attr_finish(void)
Expand All @@ -5019,6 +5120,7 @@ void bgp_attr_finish(void)
transit_finish();
encap_finish();
srv6_finish();
evpn_overlay_finish();
}

/* Make attribute packet. */
Expand Down
10 changes: 5 additions & 5 deletions bgpd/bgp_attr.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ struct attr {
struct bgp_attr_encap_subtlv *vnc_subtlvs; /* VNC-specific */
#endif
/* EVPN */
struct bgp_route_evpn evpn_overlay;
struct bgp_route_evpn *evpn_overlay;

/* EVPN MAC Mobility sequence number, if any. */
uint32_t mm_seqnum;
Expand Down Expand Up @@ -614,16 +614,16 @@ static inline void bgp_attr_set_cluster(struct attr *attr,
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST));
}

static inline const struct bgp_route_evpn *
static inline struct bgp_route_evpn *
bgp_attr_get_evpn_overlay(const struct attr *attr)
{
return &attr->evpn_overlay;
return attr->evpn_overlay;
}

static inline void bgp_attr_set_evpn_overlay(struct attr *attr,
struct bgp_route_evpn *eo)
struct bgp_route_evpn *bre)
{
memcpy(&attr->evpn_overlay, eo, sizeof(struct bgp_route_evpn));
attr->evpn_overlay = bre;
}

static inline struct bgp_attr_encap_subtlv *
Expand Down
7 changes: 7 additions & 0 deletions bgpd/bgp_attr_evpn.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
bool bgp_route_evpn_same(const struct bgp_route_evpn *e1,
const struct bgp_route_evpn *e2)
{
if (!e1 && e2)
return false;
if (!e2 && e1)
return false;
if (!e1 && !e2)
return true;

return (e1->type == e2->type &&
!memcmp(&(e1->eth_s_id), &(e2->eth_s_id), sizeof(esi_t)) &&
!ipaddr_cmp(&(e1->gw_ip), &(e2->gw_ip)));
Expand Down
1 change: 1 addition & 0 deletions bgpd/bgp_attr_evpn.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ enum overlay_index_type {
* MAC overlay index is stored in the RMAC attribute.
*/
struct bgp_route_evpn {
unsigned long refcnt;
enum overlay_index_type type;
esi_t eth_s_id;
struct ipaddr gw_ip;
Expand Down
Loading

0 comments on commit 89a3879

Please sign in to comment.