From d04ac434f05e38271872f34e9c4649209a7df3f4 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Mon, 2 Nov 2020 11:12:39 -0500 Subject: [PATCH] bgpd: Convert ipv6_ecommunity to use accessor functions Convert the `struct attr`->ipv6_ecommunity to use accessor functions. We'll be able to reduce memory usage in the `struct bgp_attr` by doing this. Signed-off-by: Donald Sharp --- bgpd/bgp_attr.c | 43 +++++++++++++++++++++++++++-------------- bgpd/bgp_attr.h | 12 ++++++++++++ bgpd/bgp_flowspec_vty.c | 12 +++++++----- bgpd/bgp_pbr.c | 4 ++-- 4 files changed, 49 insertions(+), 22 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index ab1173ba8d..9dc43ed357 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -663,8 +663,8 @@ unsigned int attrhash_key_make(const void *p) MIX(lcommunity_hash_make(attr->lcommunity)); if (attr->ecommunity) MIX(ecommunity_hash_make(attr->ecommunity)); - if (attr->ipv6_ecommunity) - MIX(ecommunity_hash_make(attr->ipv6_ecommunity)); + if (bgp_attr_get_ipv6_ecommunity(attr)) + MIX(ecommunity_hash_make(bgp_attr_get_ipv6_ecommunity(attr))); if (attr->cluster) MIX(cluster_hash_key_make(attr->cluster)); if (attr->transit) @@ -703,7 +703,8 @@ bool attrhash_cmp(const void *p1, const void *p2) && attr1->label_index == attr2->label_index && attr1->mp_nexthop_len == attr2->mp_nexthop_len && attr1->ecommunity == attr2->ecommunity - && attr1->ipv6_ecommunity == attr2->ipv6_ecommunity + && bgp_attr_get_ipv6_ecommunity(attr1) + == bgp_attr_get_ipv6_ecommunity(attr2) && attr1->lcommunity == attr2->lcommunity && attr1->cluster == attr2->cluster && attr1->transit == attr2->transit @@ -814,6 +815,7 @@ static void *bgp_attr_hash_alloc(void *p) struct attr *bgp_attr_intern(struct attr *attr) { struct attr *find; + struct ecommunity *ecomm; /* Intern referenced strucutre. */ if (attr->aspath) { @@ -836,12 +838,13 @@ struct attr *bgp_attr_intern(struct attr *attr) attr->ecommunity->refcnt++; } - if (attr->ipv6_ecommunity) { - if (!attr->ipv6_ecommunity->refcnt) - attr->ipv6_ecommunity = - ecommunity_intern(attr->ipv6_ecommunity); + ecomm = bgp_attr_get_ipv6_ecommunity(attr); + if (ecomm) { + if (!ecomm->refcnt) + bgp_attr_set_ipv6_ecommunity(attr, + ecommunity_intern(ecomm)); else - attr->ipv6_ecommunity->refcnt++; + ecomm->refcnt++; } if (attr->lcommunity) { @@ -1036,6 +1039,8 @@ struct attr *bgp_attr_aggregate_intern( /* Unintern just the sub-components of the attr, but not the attr */ void bgp_attr_unintern_sub(struct attr *attr) { + struct ecommunity *ecomm; + /* aspath refcount shoud be decrement. */ if (attr->aspath) aspath_unintern(&attr->aspath); @@ -1048,8 +1053,10 @@ void bgp_attr_unintern_sub(struct attr *attr) ecommunity_unintern(&attr->ecommunity); UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)); - ecommunity_unintern(&attr->ipv6_ecommunity); + ecomm = bgp_attr_get_ipv6_ecommunity(attr); + ecommunity_unintern(&ecomm); UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_IPV6_EXT_COMMUNITIES)); + bgp_attr_set_ipv6_ecommunity(attr, NULL); if (attr->lcommunity) lcommunity_unintern(&attr->lcommunity); @@ -1127,6 +1134,8 @@ void bgp_attr_unintern(struct attr **pattr) void bgp_attr_flush(struct attr *attr) { + struct ecommunity *ecomm; + if (attr->aspath && !attr->aspath->refcnt) { aspath_free(attr->aspath); attr->aspath = NULL; @@ -1135,8 +1144,10 @@ void bgp_attr_flush(struct attr *attr) community_free(&attr->community); if (attr->ecommunity && !attr->ecommunity->refcnt) ecommunity_free(&attr->ecommunity); - if (attr->ipv6_ecommunity && !attr->ecommunity->refcnt) - ecommunity_free(&attr->ipv6_ecommunity); + ecomm = bgp_attr_get_ipv6_ecommunity(attr); + if (ecomm && !ecomm->refcnt) + ecommunity_free(&ecomm); + bgp_attr_set_ipv6_ecommunity(attr, NULL); if (attr->lcommunity && !attr->lcommunity->refcnt) lcommunity_free(&attr->lcommunity); if (attr->cluster && !attr->cluster->refcnt) { @@ -2300,19 +2311,21 @@ bgp_attr_ipv6_ext_communities(struct bgp_attr_parser_args *args) struct peer *const peer = args->peer; struct attr *const attr = args->attr; const bgp_size_t length = args->length; + struct ecommunity *ipv6_ecomm = NULL; if (length == 0) { - attr->ipv6_ecommunity = NULL; + bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm); return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); } - attr->ipv6_ecommunity = - ecommunity_parse_ipv6(stream_pnt(peer->curr), length); + ipv6_ecomm = ecommunity_parse_ipv6(stream_pnt(peer->curr), length); + bgp_attr_set_ipv6_ecommunity(attr, ipv6_ecomm); + /* XXX: fix ecommunity_parse to use stream API */ stream_forward_getp(peer->curr, length); - if (!attr->ipv6_ecommunity) + if (!ipv6_ecomm) return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR, args->total); diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 6ce5d18942..1672da1911 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -469,4 +469,16 @@ static inline void bgp_attr_set_pmsi_tnl_type(struct attr *attr, attr->pmsi_tnl_type = pmsi_tnl_type; } +static inline struct ecommunity * +bgp_attr_get_ipv6_ecommunity(const struct attr *attr) +{ + return attr->ipv6_ecommunity; +} + +static inline void bgp_attr_set_ipv6_ecommunity(struct attr *attr, + struct ecommunity *ipv6_ecomm) +{ + attr->ipv6_ecommunity = ipv6_ecomm; +} + #endif /* _QUAGGA_BGP_ATTR_H */ diff --git a/bgpd/bgp_flowspec_vty.c b/bgpd/bgp_flowspec_vty.c index 3b7fb649a9..0789581df1 100644 --- a/bgpd/bgp_flowspec_vty.c +++ b/bgpd/bgp_flowspec_vty.c @@ -268,6 +268,7 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p, json_object *json_ecom_path = NULL; json_object *json_time_path = NULL; char timebuf[BGP_UPTIME_LEN]; + struct ecommunity *ipv6_ecomm; if (p == NULL || p->family != AF_FLOWSPEC) return; @@ -298,16 +299,17 @@ void route_vty_out_flowspec(struct vty *vty, const struct prefix *p, json_object_array_add(json_paths, json_nlri_path); if (!path) return; - if (path->attr && - (path->attr->ecommunity || path->attr->ipv6_ecommunity)) { + + ipv6_ecomm = bgp_attr_get_ipv6_ecommunity(path->attr); + if (path->attr && (path->attr->ecommunity || ipv6_ecomm)) { /* Print attribute */ attr = path->attr; if (attr->ecommunity) s1 = ecommunity_ecom2str(attr->ecommunity, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); - if (attr->ipv6_ecommunity) - s2 = ecommunity_ecom2str(attr->ipv6_ecommunity, - ECOMMUNITY_FORMAT_ROUTE_MAP, 0); + if (ipv6_ecomm) + s2 = ecommunity_ecom2str( + ipv6_ecomm, ECOMMUNITY_FORMAT_ROUTE_MAP, 0); if (!s1 && !s2) return; if (display == NLRI_STRING_FORMAT_LARGE) diff --git a/bgpd/bgp_pbr.c b/bgpd/bgp_pbr.c index f7dd08443f..a3f1eb8401 100644 --- a/bgpd/bgp_pbr.c +++ b/bgpd/bgp_pbr.c @@ -915,10 +915,10 @@ int bgp_pbr_build_and_validate_entry(const struct prefix *p, api->action_num++; } } - if (path && path->attr && path->attr->ipv6_ecommunity) { + if (path && path->attr && bgp_attr_get_ipv6_ecommunity(path->attr)) { struct ecommunity_val_ipv6 *ipv6_ecom_eval; - ecom = path->attr->ipv6_ecommunity; + ecom = bgp_attr_get_ipv6_ecommunity(path->attr); for (i = 0; i < ecom->size; i++) { ipv6_ecom_eval = (struct ecommunity_val_ipv6 *) (ecom->val + (i * ecom->unit_size)); -- 2.39.5