From: Mitesh Kanjariya Date: Fri, 9 Feb 2018 09:09:20 +0000 (-0800) Subject: bgpd: Policy to control which RIB routes are injected into EVPN X-Git-Tag: frr-5.0-dev~225^2 X-Git-Url: https://git.puffer.fish/?a=commitdiff_plain;h=refs%2Fpull%2F1745%2Fhead;p=mirror%2Ffrr.git bgpd: Policy to control which RIB routes are injected into EVPN 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 --- diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index c7d5f8d111..ec8e2907a6 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -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); diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c index bd42ccdecf..e1e11e44ac 100644 --- a/bgpd/bgp_evpn_vty.c +++ b/bgpd/bgp_evpn_vty.c @@ -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; } diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index 06e53e2daf..4d5624d3b0 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -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) diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 51709f9ed0..220b6d989e 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -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)