]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_attr.c
Merge pull request #10356 from opensourcerouting/pim6-adjust-20220117
[mirror_frr.git] / bgpd / bgp_attr.c
index e0cb26116d7638e7e2d008037de1bb80b2757aa4..21f92c353eeca571d63e154bff86ea60ab820498 100644 (file)
@@ -95,16 +95,6 @@ static const struct message attr_flag_str[] = {
 
 static struct hash *cluster_hash;
 
-struct attr_extra *bgp_attr_extra_alloc(void)
-{
-       return XCALLOC(MTYPE_ATTR_EXTRA, sizeof(struct attr_extra));
-}
-
-void bgp_attr_extra_free(struct attr *attr)
-{
-       XFREE(MTYPE_ATTR_EXTRA, attr->extra);
-}
-
 static void *cluster_hash_alloc(void *p)
 {
        const struct cluster_list *val = (const struct cluster_list *)p;
@@ -682,8 +672,8 @@ unsigned int attrhash_key_make(const void *p)
        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))
@@ -737,7 +727,8 @@ bool attrhash_cmp(const void *p1, const void *p2)
                               == 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)
@@ -788,7 +779,6 @@ static void attrhash_init(void)
  */
 static void attr_vfree(void *attr)
 {
-       bgp_attr_extra_free(attr);
        XFREE(MTYPE_ATTR, attr);
 }
 
@@ -853,6 +843,7 @@ struct attr *bgp_attr_intern(struct attr *attr)
        struct attr *find;
        struct ecommunity *ecomm = NULL;
        struct ecommunity *ipv6_ecomm = NULL;
+       struct lcommunity *lcomm = NULL;
 
        /* Intern referenced strucutre. */
        if (attr->aspath) {
@@ -885,11 +876,12 @@ struct attr *bgp_attr_intern(struct attr *attr)
                        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);
@@ -1021,7 +1013,7 @@ struct attr *bgp_attr_aggregate_intern(
        }
 
        if (lcommunity) {
-               attr.lcommunity = lcommunity;
+               bgp_attr_set_lcommunity(&attr, lcommunity);
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
        }
 
@@ -1091,10 +1083,10 @@ void bgp_attr_unintern_sub(struct attr *attr)
        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)
-               aspath_unintern(&attr->aspath);
+       aspath_unintern(&attr->aspath);
        UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_AS_PATH));
 
        if (attr->community)
@@ -1111,9 +1103,10 @@ void bgp_attr_unintern_sub(struct attr *attr)
        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) {
@@ -1149,43 +1142,6 @@ void bgp_attr_unintern_sub(struct attr *attr)
                srv6_vpn_unintern(&attr->srv6_vpn);
 }
 
-/*
- * We have some show commands that let you experimentally
- * apply a route-map.  When we apply the route-map
- * we are reseting values but not saving them for
- * posterity via intern'ing( because route-maps don't
- * do that) but at this point in time we need
- * to compare the new attr to the old and if the
- * routemap has changed it we need to, as Snoop Dog says,
- * Drop it like it's hot
- */
-void bgp_attr_undup(struct attr *new, struct attr *old)
-{
-       struct ecommunity *ecomm = bgp_attr_get_ecommunity(new);
-
-       if (new->aspath != old->aspath)
-               aspath_free(new->aspath);
-
-       if (new->community != old->community)
-               community_free(&new->community);
-
-       if (ecomm != bgp_attr_get_ecommunity(old))
-               ecommunity_free(&ecomm);
-
-       if (new->lcommunity != old->lcommunity)
-               lcommunity_free(&new->lcommunity);
-
-       if (new->srv6_l3vpn != old->srv6_l3vpn) {
-               srv6_l3vpn_free(new->srv6_l3vpn);
-               new->srv6_l3vpn = NULL;
-       }
-
-       if (new->srv6_vpn != old->srv6_vpn) {
-               srv6_vpn_free(new->srv6_vpn);
-               new->srv6_vpn = NULL;
-       }
-}
-
 /* Free bgp attribute and aspath. */
 void bgp_attr_unintern(struct attr **pattr)
 {
@@ -1202,7 +1158,6 @@ void bgp_attr_unintern(struct attr **pattr)
        if (attr->refcnt == 0) {
                ret = hash_release(attrhash, attr);
                assert(ret != NULL);
-               bgp_attr_extra_free(attr);
                XFREE(MTYPE_ATTR, attr);
                *pattr = NULL;
        }
@@ -1215,6 +1170,7 @@ void bgp_attr_flush(struct attr *attr)
        struct ecommunity *ecomm;
        struct ecommunity *ipv6_ecomm;
        struct cluster_list *cluster;
+       struct lcommunity *lcomm;
 
        if (attr->aspath && !attr->aspath->refcnt) {
                aspath_free(attr->aspath);
@@ -1230,8 +1186,10 @@ void bgp_attr_flush(struct attr *attr)
        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) {
@@ -2308,17 +2266,18 @@ bgp_attr_large_community(struct bgp_attr_parser_args *args)
         * 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);
 
@@ -3534,14 +3493,12 @@ done:
         * we can chuck as4_aggregator and as4_path alltogether in order
         * to save memory
         */
-       if (as4_path) {
-               /*
-                * unintern - it is in the hash
-                * The flag that we got this is still there, but that
-                * does not do any trouble
-                */
-               aspath_unintern(&as4_path);
-       }
+       /*
+        * unintern - it is in the hash
+        * The flag that we got this is still there, but that
+        * does not do any trouble
+        */
+       aspath_unintern(&as4_path);
 
        transit = bgp_attr_get_transit(attr);
        if (ret != BGP_ATTR_PARSE_ERROR) {
@@ -4140,21 +4097,23 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
        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. */
@@ -4584,22 +4543,24 @@ void bgp_dump_routes_attr(struct stream *s, struct attr *attr,
 
        /* 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 */