]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: Allow EVPN-sourced routes to be leaked back into EVPN
authorvivek <vivek@cumulusnetworks.com>
Thu, 28 Feb 2019 16:01:38 +0000 (16:01 +0000)
committervivek <vivek@cumulusnetworks.com>
Thu, 28 Feb 2019 16:01:38 +0000 (16:01 +0000)
Refine check on whether a route can be injected into EVPN to allow
EVPN-sourced routes to be injected back into another instance.

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
Reviewed-by: Anuradha Karuppiah <anuradhak@cumulusnetworks.com>
Reviewed-by: Donald Sharp <sharpd@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_route.c

index 1c65d69ef419949c89126f900086cbdc30c5dcb1..361df826fa49d980639f14fc86cddf1c7e712119 100644 (file)
@@ -4234,11 +4234,13 @@ void bgp_evpn_withdraw_type5_routes(struct bgp *bgp_vrf, afi_t afi, safi_t safi)
 
        table = bgp_vrf->rib[afi][safi];
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
-               /* Only care about "selected" routes - non-imported. */
+               /* Only care about "selected" routes. Also ensure that
+                * these are routes that are injectable into EVPN.
+                */
                /* TODO: Support for AddPath for EVPN. */
                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)) {
+                           && is_route_injectable_into_evpn(pi)) {
                                bgp_evpn_withdraw_type5_route(bgp_vrf, &rn->p,
                                                              afi, safi);
                                break;
@@ -4305,12 +4307,13 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
        table = bgp_vrf->rib[afi][safi];
        for (rn = bgp_table_top(table); rn; rn = bgp_route_next(rn)) {
                /* Need to identify the "selected" route entry to use its
-                * attribute. Also, we only consider "non-imported" routes.
+                * attribute. Also, ensure that the route is injectable
+                * into EVPN.
                 * TODO: Support for AddPath for EVPN.
                 */
                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)) {
+                           && is_route_injectable_into_evpn(pi)) {
 
                                /* apply the route-map */
                                if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
index c2fed76a0a21624513f60b2ef07536c782595db8..0027ae51a43f00915e12dfa4ea43682a87af7a10 100644 (file)
@@ -107,6 +107,32 @@ static inline bool is_pi_family_evpn(struct bgp_path_info *pi)
        return is_pi_family_matching(pi, AFI_L2VPN, SAFI_EVPN);
 }
 
+/* Flag if the route is injectable into EVPN. This would be either a
+ * non-imported route or a non-EVPN imported route.
+ */
+static inline bool is_route_injectable_into_evpn(struct bgp_path_info *pi)
+{
+       struct bgp_path_info *parent_pi;
+       struct bgp_table *table;
+       struct bgp_node *rn;
+
+       if (pi->sub_type != BGP_ROUTE_IMPORTED ||
+           !pi->extra ||
+           !pi->extra->parent)
+               return true;
+
+       parent_pi = (struct bgp_path_info *)pi->extra->parent;
+       rn = parent_pi->net;
+       if (!rn)
+               return true;
+       table = bgp_node_table(rn);
+       if (table &&
+           table->afi == AFI_L2VPN &&
+           table->safi == SAFI_EVPN)
+               return false;
+       return true;
+}
+
 extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
                                           struct prefix *p,
                                           struct attr *src_attr, afi_t afi,
index 7ddc10ae011e9f97728acb37ecfa225dd3368d12..0b6c536f5a53e72a4a414d5bc05c5f1dc5b29372 100644 (file)
@@ -2476,8 +2476,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
 
        /* advertise/withdraw type-5 routes */
        if ((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST)) {
-               if (advertise_type5_routes(bgp, afi) && new_select &&
-                   (!new_select->extra || !new_select->extra->parent)) {
+               if (advertise_type5_routes(bgp, afi) &&
+                   new_select &&
+                   is_route_injectable_into_evpn(new_select)) {
 
                        /* apply the route-map */
                        if (bgp->adv_cmd_rmap[afi][safi].map) {
@@ -2500,8 +2501,9 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_node *rn,
                                                               afi, safi);
 
                        }
-               } else if (advertise_type5_routes(bgp, afi) && old_select &&
-                        (!old_select->extra || !old_select->extra->parent))
+               } else if (advertise_type5_routes(bgp, afi) &&
+                          old_select &&
+                          is_route_injectable_into_evpn(old_select))
                        bgp_evpn_withdraw_type5_route(bgp, &rn->p, afi, safi);
        }