]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_attr.c
Merge pull request #3409 from opensourcerouting/feature/cleanup-topotest-docker-docs
[mirror_frr.git] / bgpd / bgp_attr.c
index b853b2b0850ff90ab54ec5307d9798625c2fa2e1..87ebb9c285f91eaf214fe3314d7048d2071019e3 100644 (file)
@@ -146,7 +146,7 @@ static unsigned int cluster_hash_key_make(void *p)
        return jhash(cluster->list, cluster->length, 0);
 }
 
-static int cluster_hash_cmp(const void *p1, const void *p2)
+static bool cluster_hash_cmp(const void *p1, const void *p2)
 {
        const struct cluster_list *cluster1 = p1;
        const struct cluster_list *cluster2 = p2;
@@ -260,11 +260,11 @@ void bgp_attr_flush_encap(struct attr *attr)
  *
  * This algorithm could be made faster if needed
  */
-static int encap_same(struct bgp_attr_encap_subtlv *h1,
-                     struct bgp_attr_encap_subtlv *h2)
+static int encap_same(const struct bgp_attr_encap_subtlv *h1,
+                     const struct bgp_attr_encap_subtlv *h2)
 {
-       struct bgp_attr_encap_subtlv *p;
-       struct bgp_attr_encap_subtlv *q;
+       const struct bgp_attr_encap_subtlv *p;
+       const struct bgp_attr_encap_subtlv *q;
 
        if (h1 == h2)
                return 1;
@@ -355,10 +355,10 @@ static unsigned int encap_hash_key_make(void *p)
        return jhash(encap->value, encap->length, 0);
 }
 
-static int encap_hash_cmp(const void *p1, const void *p2)
+static bool encap_hash_cmp(const void *p1, const void *p2)
 {
-       return encap_same((struct bgp_attr_encap_subtlv *)p1,
-                         (struct bgp_attr_encap_subtlv *)p2);
+       return encap_same((const struct bgp_attr_encap_subtlv *)p1,
+                         (const struct bgp_attr_encap_subtlv *)p2);
 }
 
 static void encap_init(void)
@@ -441,7 +441,7 @@ static unsigned int transit_hash_key_make(void *p)
        return jhash(transit->val, transit->length, 0);
 }
 
-static int transit_hash_cmp(const void *p1, const void *p2)
+static bool transit_hash_cmp(const void *p1, const void *p2)
 {
        const struct transit *transit1 = p1;
        const struct transit *transit2 = p2;
@@ -527,7 +527,7 @@ unsigned int attrhash_key_make(void *p)
        return key;
 }
 
-int attrhash_cmp(const void *p1, const void *p2)
+bool attrhash_cmp(const void *p1, const void *p2)
 {
        const struct attr *attr1 = p1;
        const struct attr *attr2 = p2;
@@ -565,10 +565,10 @@ int attrhash_cmp(const void *p1, const void *p2)
                    && overlay_index_same(attr1, attr2)
                    && attr1->nh_ifindex == attr2->nh_ifindex
                    && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex)
-                       return 1;
+                       return true;
        }
 
-       return 0;
+       return false;
 }
 
 static void attrhash_init(void)
@@ -723,8 +723,10 @@ struct attr *bgp_attr_default_set(struct attr *attr, uint8_t origin)
 /* Create the attributes for an aggregate */
 struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                                       struct aspath *aspath,
-                                      struct community *community, int as_set,
-                                      uint8_t atomic_aggregate)
+                                      struct community *community,
+                                      struct ecommunity *ecommunity,
+                                      struct lcommunity *lcommunity,
+                                      int as_set, uint8_t atomic_aggregate)
 {
        struct attr attr;
        struct attr *new;
@@ -760,6 +762,16 @@ struct attr *bgp_attr_aggregate_intern(struct bgp *bgp, uint8_t origin,
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES);
        }
 
+       if (ecommunity) {
+               attr.ecommunity = ecommunity;
+               attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES);
+       }
+
+       if (lcommunity) {
+               attr.lcommunity = lcommunity;
+               attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES);
+       }
+
        if (bgp_flag_check(bgp, BGP_FLAG_GRACEFUL_SHUTDOWN)) {
                bgp_attr_add_gshut_community(&attr);
        }
@@ -837,7 +849,7 @@ void bgp_attr_undup(struct attr *new, struct attr *old)
                aspath_free(new->aspath);
 
        if (new->community != old->community)
-               community_free(new->community);
+               community_free(&new->community);
 
        if (new->ecommunity != old->ecommunity)
                ecommunity_free(&new->ecommunity);
@@ -875,11 +887,8 @@ void bgp_attr_flush(struct attr *attr)
                aspath_free(attr->aspath);
                attr->aspath = NULL;
        }
-       if (attr->community && !attr->community->refcnt) {
-               community_free(attr->community);
-               attr->community = NULL;
-       }
-
+       if (attr->community && !attr->community->refcnt)
+               community_free(&attr->community);
        if (attr->ecommunity && !attr->ecommunity->refcnt)
                ecommunity_free(&attr->ecommunity);
        if (attr->lcommunity && !attr->lcommunity->refcnt)
@@ -1688,7 +1697,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
                                 * - for consistency in rx processing
                                 *
                                 * The following comment is to signal GCC this intention
-                                * and supress the warning
+                                * and suppress the warning
                                 */
        /* FALLTHRU */
        case BGP_ATTR_NHLEN_IPV4:
@@ -1705,8 +1714,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
                        stream_getl(s); /* RD low */
                }
                stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
-               if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+               if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
+                       if (!peer->nexthop.ifp) {
+                               zlog_warn("%s: interface not set appropriately to handle some attributes",
+                                         peer->host);
+                               return BGP_ATTR_PARSE_WITHDRAW;
+                       }
                        attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+               }
                break;
        case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
        case BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL:
@@ -1716,8 +1731,14 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
                        stream_getl(s); /* RD low */
                }
                stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN);
-               if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global))
+               if (IN6_IS_ADDR_LINKLOCAL(&attr->mp_nexthop_global)) {
+                       if (!peer->nexthop.ifp) {
+                               zlog_warn("%s: interface not set appropriately to handle some attributes",
+                                         peer->host);
+                               return BGP_ATTR_PARSE_WITHDRAW;
+                       }
                        attr->nh_ifindex = peer->nexthop.ifp->ifindex;
+               }
                if (attr->mp_nexthop_len
                    == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {
                        stream_getl(s); /* RD high */
@@ -1741,6 +1762,11 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
 
                        attr->mp_nexthop_len = IPV6_MAX_BYTELEN;
                }
+               if (!peer->nexthop.ifp) {
+                       zlog_warn("%s: Interface not set appropriately to handle this some attributes",
+                                 peer->host);
+                       return BGP_ATTR_PARSE_WITHDRAW;
+               }
                attr->nh_lla_ifindex = peer->nexthop.ifp->ifindex;
                break;
        default:
@@ -2598,7 +2624,7 @@ bgp_attr_parse_ret_t bgp_attr_parse(struct peer *peer, struct attr *attr,
                        return ret;
                }
 
-               /* If hard error occured immediately return to the caller. */
+               /* If hard error occurred immediately return to the caller. */
                if (ret == BGP_ATTR_PARSE_ERROR) {
                        flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR,
                                  "%s: Attribute %s, parse error", peer->host,
@@ -3469,8 +3495,8 @@ void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, afi_t afi,
                num_labels = 1;
        }
 
-       return bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
-                                       addpath_encode, addpath_tx_id, attr);
+       bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label, num_labels,
+                                addpath_encode, addpath_tx_id, attr);
 }
 
 void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt)