]> git.proxmox.com Git - mirror_frr.git/commitdiff
bgpd: Policy to control which RIB routes are injected into EVPN
authorMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Fri, 9 Feb 2018 09:09:20 +0000 (01:09 -0800)
committermitesh <mitesh@cumulusnetworks.com>
Tue, 13 Feb 2018 00:02:15 +0000 (16:02 -0800)
FRR/CL provides the means for injecting regular (IPv4) routes
from the BGP RIB into EVPN as type-5 routes.
This needs to be enhanced to allow selective injection.
This can be achieved by adding a route-map option
for the "advertise ipv4/ipv6 unicast" command.

Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn_vty.c
bgpd/bgp_routemap.c
bgpd/bgpd.h

index c7d5f8d1118c785b30704f475dfec5e0afb75594..ec8e2907a69c5b641005259c6df6f30ccbd34627 100644 (file)
@@ -3275,6 +3275,19 @@ void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf,
                 */
                for (ri = rn->info; ri; ri = ri->next) {
                        if (CHECK_FLAG(ri->flags, BGP_INFO_SELECTED)) {
+
+                               /* apply the route-map */
+                               if (bgp_vrf->adv_cmd_rmap[afi][safi].map) {
+                                       int ret = 0;
+
+                                       ret =
+                                               route_map_apply(
+                                                       bgp_vrf->adv_cmd_rmap[afi][safi].map,
+                                                       &rn->p, RMAP_BGP, ri);
+                                       if (ret == RMAP_DENYMATCH)
+                                               continue;
+                               }
+
                                bgp_evpn_advertise_type5_route(bgp_vrf, &rn->p,
                                                               ri->attr,
                                                               afi, safi);
index bd42ccdecfddaf86c83c704910bdac7f8ba5f781..e1e11e44ace97ff70f8a1136d31eb22971719ef0 100644 (file)
@@ -2723,19 +2723,34 @@ DEFUN (no_bgp_evpn_advertise_vni_subnet,
 
 DEFUN (bgp_evpn_advertise_type5,
        bgp_evpn_advertise_type5_cmd,
-       "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR,
+       "advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR " [route-map WORD]",
        "Advertise prefix routes\n"
        BGP_AFI_HELP_STR
-       BGP_SAFI_HELP_STR)
+       BGP_SAFI_HELP_STR
+       "route-map for filtering specific routes\n"
+       "Name of the route map\n")
 {
        struct bgp *bgp_vrf = VTY_GET_CONTEXT(bgp); /* bgp vrf instance */
        int idx_afi = 0;
        int idx_safi = 0;
+       int idx_rmap = 0;
        afi_t afi = 0;
        safi_t safi = 0;
+       int ret = 0;
+       int rmap_changed = 0;
 
        argv_find_and_parse_afi(argv, argc, &idx_afi, &afi);
        argv_find_and_parse_safi(argv, argc, &idx_safi, &safi);
+       ret = argv_find(argv, argc, "route-map", &idx_rmap);
+       if (ret) {
+               if (!bgp_vrf->adv_cmd_rmap[afi][safi].name)
+                       rmap_changed = 1;
+               else if (strcmp(argv[idx_rmap + 1]->arg,
+                               bgp_vrf->adv_cmd_rmap[afi][safi].name) != 0)
+                       rmap_changed = 1;
+       } else if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
+               rmap_changed = 1;
+       }
 
        if (!(afi == AFI_IP) || (afi == AFI_IP6)) {
                vty_out(vty,
@@ -2754,24 +2769,44 @@ DEFUN (bgp_evpn_advertise_type5,
                /* if we are already advertising ipv4 prefix as type-5
                 * nothing to do
                 */
-               if (!CHECK_FLAG(bgp_vrf->vrf_flags,
-                               BGP_VRF_ADVERTISE_IPV4_IN_EVPN)) {
-                       SET_FLAG(bgp_vrf->vrf_flags,
-                                BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
-                       bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
-               }
+               if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
+                                               BGP_VRF_ADVERTISE_IPV4_IN_EVPN))
+                       return CMD_WARNING;
+               SET_FLAG(bgp_vrf->vrf_flags,
+                        BGP_VRF_ADVERTISE_IPV4_IN_EVPN);
        } else {
 
                /* if we are already advertising ipv6 prefix as type-5
                 * nothing to do
                 */
-               if (!CHECK_FLAG(bgp_vrf->vrf_flags,
-                               BGP_VRF_ADVERTISE_IPV6_IN_EVPN)) {
-                       SET_FLAG(bgp_vrf->vrf_flags,
-                                BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
-                       bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
+               if (!rmap_changed && CHECK_FLAG(bgp_vrf->vrf_flags,
+                                               BGP_VRF_ADVERTISE_IPV6_IN_EVPN))
+                       return CMD_WARNING;
+               SET_FLAG(bgp_vrf->vrf_flags,
+                        BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
+       }
+
+       if (rmap_changed) {
+               bgp_evpn_withdraw_type5_routes(bgp_vrf, afi, safi);
+               if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
+                       XFREE(MTYPE_ROUTE_MAP_NAME,
+                             bgp_vrf->adv_cmd_rmap[afi][safi].name);
+                       bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL;
+                       bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL;
                }
        }
+
+       /* set the route-map for advertise command */
+       if (ret && argv[idx_rmap + 1]->arg) {
+               bgp_vrf->adv_cmd_rmap[afi][safi].name =
+                       XSTRDUP(MTYPE_ROUTE_MAP_NAME,
+                               argv[idx_rmap + 1]->arg);
+               bgp_vrf->adv_cmd_rmap[afi][safi].map =
+                       route_map_lookup_by_name(argv[idx_rmap + 1]->arg);
+       }
+
+       /* advertise type-5 routes */
+       bgp_evpn_advertise_type5_routes(bgp_vrf, afi, safi);
        return CMD_SUCCESS;
 }
 
@@ -2827,6 +2862,15 @@ DEFUN (no_bgp_evpn_advertise_type5,
                                   BGP_VRF_ADVERTISE_IPV6_IN_EVPN);
                }
        }
+
+       /* clear the route-map information for advertise ipv4/ipv6 unicast */
+       if (bgp_vrf->adv_cmd_rmap[afi][safi].name) {
+               XFREE(MTYPE_ROUTE_MAP_NAME,
+                     bgp_vrf->adv_cmd_rmap[afi][safi].name);
+               bgp_vrf->adv_cmd_rmap[afi][safi].name = NULL;
+               bgp_vrf->adv_cmd_rmap[afi][safi].map = NULL;
+       }
+
        return CMD_SUCCESS;
 }
 
index 06e53e2daf8d66eb5d98292065c0569fe08cbd9a..4d5624d3b0027a6d501aa4ab55dc025dc37336ea 100644 (file)
@@ -3076,6 +3076,19 @@ static void bgp_route_map_process_update(struct bgp *bgp, const char *rmap_name,
                                }
                        }
                }
+
+       /* for type5 command route-maps */
+       FOREACH_AFI_SAFI (afi, safi) {
+               if (bgp->adv_cmd_rmap[afi][safi].name &&
+                   strcmp(rmap_name, bgp->adv_cmd_rmap[afi][safi].name) == 0) {
+                       if (BGP_DEBUG(zebra, ZEBRA))
+                               zlog_debug(
+                                          "Processing route_map %s update on advertise type5 route command",
+                                          rmap_name);
+                       bgp_evpn_withdraw_type5_routes(bgp, afi, safi);
+                       bgp_evpn_advertise_type5_routes(bgp, afi, safi);
+               }
+       }
 }
 
 static int bgp_route_map_process_update_cb(char *rmap_name)
index 51709f9ed0efddb50fca44d6c44705bea8f002a2..220b6d989e43b551f98b8275d4884b85f7c6c14d 100644 (file)
@@ -452,6 +452,9 @@ struct bgp {
        /* list of corresponding l2vnis (struct bgpevpn) */
        struct list *l2vnis;
 
+       /* route map for advertise ipv4/ipv6 unicast (type-5 routes) */
+       struct bgp_rmap adv_cmd_rmap[AFI_MAX][SAFI_MAX];
+
        QOBJ_FIELDS
 };
 DECLARE_QOBJ_TYPE(bgp)