if (attr->community)
MIX(community_hash_make(attr->community));
- if (attr->lcommunity)
- MIX(lcommunity_hash_make(attr->lcommunity));
+ if (bgp_attr_get_lcommunity(attr))
+ MIX(lcommunity_hash_make(bgp_attr_get_lcommunity(attr)));
if (bgp_attr_get_ecommunity(attr))
MIX(ecommunity_hash_make(bgp_attr_get_ecommunity(attr)));
if (bgp_attr_get_ipv6_ecommunity(attr))
== bgp_attr_get_ecommunity(attr2)
&& bgp_attr_get_ipv6_ecommunity(attr1)
== bgp_attr_get_ipv6_ecommunity(attr2)
- && attr1->lcommunity == attr2->lcommunity
+ && bgp_attr_get_lcommunity(attr1)
+ == bgp_attr_get_lcommunity(attr2)
&& bgp_attr_get_cluster(attr1)
== bgp_attr_get_cluster(attr2)
&& bgp_attr_get_transit(attr1)
struct attr *find;
struct ecommunity *ecomm = NULL;
struct ecommunity *ipv6_ecomm = NULL;
+ struct lcommunity *lcomm = NULL;
/* Intern referenced strucutre. */
if (attr->aspath) {
ipv6_ecomm->refcnt++;
}
- if (attr->lcommunity) {
- if (!attr->lcommunity->refcnt)
- attr->lcommunity = lcommunity_intern(attr->lcommunity);
+ lcomm = bgp_attr_get_lcommunity(attr);
+ if (lcomm) {
+ if (!lcomm->refcnt)
+ bgp_attr_set_lcommunity(attr, lcommunity_intern(lcomm));
else
- attr->lcommunity->refcnt++;
+ lcomm->refcnt++;
}
struct cluster_list *cluster = bgp_attr_get_cluster(attr);
}
if (lcommunity) {
- attr.lcommunity = lcommunity;
+ bgp_attr_set_lcommunity(&attr, lcommunity);
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
}
struct ecommunity *ecomm = NULL;
struct ecommunity *ipv6_ecomm = NULL;
struct cluster_list *cluster;
+ struct lcommunity *lcomm = NULL;
/* aspath refcount shoud be decrement. */
if (attr->aspath)
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);
+ lcomm = bgp_attr_get_lcommunity(attr);
+ lcommunity_unintern(&lcomm);
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
+ bgp_attr_set_lcommunity(attr, NULL);
cluster = bgp_attr_get_cluster(attr);
if (cluster) {
struct ecommunity *ecomm;
struct ecommunity *ipv6_ecomm;
struct cluster_list *cluster;
+ struct lcommunity *lcomm;
if (attr->aspath && !attr->aspath->refcnt) {
aspath_free(attr->aspath);
if (ipv6_ecomm && !ipv6_ecomm->refcnt)
ecommunity_free(&ipv6_ecomm);
bgp_attr_set_ipv6_ecommunity(attr, NULL);
- if (attr->lcommunity && !attr->lcommunity->refcnt)
- lcommunity_free(&attr->lcommunity);
+ lcomm = bgp_attr_get_lcommunity(attr);
+ if (lcomm && !lcomm->refcnt)
+ lcommunity_free(&lcomm);
+ bgp_attr_set_lcommunity(attr, NULL);
cluster = bgp_attr_get_cluster(attr);
if (cluster && !cluster->refcnt) {
* Large community follows new attribute format.
*/
if (length == 0) {
- attr->lcommunity = NULL;
+ bgp_attr_set_lcommunity(attr, NULL);
/* Empty extcomm doesn't seem to be invalid per se */
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
}
- attr->lcommunity = lcommunity_parse(stream_pnt(peer->curr), length);
+ bgp_attr_set_lcommunity(
+ attr, lcommunity_parse(stream_pnt(peer->curr), length));
/* XXX: fix ecommunity_parse to use stream API */
stream_forward_getp(peer->curr, length);
- if (!attr->lcommunity)
+ if (!bgp_attr_get_lcommunity(attr))
return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_OPT_ATTR_ERR,
args->total);
if (CHECK_FLAG(peer->af_flags[afi][safi],
PEER_FLAG_SEND_LARGE_COMMUNITY)
&& (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))) {
- if (lcom_length(attr->lcommunity) > 255) {
+ if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
- stream_putw(s, lcom_length(attr->lcommunity));
+ stream_putw(s,
+ lcom_length(bgp_attr_get_lcommunity(attr)));
} else {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
- stream_putc(s, lcom_length(attr->lcommunity));
+ stream_putc(s,
+ lcom_length(bgp_attr_get_lcommunity(attr)));
}
- stream_put(s, attr->lcommunity->val,
- lcom_length(attr->lcommunity));
+ stream_put(s, bgp_attr_get_lcommunity(attr)->val,
+ lcom_length(bgp_attr_get_lcommunity(attr)));
}
/* Route Reflector. */
/* Large Community attribute. */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
- if (lcom_length(attr->lcommunity) > 255) {
+ if (lcom_length(bgp_attr_get_lcommunity(attr)) > 255) {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_TRANS
| BGP_ATTR_FLAG_EXTLEN);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
- stream_putw(s, lcom_length(attr->lcommunity));
+ stream_putw(s,
+ lcom_length(bgp_attr_get_lcommunity(attr)));
} else {
stream_putc(s,
BGP_ATTR_FLAG_OPTIONAL
| BGP_ATTR_FLAG_TRANS);
stream_putc(s, BGP_ATTR_LARGE_COMMUNITIES);
- stream_putc(s, lcom_length(attr->lcommunity));
+ stream_putc(s,
+ lcom_length(bgp_attr_get_lcommunity(attr)));
}
- stream_put(s, attr->lcommunity->val,
- lcom_length(attr->lcommunity));
+ stream_put(s, bgp_attr_get_lcommunity(attr)->val,
+ lcom_length(bgp_attr_get_lcommunity(attr)));
}
/* Add a MP_NLRI attribute to dump the IPv6 next hop */
attr->ecommunity = ecomm;
}
+static inline struct lcommunity *
+bgp_attr_get_lcommunity(const struct attr *attr)
+{
+ return attr->lcommunity;
+}
+
+static inline void bgp_attr_set_lcommunity(struct attr *attr,
+ struct lcommunity *lcomm)
+{
+ attr->lcommunity = lcomm;
+}
+
static inline struct ecommunity *
bgp_attr_get_ipv6_ecommunity(const struct attr *attr)
{
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
", large-community %s",
- lcommunity_str(attr->lcommunity, false));
+ lcommunity_str(bgp_attr_get_lcommunity(attr), false));
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
snprintf(buf + strlen(buf), size - strlen(buf),
if (type == bgp_show_type_lcommunity_exact) {
struct lcommunity *lcom = output_arg;
- if (!pi->attr->lcommunity ||
- !lcommunity_cmp(
- pi->attr->lcommunity, lcom))
+ if (!bgp_attr_get_lcommunity(
+ pi->attr) ||
+ !lcommunity_cmp(
+ bgp_attr_get_lcommunity(
+ pi->attr),
+ lcom))
continue;
}
if (type == bgp_show_type_lcommunity) {
struct lcommunity *lcom = output_arg;
- if (!pi->attr->lcommunity ||
- !lcommunity_match(
- pi->attr->lcommunity, lcom))
+ if (!bgp_attr_get_lcommunity(
+ pi->attr) ||
+ !lcommunity_match(
+ bgp_attr_get_lcommunity(
+ pi->attr),
+ lcom))
continue;
}
if (type == bgp_show_type_community) {
{
struct lcommunity *ret;
+ if (!*lcom)
+ return;
+
if ((*lcom)->refcnt)
(*lcom)->refcnt--;
ecomm = (bgp_attr_get_ecommunity(&attr))
? ecommunity_dup(bgp_attr_get_ecommunity(&attr))
: NULL;
- lcomm = (attr.lcommunity) ? lcommunity_dup(attr.lcommunity)
- : NULL;
+ lcomm = (bgp_attr_get_lcommunity(&attr))
+ ? lcommunity_dup(bgp_attr_get_lcommunity(&attr))
+ : NULL;
for (mpinfo = bgp_path_info_mpath_first(new_best); mpinfo;
mpinfo = bgp_path_info_mpath_next(mpinfo)) {
bgp_attr_get_ecommunity(
mpinfo->attr));
}
- if (mpinfo->attr->lcommunity) {
+ if (bgp_attr_get_lcommunity(mpinfo->attr)) {
if (lcomm) {
lcommerge = lcommunity_merge(
- lcomm,
- mpinfo->attr->lcommunity);
+ lcomm, bgp_attr_get_lcommunity(
+ mpinfo->attr));
lcomm = lcommunity_uniq_sort(lcommerge);
lcommunity_free(&lcommerge);
} else
lcomm = lcommunity_dup(
- mpinfo->attr->lcommunity);
+ bgp_attr_get_lcommunity(
+ mpinfo->attr));
}
}
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
}
if (lcomm) {
- attr.lcommunity = lcomm;
+ bgp_attr_set_lcommunity(&attr, lcomm);
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
}
if (!ecommunity_cmp(bgp_attr_get_ecommunity(pi->attr), ecomm))
return false;
- if (!lcommunity_cmp(pi->attr->lcommunity, lcomm))
+ if (!lcommunity_cmp(bgp_attr_get_lcommunity(pi->attr), lcomm))
return false;
if (!CHECK_FLAG(pi->flags, BGP_PATH_VALID))
/* Compute aggregate route's large community.
*/
- if (pi->attr->lcommunity)
+ if (bgp_attr_get_lcommunity(pi->attr))
bgp_compute_aggregate_lcommunity_hash(
- aggregate,
- pi->attr->lcommunity);
+ aggregate,
+ bgp_attr_get_lcommunity(pi->attr));
}
if (match)
bgp_process(bgp, dest, afi, safi);
bgp_attr_get_ecommunity(
pi->attr));
- if (pi->attr->lcommunity)
+ if (bgp_attr_get_lcommunity(pi->attr))
/* Remove lcommunity from aggregate.
*/
bgp_remove_lcomm_from_aggregate_hash(
- aggregate,
- pi->attr->lcommunity);
+ aggregate,
+ bgp_attr_get_lcommunity(
+ pi->attr));
}
}
/* Compute aggregate route's large community.
*/
- if (pinew->attr->lcommunity)
+ if (bgp_attr_get_lcommunity(pinew->attr))
bgp_compute_aggregate_lcommunity(
- aggregate,
- pinew->attr->lcommunity);
+ aggregate,
+ bgp_attr_get_lcommunity(pinew->attr));
/* Retrieve aggregate route's as-path.
*/
bgp_remove_ecommunity_from_aggregate(
aggregate, bgp_attr_get_ecommunity(pi->attr));
- if (pi->attr->lcommunity)
+ if (bgp_attr_get_lcommunity(pi->attr))
/* Remove lcommunity from aggregate.
*/
bgp_remove_lcommunity_from_aggregate(
- aggregate,
- pi->attr->lcommunity);
+ aggregate, bgp_attr_get_lcommunity(pi->attr));
}
/* If this node was suppressed, process the change. */
/* Line 6 display Large community */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES)) {
if (json_paths) {
- if (!attr->lcommunity->json)
- lcommunity_str(attr->lcommunity, true);
- json_object_lock(attr->lcommunity->json);
- json_object_object_add(json_path, "largeCommunity",
- attr->lcommunity->json);
+ if (!bgp_attr_get_lcommunity(attr)->json)
+ lcommunity_str(bgp_attr_get_lcommunity(attr),
+ true);
+ json_object_lock(bgp_attr_get_lcommunity(attr)->json);
+ json_object_object_add(
+ json_path, "largeCommunity",
+ bgp_attr_get_lcommunity(attr)->json);
} else {
vty_out(vty, " Large Community: %s\n",
- attr->lcommunity->str);
+ bgp_attr_get_lcommunity(attr)->str);
}
}
XFREE(MTYPE_TMP, communities);
}
- if (!found && pi->attr->lcommunity) {
- frrstr_split(pi->attr->lcommunity->str,
+ if (!found &&
+ bgp_attr_get_lcommunity(pi->attr)) {
+ frrstr_split(bgp_attr_get_lcommunity(
+ pi->attr)
+ ->str,
" ", &communities, &num);
for (int i = 0; i < num; i++) {
const char *com2alias =
if (type == bgp_show_type_lcommunity) {
struct lcommunity *lcom = output_arg;
- if (!pi->attr->lcommunity
- || !lcommunity_match(pi->attr->lcommunity,
- lcom))
+ if (!bgp_attr_get_lcommunity(pi->attr) ||
+ !lcommunity_match(
+ bgp_attr_get_lcommunity(pi->attr),
+ lcom))
continue;
}
if (type == bgp_show_type_lcommunity_exact) {
struct lcommunity *lcom = output_arg;
- if (!pi->attr->lcommunity
- || !lcommunity_cmp(pi->attr->lcommunity,
- lcom))
+ if (!bgp_attr_get_lcommunity(pi->attr) ||
+ !lcommunity_cmp(
+ bgp_attr_get_lcommunity(pi->attr),
+ lcom))
continue;
}
if (type == bgp_show_type_lcommunity_list) {
struct community_list *list = output_arg;
- if (!lcommunity_list_match(pi->attr->lcommunity,
- list))
+ if (!lcommunity_list_match(
+ bgp_attr_get_lcommunity(pi->attr),
+ list))
continue;
}
if (type
struct community_list *list = output_arg;
if (!lcommunity_list_exact_match(
- pi->attr->lcommunity, list))
+ bgp_attr_get_lcommunity(pi->attr),
+ list))
continue;
}
if (type == bgp_show_type_lcommunity_all) {
- if (!pi->attr->lcommunity)
+ if (!bgp_attr_get_lcommunity(pi->attr))
continue;
}
if (type == bgp_show_type_dampend_paths
return RMAP_MATCH;
}
- if (path->attr->lcommunity) {
+ if (bgp_attr_get_lcommunity(path->attr)) {
found = false;
- frrstr_split(path->attr->lcommunity->str, " ", &communities,
- &num);
+ frrstr_split(bgp_attr_get_lcommunity(path->attr)->str, " ",
+ &communities, &num);
for (int i = 0; i < num; i++) {
const char *com2alias =
bgp_community2alias(communities[i]);
return RMAP_NOMATCH;
if (rcom->exact) {
- if (lcommunity_list_exact_match(path->attr->lcommunity, list))
+ if (lcommunity_list_exact_match(
+ bgp_attr_get_lcommunity(path->attr), list))
return RMAP_MATCH;
} else {
- if (lcommunity_list_match(path->attr->lcommunity, list))
+ if (lcommunity_list_match(bgp_attr_get_lcommunity(path->attr),
+ list))
return RMAP_MATCH;
}
rcs = rule;
path = object;
attr = path->attr;
- old = attr->lcommunity;
+ old = bgp_attr_get_lcommunity(attr);
/* "none" case. */
if (rcs->none) {
attr->flag &= ~(ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES));
- attr->lcommunity = NULL;
+ bgp_attr_set_lcommunity(attr, NULL);
/* See the longer comment down below. */
if (old && old->refcnt == 0)
lcommunity_free(&old);
/* will be intern()'d or attr_flush()'d by bgp_update_main() */
- attr->lcommunity = new;
+ bgp_attr_set_lcommunity(attr, new);
attr->flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
path = object;
list = community_list_lookup(bgp_clist, rcom->name, rcom->name_hash,
LARGE_COMMUNITY_LIST_MASTER);
- old = path->attr->lcommunity;
+ old = bgp_attr_get_lcommunity(path->attr);
if (list && old) {
merge = lcommunity_list_match_delete(lcommunity_dup(old), list);
lcommunity_free(&old);
if (new->size == 0) {
- path->attr->lcommunity = NULL;
+ bgp_attr_set_lcommunity(path->attr, NULL);
path->attr->flag &=
~ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
lcommunity_free(&new);
} else {
- path->attr->lcommunity = new;
+ bgp_attr_set_lcommunity(path->attr, new);
path->attr->flag |=
ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
}
if (info->attr->flag
& ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES))
- strlcpy(bzo.lcommunity, info->attr->lcommunity->str,
+ strlcpy(bzo.lcommunity,
+ bgp_attr_get_lcommunity(info->attr)->str,
sizeof(bzo.lcommunity));
strlcpy(bzo.selection_reason, reason,