]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_evpn.c
bgpd: Allow shortened 'no set large-community' and 'no set large-comm-list'
[mirror_frr.git] / bgpd / bgp_evpn.c
index 7be79377866a7f82824434a3e23f055efbb73f27..7f6d34808f1f9eb26aabd833c70adba79f799b17 100644 (file)
@@ -1232,7 +1232,8 @@ static int evpn_route_is_def_gw(struct bgp *bgp, struct bgp_node *rn)
        struct bgp_path_info *local_pi = NULL;
 
        local_pi = NULL;
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1255,7 +1256,8 @@ static int evpn_route_is_sticky(struct bgp *bgp, struct bgp_node *rn)
        struct bgp_path_info *local_pi;
 
        local_pi = NULL;
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1292,7 +1294,8 @@ static int update_evpn_type4_route_entry(struct bgp *bgp, struct evpnes *es,
        evp = (struct prefix_evpn *)&rn->p;
 
        /* locate the local and remote entries if any */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1303,7 +1306,7 @@ static int update_evpn_type4_route_entry(struct bgp *bgp, struct evpnes *es,
                        remote_pi = tmp_pi;
        }
 
-       /* we don't expect to see a remote_pi at this point.
+       /* we don't expect to see a remote_ri at this point.
         * An ES route has esi + vtep_ip as the key,
         * We shouldn't see the same route from any other vtep.
         */
@@ -1449,7 +1452,8 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_def,
 
        *route_changed = 0;
        /* locate the local route entry if any */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp_def->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1587,7 +1591,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
 
        /* See if this is an update of an existing route, or a new add. */
        local_pi = NULL;
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next) {
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -1726,7 +1731,8 @@ static void evpn_cleanup_local_non_best_route(struct bgp *bgp,
        bgp_path_info_reap(rn, local_pi);
 
        /* tell zebra to re-add the best remote path */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn);
+            tmp_pi; tmp_pi = tmp_pi->next) {
                if (CHECK_FLAG(tmp_pi->flags, BGP_PATH_SELECTED)) {
                        curr_select = tmp_pi;
                        break;
@@ -1863,7 +1869,8 @@ static void delete_evpn_route_entry(struct bgp *bgp, afi_t afi, safi_t safi,
        *pi = NULL;
 
        /* Now, find matching route. */
-       for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next)
+       for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+            tmp_pi = tmp_pi->next)
                if (tmp_pi->peer == bgp->peer_self
                    && tmp_pi->type == ZEBRA_ROUTE_BGP
                    && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -2034,7 +2041,8 @@ static int update_all_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
                        continue;
 
                /* Identify local route. */
-               for (tmp_pi = rn->info; tmp_pi; tmp_pi = tmp_pi->next) {
+               for (tmp_pi = bgp_node_get_bgp_path_info(rn); tmp_pi;
+                    tmp_pi = tmp_pi->next) {
                        if (tmp_pi->peer == bgp->peer_self
                            && tmp_pi->type == ZEBRA_ROUTE_BGP
                            && tmp_pi->sub_type == BGP_ROUTE_STATIC)
@@ -2125,8 +2133,8 @@ static int delete_global_type2_routes(struct bgp *bgp, struct bgpevpn *vpn)
        safi = SAFI_EVPN;
 
        rdrn = bgp_node_lookup(bgp->rib[afi][safi], (struct prefix *)&vpn->prd);
-       if (rdrn && rdrn->info) {
-               table = (struct bgp_table *)rdrn->info;
+       if (rdrn && bgp_node_has_bgp_path_info_data(rdrn)) {
+               table = bgp_node_get_bgp_table_info(rdrn);
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                        struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
 
@@ -2195,8 +2203,8 @@ static int delete_all_es_routes(struct bgp *bgp, struct evpnes *es)
        /* Walk this ES's route table and delete all routes. */
        for (rn = bgp_table_top(es->route_table); rn;
             rn = bgp_route_next(rn)) {
-               for (pi = rn->info; (pi != NULL) && (nextpi = pi->next, 1);
-                    pi = nextpi) {
+               for (pi = bgp_node_get_bgp_path_info(rn);
+                    (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
                        bgp_path_info_delete(rn, pi);
                        bgp_path_info_reap(rn, pi);
                }
@@ -2216,8 +2224,8 @@ static int delete_all_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
        /* Walk this VNI's route table and delete all routes. */
        for (rn = bgp_table_top(vpn->route_table); rn;
             rn = bgp_route_next(rn)) {
-               for (pi = rn->info; (pi != NULL) && (nextpi = pi->next, 1);
-                    pi = nextpi) {
+               for (pi = bgp_node_get_bgp_path_info(rn);
+                    (pi != NULL) && (nextpi = pi->next, 1); pi = nextpi) {
                        bgp_path_info_delete(rn, pi);
                        bgp_path_info_reap(rn, pi);
                }
@@ -2353,7 +2361,7 @@ static int install_evpn_route_entry_in_es(struct bgp *bgp, struct evpnes *es,
        rn = bgp_node_get(es->route_table, (struct prefix *)p);
 
        /* Check if route entry is already present. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2454,7 +2462,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
 
        /* Check if route entry is already present. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2498,6 +2506,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                                           &attr_new->mp_nexthop_global)))
                        SET_FLAG(pi->flags, BGP_PATH_IGP_CHANGED);
 
+               bgp_path_info_set_flag(rn, pi, BGP_PATH_ATTR_CHANGED);
                /* Unintern existing, set to new. */
                bgp_attr_unintern(&pi->attr);
                pi->attr = attr_new;
@@ -2529,7 +2538,7 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        rn = bgp_node_get(vpn->route_table, (struct prefix *)p);
 
        /* Check if route entry is already present. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2601,7 +2610,7 @@ static int uninstall_evpn_route_entry_in_es(struct bgp *bgp, struct evpnes *es,
                return 0;
 
        /* Find matching route entry. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2666,7 +2675,7 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                return 0;
 
        /* Find matching route entry. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2707,7 +2716,7 @@ static int uninstall_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                return 0;
 
        /* Find matching route entry. */
-       for (pi = rn->info; pi; pi = pi->next)
+       for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                if (pi->extra
                    && (struct bgp_path_info *)pi->extra->parent == parent_pi)
                        break;
@@ -2900,14 +2909,15 @@ static int install_uninstall_routes_for_es(struct bgp *bgp,
         */
        for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                        struct prefix_evpn *evp = (struct prefix_evpn *)&rn->p;
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                /*
                                 * Consider "valid" remote routes applicable for
                                 * this ES.
@@ -2972,7 +2982,7 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
         */
        for (rd_rn = bgp_table_top(bgp_def->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
@@ -2990,7 +3000,8 @@ static int install_uninstall_routes_for_vrf(struct bgp *bgp_vrf, int install)
                              || is_evpn_prefix_ipaddr_v6(evp)))
                                continue;
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                /* Consider "valid" remote routes applicable for
                                 * this VRF.
                                 */
@@ -3055,7 +3066,7 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp,
        /* EVPN routes are a 2-level table. */
        for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
@@ -3065,7 +3076,8 @@ static int install_uninstall_routes_for_vni(struct bgp *bgp,
                        if (evp->prefix.route_type != rtype)
                                continue;
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
                                /* Consider "valid" remote routes applicable for
                                 * this VNI. */
                                if (!(CHECK_FLAG(pi->flags, BGP_PATH_VALID)
@@ -3500,7 +3512,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
                rn = bgp_node_lookup(vpn->route_table, (struct prefix *)&p);
                if (!rn) /* unexpected */
                        return 0;
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self &&
                            pi->type == ZEBRA_ROUTE_BGP
                            && pi->sub_type == BGP_ROUTE_STATIC)
@@ -3530,7 +3542,7 @@ static int update_advertise_vni_routes(struct bgp *bgp, struct bgpevpn *vpn)
                if (evp->prefix.route_type != BGP_EVPN_MAC_IP_ROUTE)
                        continue;
 
-               for (pi = rn->info; pi; pi = pi->next)
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next)
                        if (pi->peer == bgp->peer_self
                            && pi->type == ZEBRA_ROUTE_BGP
                            && pi->sub_type == BGP_ROUTE_STATIC)
@@ -4228,7 +4240,7 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                /* Only care about "selected" routes - non-imported. */
                /* TODO: Support for AddPath for EVPN. */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
                            && (!pi->extra || !pi->extra->parent)) {
                                bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
@@ -4300,7 +4312,7 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
                 * attribute. Also, we only consider "non-imported" routes.
                 * TODO: Support for AddPath for EVPN.
                 */
-               for (pi = rn->info; pi; pi = pi->next) {
+               for (pi = bgp_node_get_bgp_path_info(rn); pi; pi = pi->next) {
                        if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
                            && (!pi->extra || !pi->extra->parent)) {
 
@@ -5262,13 +5274,14 @@ int bgp_filter_evpn_routes_upon_martian_nh_change(struct bgp *bgp)
        /* EVPN routes are a 2-level table. */
        for (rd_rn = bgp_table_top(bgp->rib[afi][safi]); rd_rn;
             rd_rn = bgp_route_next(rd_rn)) {
-               table = (struct bgp_table *)(rd_rn->info);
+               table = bgp_node_get_bgp_table_info(rd_rn);
                if (!table)
                        continue;
 
                for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
 
-                       for (pi = rn->info; pi; pi = pi->next) {
+                       for (pi = bgp_node_get_bgp_path_info(rn); pi;
+                            pi = pi->next) {
 
                                /* Consider "valid" remote routes applicable for
                                 * this VNI. */
@@ -5446,11 +5459,16 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni, vrf_id_t vrf_id, struct ethaddr *rmac,
        if (filter)
                SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_L3VNI_PREFIX_ROUTES_ONLY);
 
-       /* auto derive RD/RT */
+       /* Map auto derive or configured RTs */
        if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
                evpn_auto_rt_import_add_for_vrf(bgp_vrf);
+       else
+               bgp_evpn_map_vrf_to_its_rts(bgp_vrf);
+
        if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
                evpn_auto_rt_export_add_for_vrf(bgp_vrf);
+
+       /* auto derive RD */
        bgp_evpn_derive_auto_rd_for_vrf(bgp_vrf);
 
        /* link all corresponding l2vnis */
@@ -5518,12 +5536,16 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni, vrf_id_t vrf_id)
        /* remove the Rmac from the BGP vrf */
        memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
 
-       /* delete RD/RT */
+       /* remove default import RT or Unmap non-default import RT */
        if (!list_isempty(bgp_vrf->vrf_import_rtl)) {
                bgp_evpn_unmap_vrf_from_its_rts(bgp_vrf);
-               list_delete_all_node(bgp_vrf->vrf_import_rtl);
+               if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
+                       list_delete_all_node(bgp_vrf->vrf_import_rtl);
        }
-       if (!list_isempty(bgp_vrf->vrf_export_rtl)) {
+
+       /* remove default export RT */
+       if (!list_isempty(bgp_vrf->vrf_export_rtl) &&
+           !CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
                list_delete_all_node(bgp_vrf->vrf_export_rtl);
        }