]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_route.c
Merge pull request #3113 from donaldsharp/uninited_value
[mirror_frr.git] / bgpd / bgp_route.c
index 50ffea27bf3740dd6fcd78323e3999f4c5991ac2..715393b91db62ffdc6cc2fb265a78e5606aaecd5 100644 (file)
@@ -215,7 +215,7 @@ static void bgp_info_extra_free(struct bgp_info_extra **extra)
                bgp_unlock(e->bgp_orig);
 
        if ((*extra)->bgp_fs_pbr)
-               list_delete_and_null(&((*extra)->bgp_fs_pbr));
+               list_delete(&((*extra)->bgp_fs_pbr));
        XFREE(MTYPE_BGP_ROUTE_EXTRA, *extra);
 
        *extra = NULL;
@@ -355,7 +355,7 @@ static void bgp_pcount_adjust(struct bgp_node *rn, struct bgp_info *ri)
                if (ri->peer->pcount[table->afi][table->safi])
                        ri->peer->pcount[table->afi][table->safi]--;
                else
-                       flog_err(LIB_ERR_DEVELOPMENT,
+                       flog_err(EC_LIB_DEVELOPMENT,
                                 "Asked to decrement 0 prefix count for peer");
        } else if (BGP_INFO_COUNTABLE(ri)
                   && !CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
@@ -2775,30 +2775,40 @@ static bool overlay_index_equal(afi_t afi, struct bgp_info *info,
 {
        struct eth_segment_id *info_eth_s_id, *info_eth_s_id_remote;
        union gw_addr *info_gw_ip, *info_gw_ip_remote;
-       char temp[16];
+       union {
+               struct eth_segment_id esi;
+               union gw_addr ip;
+       } temp;
 
        if (afi != AFI_L2VPN)
                return true;
        if (!info->attr) {
-               memset(&temp, 0, 16);
-               info_eth_s_id = (struct eth_segment_id *)&temp;
-               info_gw_ip = (union gw_addr *)&temp;
+               memset(&temp, 0, sizeof(temp));
+               info_eth_s_id = &temp.esi;
+               info_gw_ip = &temp.ip;
+
                if (eth_s_id == NULL && gw_ip == NULL)
                        return true;
        } else {
                info_eth_s_id = &(info->attr->evpn_overlay.eth_s_id);
                info_gw_ip = &(info->attr->evpn_overlay.gw_ip);
        }
-       if (gw_ip == NULL)
-               info_gw_ip_remote = (union gw_addr *)&temp;
-       else
+
+       if (gw_ip == NULL) {
+               memset(&temp, 0, sizeof(temp));
+               info_gw_ip_remote = &temp.ip;
+       } else
                info_gw_ip_remote = gw_ip;
-       if (eth_s_id == NULL)
-               info_eth_s_id_remote = (struct eth_segment_id *)&temp;
-       else
+
+       if (eth_s_id == NULL) {
+               memset(&temp, 0, sizeof(temp));
+               info_eth_s_id_remote = &temp.esi;
+       } else
                info_eth_s_id_remote = eth_s_id;
+
        if (!memcmp(info_gw_ip, info_gw_ip_remote, sizeof(union gw_addr)))
                return false;
+
        return !memcmp(info_eth_s_id, info_eth_s_id_remote,
                       sizeof(struct eth_segment_id));
 }
@@ -4040,7 +4050,6 @@ void bgp_clear_stale_route(struct peer *peer, afi_t afi, safi_t safi)
                for (rn = bgp_table_top(peer->bgp->rib[afi][safi]); rn;
                     rn = bgp_route_next(rn)) {
                        struct bgp_node *rm;
-                       struct bgp_info *ri;
 
                        /* look for neighbor in tables */
                        if ((table = rn->info) == NULL)
@@ -4217,7 +4226,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                /* Prefix length check. */
                if (p.prefixlen > prefix_blen(&p) * 8) {
                        flog_err(
-                               BGP_ERR_UPDATE_RCV,
+                               EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (wrong prefix length %d for afi %u)",
                                peer->host, p.prefixlen, packet->afi);
                        return -1;
@@ -4229,7 +4238,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                /* When packet overflow occur return immediately. */
                if (pnt + psize > lim) {
                        flog_err(
-                               BGP_ERR_UPDATE_RCV,
+                               EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d overflows packet)",
                                peer->host, p.prefixlen);
                        return -1;
@@ -4239,7 +4248,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                 * prefix */
                if (psize > (ssize_t)sizeof(p.u)) {
                        flog_err(
-                               BGP_ERR_UPDATE_RCV,
+                               EC_BGP_UPDATE_RCV,
                                "%s [Error] Update packet error (prefix length %d too large for prefix storage %zu)",
                                peer->host, p.prefixlen, sizeof(p.u));
                        return -1;
@@ -4261,7 +4270,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                 * ignored.
                                 */
                                flog_err(
-                                       BGP_ERR_UPDATE_RCV,
+                                       EC_BGP_UPDATE_RCV,
                                        "%s: IPv4 unicast NLRI is multicast address %s, ignoring",
                                        peer->host, inet_ntoa(p.u.prefix4));
                                continue;
@@ -4274,7 +4283,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                char buf[BUFSIZ];
 
                                flog_err(
-                                       BGP_ERR_UPDATE_RCV,
+                                       EC_BGP_UPDATE_RCV,
                                        "%s: IPv6 unicast NLRI is link-local address %s, ignoring",
                                        peer->host,
                                        inet_ntop(AF_INET6, &p.u.prefix6, buf,
@@ -4286,7 +4295,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                                char buf[BUFSIZ];
 
                                flog_err(
-                                       BGP_ERR_UPDATE_RCV,
+                                       EC_BGP_UPDATE_RCV,
                                        "%s: IPv6 unicast NLRI is multicast address %s, ignoring",
                                        peer->host,
                                        inet_ntop(AF_INET6, &p.u.prefix6, buf,
@@ -4316,7 +4325,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
        /* Packet length consistency check. */
        if (pnt != lim) {
                flog_err(
-                       BGP_ERR_UPDATE_RCV,
+                       EC_BGP_UPDATE_RCV,
                        "%s [Error] Update packet error (prefix length mismatch with total length)",
                        peer->host);
                return -1;
@@ -4728,7 +4737,6 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
                        break;
 
        if (ri) {
-               union gw_addr add;
                memset(&add, 0, sizeof(union gw_addr));
                if (attrhash_cmp(ri->attr, attr_new)
                    && overlay_index_equal(afi, ri, bgp_static->eth_s_id, &add)
@@ -4847,7 +4855,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                        return CMD_WARNING_CONFIG_FAILED;
                }
 
-               bgp_static = rn->info;
+               bgp_static = bgp_static_get_node_info(rn);
 
                if ((label_index != BGP_INVALID_LABEL_INDEX)
                    && (label_index != bgp_static->label_index)) {
@@ -4869,7 +4877,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
 
                /* Clear configuration. */
                bgp_static_free(bgp_static);
-               rn->info = NULL;
+               bgp_static_set_node_info(rn, NULL);
                bgp_unlock_node(rn);
                bgp_unlock_node(rn);
        } else {
@@ -4877,10 +4885,9 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                /* Set BGP static route configuration. */
                rn = bgp_node_get(bgp->route[afi][safi], &p);
 
-               if (rn->info) {
+               bgp_static = bgp_static_get_node_info(rn);
+               if (bgp_static) {
                        /* Configuration change. */
-                       bgp_static = rn->info;
-
                        /* Label index cannot be changed. */
                        if (bgp_static->label_index != label_index) {
                                vty_out(vty, "%% cannot change label-index\n");
@@ -4929,7 +4936,7 @@ static int bgp_static_set(struct vty *vty, const char *negate,
                                bgp_static->rmap.map =
                                        route_map_lookup_by_name(rmap);
                        }
-                       rn->info = bgp_static;
+                       bgp_static_set_node_info(rn, bgp_static);
                }
 
                bgp_static->valid = 1;
@@ -4964,14 +4971,16 @@ void bgp_static_add(struct bgp *bgp)
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
-                                       bgp_static = rm->info;
+                                       bgp_static =
+                                               bgp_static_get_node_info(rm);
                                        bgp_static_update_safi(bgp, &rm->p,
                                                               bgp_static, afi,
                                                               safi);
                                }
                        } else {
-                               bgp_static_update(bgp, &rn->p, rn->info, afi,
-                                                 safi);
+                               bgp_static_update(bgp, &rn->p,
+                                                 bgp_static_get_node_info(rn),
+                                                 afi, safi);
                        }
                }
 }
@@ -4999,19 +5008,20 @@ void bgp_static_delete(struct bgp *bgp)
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
-                                       bgp_static = rm->info;
+                                       bgp_static =
+                                               bgp_static_get_node_info(rm);
                                        bgp_static_withdraw_safi(
                                                bgp, &rm->p, AFI_IP, safi,
                                                (struct prefix_rd *)&rn->p);
                                        bgp_static_free(bgp_static);
-                                       rn->info = NULL;
+                                       bgp_static_set_node_info(rn, NULL);
                                        bgp_unlock_node(rn);
                                }
                        } else {
-                               bgp_static = rn->info;
+                               bgp_static = bgp_static_get_node_info(rn);
                                bgp_static_withdraw(bgp, &rn->p, afi, safi);
                                bgp_static_free(bgp_static);
-                               rn->info = NULL;
+                               bgp_static_set_node_info(rn, NULL);
                                bgp_unlock_node(rn);
                        }
                }
@@ -5040,13 +5050,14 @@ void bgp_static_redo_import_check(struct bgp *bgp)
 
                                for (rm = bgp_table_top(table); rm;
                                     rm = bgp_route_next(rm)) {
-                                       bgp_static = rm->info;
+                                       bgp_static =
+                                               bgp_static_get_node_info(rm);
                                        bgp_static_update_safi(bgp, &rm->p,
                                                               bgp_static, afi,
                                                               safi);
                                }
                        } else {
-                               bgp_static = rn->info;
+                               bgp_static = bgp_static_get_node_info(rn);
                                bgp_static_update(bgp, &rn->p, bgp_static, afi,
                                                  safi);
                        }
@@ -5218,7 +5229,7 @@ int bgp_static_set_safi(afi_t afi, safi_t safi, struct vty *vty,
                        if (gwip)
                                prefix_copy(&bgp_static->gatewayIp, &gw_ip);
                }
-               rn->info = bgp_static;
+               bgp_static_set_node_info(rn, bgp_static);
 
                bgp_static->valid = 1;
                bgp_static_update_safi(bgp, &p, bgp_static, afi, safi);
@@ -5280,9 +5291,9 @@ int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *vty,
        if (rn) {
                bgp_static_withdraw_safi(bgp, &p, afi, safi, &prd);
 
-               bgp_static = rn->info;
+               bgp_static = bgp_static_get_node_info(rn);
                bgp_static_free(bgp_static);
-               rn->info = NULL;
+               bgp_static_set_node_info(rn, NULL);
                bgp_unlock_node(rn);
                bgp_unlock_node(rn);
        } else
@@ -5456,7 +5467,8 @@ static void bgp_aggregate_free(struct bgp_aggregate *aggregate)
        XFREE(MTYPE_BGP_AGGREGATE, aggregate);
 }
 
-static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath,
+static int bgp_aggregate_info_same(struct bgp_info *ri, uint8_t origin,
+                                  struct aspath *aspath,
                                   struct community *comm)
 {
        static struct aspath *ae = NULL;
@@ -5467,12 +5479,18 @@ static int bgp_aggregate_info_same(struct bgp_info *ri, struct aspath *aspath,
        if (!ri)
                return 0;
 
+       if (origin != ri->attr->origin)
+               return 0;
+
        if (!aspath_cmp(ri->attr->aspath, (aspath) ? aspath : ae))
                return 0;
 
        if (!community_cmp(ri->attr->community, comm))
                return 0;
 
+       if (!CHECK_FLAG(ri->flags, BGP_INFO_VALID))
+               return 0;
+
        return 1;
 }
 
@@ -5501,7 +5519,8 @@ static void bgp_aggregate_install(struct bgp *bgp, afi_t afi, safi_t safi,
                 * If the aggregate information has not changed
                 * no need to re-install it again.
                 */
-               if (bgp_aggregate_info_same(rn->info, aspath, community)) {
+               if (bgp_aggregate_info_same(rn->info, origin, aspath,
+                                           community)) {
                        bgp_unlock_node(rn);
 
                        if (aspath)
@@ -5766,13 +5785,14 @@ void bgp_aggregate_increment(struct bgp *bgp, struct prefix *p,
        child = bgp_node_get(table, p);
 
        /* Aggregate address configuration check. */
-       for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
-               if ((aggregate = rn->info) != NULL
-                   && rn->p.prefixlen < p->prefixlen) {
+       for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
+               aggregate = bgp_aggregate_get_node_info(rn);
+               if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
                        bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
                        bgp_aggregate_route(bgp, &rn->p, ri, afi, safi, NULL,
                                            aggregate);
                }
+       }
        bgp_unlock_node(child);
 }
 
@@ -5796,13 +5816,14 @@ void bgp_aggregate_decrement(struct bgp *bgp, struct prefix *p,
        child = bgp_node_get(table, p);
 
        /* Aggregate address configuration check. */
-       for (rn = child; rn; rn = bgp_node_parent_nolock(rn))
-               if ((aggregate = rn->info) != NULL
-                   && rn->p.prefixlen < p->prefixlen) {
+       for (rn = child; rn; rn = bgp_node_parent_nolock(rn)) {
+               aggregate = bgp_aggregate_get_node_info(rn);
+               if (aggregate != NULL && rn->p.prefixlen < p->prefixlen) {
                        bgp_aggregate_delete(bgp, &rn->p, afi, safi, aggregate);
                        bgp_aggregate_route(bgp, &rn->p, NULL, afi, safi, del,
                                            aggregate);
                }
+       }
        bgp_unlock_node(child);
 }
 
@@ -5835,12 +5856,12 @@ static int bgp_aggregate_unset(struct vty *vty, const char *prefix_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       aggregate = rn->info;
+       aggregate = bgp_aggregate_get_node_info(rn);
        bgp_aggregate_delete(bgp, &p, afi, safi, aggregate);
        bgp_aggregate_install(bgp, afi, safi, &p, 0, NULL, NULL, 0, aggregate);
 
        /* Unlock aggregate address configuration. */
-       rn->info = NULL;
+       bgp_aggregate_set_node_info(rn, NULL);
        bgp_aggregate_free(aggregate);
        bgp_unlock_node(rn);
        bgp_unlock_node(rn);
@@ -5891,7 +5912,7 @@ static int bgp_aggregate_set(struct vty *vty, const char *prefix_str, afi_t afi,
        aggregate->summary_only = summary_only;
        aggregate->as_set = as_set;
        aggregate->safi = safi;
-       rn->info = aggregate;
+       bgp_aggregate_set_node_info(rn, aggregate);
 
        /* Aggregate address insert into BGP routing table. */
        bgp_aggregate_route(bgp, &p, NULL, afi, safi, NULL, aggregate);
@@ -8286,8 +8307,7 @@ static int bgp_show_table(struct vty *vty, struct bgp *bgp, safi_t safi,
                                        continue;
                        }
                        if (type == bgp_show_type_prefix_longer) {
-                               struct prefix *p = output_arg;
-
+                               p = output_arg;
                                if (!prefix_match(p, &rn->p))
                                        continue;
                        }
@@ -8911,7 +8931,7 @@ static int bgp_show_route(struct vty *vty, struct bgp *bgp, const char *ip_str,
 
 static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
                               struct cmd_token **argv, afi_t afi, safi_t safi,
-                              uint8_t uj)
+                              bool uj)
 {
        struct lcommunity *lcom;
        struct buffer *b;
@@ -8948,7 +8968,7 @@ static int bgp_show_lcommunity(struct vty *vty, struct bgp *bgp, int argc,
 
 static int bgp_show_lcommunity_list(struct vty *vty, struct bgp *bgp,
                                    const char *lcom, afi_t afi, safi_t safi,
-                                   uint8_t uj)
+                                   bool uj)
 {
        struct community_list *list;
 
@@ -9888,12 +9908,14 @@ static int bgp_peer_count_walker(struct thread *t)
                        if (CHECK_FLAG(ri->flags, BGP_INFO_COUNTED)) {
                                pc->count[PCOUNT_COUNTED]++;
                                if (CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
-                                       flog_err(LIB_ERR_DEVELOPMENT,
-                                                "Attempting to count but flags say it is unusable");
+                                       flog_err(
+                                               EC_LIB_DEVELOPMENT,
+                                               "Attempting to count but flags say it is unusable");
                        } else {
                                if (!CHECK_FLAG(ri->flags, BGP_INFO_UNUSEABLE))
-                                       flog_err(LIB_ERR_DEVELOPMENT,
-                                                "Not counted but flags say we should");
+                                       flog_err(
+                                               EC_LIB_DEVELOPMENT,
+                                               "Not counted but flags say we should");
                        }
                }
        }
@@ -10765,12 +10787,12 @@ static int bgp_distance_set(struct vty *vty, const char *distance_str,
 
        /* Get BGP distance node. */
        rn = bgp_node_get(bgp_distance_table[afi][safi], (struct prefix *)&p);
-       if (rn->info) {
-               bdistance = rn->info;
+       bdistance = bgp_distance_get_node(rn);
+       if (bdistance)
                bgp_unlock_node(rn);
-       else {
+       else {
                bdistance = bgp_distance_new();
-               rn->info = bdistance;
+               bgp_distance_set_node_info(rn, bdistance);
        }
 
        /* Set distance value. */
@@ -10815,7 +10837,7 @@ static int bgp_distance_unset(struct vty *vty, const char *distance_str,
                return CMD_WARNING_CONFIG_FAILED;
        }
 
-       bdistance = rn->info;
+       bdistance = bgp_distance_get_node(rn);
        distance = atoi(distance_str);
 
        if (bdistance->distance != distance) {
@@ -10854,7 +10876,7 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
        sockunion2hostprefix(&peer->su, &q);
        rn = bgp_node_match(bgp_distance_table[afi][safi], &q);
        if (rn) {
-               bdistance = rn->info;
+               bdistance = bgp_distance_get_node(rn);
                bgp_unlock_node(rn);
 
                if (bdistance->access_list) {
@@ -10869,7 +10891,7 @@ uint8_t bgp_distance_apply(struct prefix *p, struct bgp_info *rinfo, afi_t afi,
        /* Backdoor check. */
        rn = bgp_node_lookup(bgp->route[afi][safi], p);
        if (rn) {
-               bgp_static = rn->info;
+               bgp_static = bgp_static_get_node_info(rn);
                bgp_unlock_node(rn);
 
                if (bgp_static->backdoor) {
@@ -11284,7 +11306,8 @@ static void bgp_config_write_network_vpn(struct vty *vty, struct bgp *bgp,
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       if ((bgp_static = rn->info) == NULL)
+                       bgp_static = bgp_static_get_node_info(rn);
+                       if (bgp_static == NULL)
                                continue;
 
                        p = &rn->p;
@@ -11333,7 +11356,8 @@ static void bgp_config_write_network_evpn(struct vty *vty, struct bgp *bgp,
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-                       if ((bgp_static = rn->info) == NULL)
+                       bgp_static = bgp_static_get_node_info(rn);
+                       if (bgp_static == NULL)
                                continue;
 
                        char *macrouter = NULL;
@@ -11408,7 +11432,8 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        /* Network configuration. */
        for (rn = bgp_table_top(bgp->route[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               if ((bgp_static = rn->info) == NULL)
+               bgp_static = bgp_static_get_node_info(rn);
+               if (bgp_static == NULL)
                        continue;
 
                p = &rn->p;
@@ -11454,7 +11479,8 @@ void bgp_config_write_network(struct vty *vty, struct bgp *bgp, afi_t afi,
        /* Aggregate-address configuration. */
        for (rn = bgp_table_top(bgp->aggregate[afi][safi]); rn;
             rn = bgp_route_next(rn)) {
-               if ((bgp_aggregate = rn->info) == NULL)
+               bgp_aggregate = bgp_aggregate_get_node_info(rn);
+               if (bgp_aggregate == NULL)
                        continue;
 
                p = &rn->p;
@@ -11504,8 +11530,9 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
        }
 
        for (rn = bgp_table_top(bgp_distance_table[afi][safi]); rn;
-            rn = bgp_route_next(rn))
-               if ((bdistance = rn->info) != NULL) {
+            rn = bgp_route_next(rn)) {
+               bdistance = bgp_distance_get_node(rn);
+               if (bdistance != NULL) {
                        char buf[PREFIX_STRLEN];
 
                        vty_out(vty, "  distance %d %s %s\n",
@@ -11514,6 +11541,7 @@ void bgp_config_write_distance(struct vty *vty, struct bgp *bgp, afi_t afi,
                                bdistance->access_list ? bdistance->access_list
                                                       : "");
                }
+       }
 }
 
 /* Allocate routing table structure and install commands. */