mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-11-01 12:47:16 +00:00
bgpd: import/export rt for BGP vrf
Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
This commit is contained in:
parent
fe1dc5a374
commit
c581d8b0f4
174
bgpd/bgp_evpn.c
174
bgpd/bgp_evpn.c
@ -301,12 +301,12 @@ static void unmap_vni_from_rt(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
* VNIs but the same across routers (in the same AS) for a particular
|
||||
* VNI.
|
||||
*/
|
||||
static void form_auto_rt(struct bgp *bgp, struct bgpevpn *vpn, struct list *rtl)
|
||||
static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl)
|
||||
{
|
||||
struct ecommunity_val eval;
|
||||
struct ecommunity *ecomadd;
|
||||
|
||||
encode_route_target_as((bgp->as & 0xFFFF), vpn->vni, &eval);
|
||||
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
|
||||
|
||||
ecomadd = ecommunity_new();
|
||||
ecommunity_add_val(ecomadd, &eval);
|
||||
@ -2107,11 +2107,152 @@ static void free_vni_entry(struct hash_backet *backet, struct bgp *bgp)
|
||||
bgp_evpn_free(bgp, vpn);
|
||||
}
|
||||
|
||||
/*
|
||||
* Derive AUTO import RT for BGP VRF - L3VNI
|
||||
*/
|
||||
static void evpn_auto_rt_import_add_for_vrf(struct bgp *bgp_vrf)
|
||||
{
|
||||
UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
|
||||
form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete AUTO import RT from BGP VRF - L3VNI
|
||||
*/
|
||||
static void evpn_auto_rt_import_delete_for_vrf(struct bgp *bgp_vrf)
|
||||
{
|
||||
evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_import_rtl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Derive AUTO export RT for BGP VRF - L3VNI
|
||||
*/
|
||||
static void evpn_auto_rt_export_add_for_vrf(struct bgp *bgp_vrf)
|
||||
{
|
||||
UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
|
||||
form_auto_rt(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete AUTO export RT from BGP VRF - L3VNI
|
||||
*/
|
||||
static void evpn_auto_rt_export_delete_for_vrf(struct bgp *bgp_vrf)
|
||||
{
|
||||
evpn_rt_delete_auto(bgp_vrf, bgp_vrf->l3vni, bgp_vrf->vrf_export_rtl);
|
||||
}
|
||||
|
||||
/*
|
||||
* Public functions.
|
||||
*/
|
||||
|
||||
void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni,
|
||||
struct list *rtl)
|
||||
{
|
||||
struct listnode *node, *nnode, *node_to_del;
|
||||
struct ecommunity *ecom, *ecom_auto;
|
||||
struct ecommunity_val eval;
|
||||
|
||||
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval);
|
||||
|
||||
ecom_auto = ecommunity_new();
|
||||
ecommunity_add_val(ecom_auto, &eval);
|
||||
node_to_del = NULL;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
|
||||
if (ecommunity_match(ecom, ecom_auto)) {
|
||||
ecommunity_free(&ecom);
|
||||
node_to_del = node;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_to_del)
|
||||
list_delete_node(rtl, node_to_del);
|
||||
|
||||
ecommunity_free(&ecom_auto);
|
||||
}
|
||||
|
||||
void bgp_evpn_configure_import_rt_for_vrf(struct bgp *bgp_vrf,
|
||||
struct ecommunity *ecomadd)
|
||||
{
|
||||
/* Remove auto generated RT */
|
||||
evpn_auto_rt_import_delete_for_vrf(bgp_vrf);
|
||||
|
||||
/* Add the newly configured RT to RT list */
|
||||
listnode_add_sort(bgp_vrf->vrf_import_rtl, ecomadd);
|
||||
SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
|
||||
|
||||
//TODO_MITESH: handle RT change (uninstall old routes and install new
|
||||
//routes matching this RT)
|
||||
}
|
||||
|
||||
void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp *bgp_vrf,
|
||||
struct ecommunity *ecomdel)
|
||||
{
|
||||
struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
|
||||
struct ecommunity *ecom = NULL;
|
||||
|
||||
/* remove the RT from the RT list */
|
||||
for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
|
||||
if (ecommunity_match(ecom, ecomdel)) {
|
||||
ecommunity_free(&ecom);
|
||||
node_to_del = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_to_del)
|
||||
list_delete_node(bgp_vrf->vrf_import_rtl, node_to_del);
|
||||
|
||||
/* fallback to auto import rt, if this was the last RT */
|
||||
if (list_isempty(bgp_vrf->vrf_import_rtl)) {
|
||||
UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD);
|
||||
evpn_auto_rt_import_add_for_vrf(bgp_vrf);
|
||||
}
|
||||
|
||||
//TODO_MITESH: handle import RT change
|
||||
//uninstall old routes, install new routes matching this RT
|
||||
}
|
||||
|
||||
void bgp_evpn_configure_export_rt_for_vrf(struct bgp *bgp_vrf,
|
||||
struct ecommunity *ecomadd)
|
||||
{
|
||||
/* remove auto-generated RT */
|
||||
evpn_auto_rt_export_delete_for_vrf(bgp_vrf);
|
||||
|
||||
/* Add the new RT to the RT list */
|
||||
listnode_add_sort(bgp_vrf->vrf_export_rtl, ecomadd);
|
||||
SET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
|
||||
|
||||
/* TODO_MITESH: update all routes */
|
||||
}
|
||||
|
||||
void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp *bgp_vrf,
|
||||
struct ecommunity *ecomdel)
|
||||
{
|
||||
struct listnode *node = NULL, *nnode = NULL, *node_to_del = NULL;
|
||||
struct ecommunity *ecom = NULL;
|
||||
|
||||
/* Remove the RT from the RT list */
|
||||
for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
|
||||
if (ecommunity_match(ecom, ecomdel)) {
|
||||
ecommunity_free(&ecom);
|
||||
node_to_del = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_to_del)
|
||||
list_delete_node(bgp_vrf->vrf_export_rtl, node_to_del);
|
||||
|
||||
/* fall back to auto-generated RT if this was the last RT */
|
||||
if (list_isempty(bgp_vrf->vrf_export_rtl)) {
|
||||
UNSET_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD);
|
||||
evpn_auto_rt_export_add_for_vrf(bgp_vrf);
|
||||
}
|
||||
|
||||
//TODO_MITESH: update all mac-ip routes
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle change to BGP router id. This is invoked twice by the change
|
||||
* handler, first before the router id has been changed and then after
|
||||
@ -2515,7 +2656,7 @@ void bgp_evpn_unmap_vni_from_its_rts(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
*/
|
||||
void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
{
|
||||
form_auto_rt(bgp, vpn, vpn->import_rtl);
|
||||
form_auto_rt(bgp, vpn->vni, vpn->import_rtl);
|
||||
UNSET_FLAG(vpn->flags, VNI_FLAG_IMPRT_CFGD);
|
||||
|
||||
/* Map RT to VNI */
|
||||
@ -2527,7 +2668,7 @@ void bgp_evpn_derive_auto_rt_import(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
*/
|
||||
void bgp_evpn_derive_auto_rt_export(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
{
|
||||
form_auto_rt(bgp, vpn, vpn->export_rtl);
|
||||
form_auto_rt(bgp, vpn->vni, vpn->export_rtl);
|
||||
UNSET_FLAG(vpn->flags, VNI_FLAG_EXPRT_CFGD);
|
||||
}
|
||||
|
||||
@ -2820,7 +2961,11 @@ int bgp_evpn_local_l3vni_add(vni_t l3vni,
|
||||
/* set the router mac - to be used in mac-ip routes for this vrf */
|
||||
memcpy(&bgp_vrf->rmac, rmac, sizeof(struct ethaddr));
|
||||
|
||||
//TODO_MITESH: auto derive RD/RT
|
||||
/* auto derive RD/RT */
|
||||
if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_IMPORT_RT_CFGD))
|
||||
evpn_auto_rt_import_add_for_vrf(bgp_vrf);
|
||||
if (!CHECK_FLAG(bgp_vrf->vrf_flags, BGP_VRF_EXPORT_RT_CFGD))
|
||||
evpn_auto_rt_export_add_for_vrf(bgp_vrf);
|
||||
|
||||
//TODO_MITESH: update all the local mac-ip routes with l3vni/rmac info
|
||||
|
||||
@ -2847,7 +2992,11 @@ int bgp_evpn_local_l3vni_del(vni_t l3vni,
|
||||
/* remove the Rmac from the BGP vrf */
|
||||
memset(&bgp_vrf->rmac, 0, sizeof(struct ethaddr));
|
||||
|
||||
/* TODO_MITESH: delete auto RD/RT */
|
||||
/* delete RD/RT */
|
||||
if (bgp_vrf->vrf_import_rtl && !list_isempty(bgp_vrf->vrf_import_rtl))
|
||||
list_delete(bgp_vrf->vrf_import_rtl);
|
||||
if (bgp_vrf->vrf_export_rtl && !list_isempty(bgp_vrf->vrf_export_rtl))
|
||||
list_delete(bgp_vrf->vrf_export_rtl);
|
||||
|
||||
/* TODO_MITESH: update all local mac-ip routes */
|
||||
|
||||
@ -3004,6 +3153,12 @@ void bgp_evpn_cleanup(struct bgp *bgp)
|
||||
if (bgp->vnihash)
|
||||
hash_free(bgp->vnihash);
|
||||
bgp->vnihash = NULL;
|
||||
if (bgp->vrf_import_rtl)
|
||||
list_delete(bgp->vrf_import_rtl);
|
||||
bgp->vrf_import_rtl = NULL;
|
||||
if (bgp->vrf_export_rtl)
|
||||
list_delete(bgp->vrf_export_rtl);
|
||||
bgp->vrf_export_rtl = NULL;
|
||||
bf_free(bgp->rd_idspace);
|
||||
}
|
||||
|
||||
@ -3021,6 +3176,13 @@ void bgp_evpn_init(struct bgp *bgp)
|
||||
bgp->import_rt_hash =
|
||||
hash_create(import_rt_hash_key_make, import_rt_hash_cmp,
|
||||
"BGP Import RT Hash");
|
||||
bgp->vrf_import_rtl = list_new();
|
||||
bgp->vrf_import_rtl->cmp =
|
||||
(int (*)(void *, void *))evpn_route_target_cmp;
|
||||
|
||||
bgp->vrf_export_rtl = list_new();
|
||||
bgp->vrf_export_rtl->cmp =
|
||||
(int (*)(void *, void *))evpn_route_target_cmp;
|
||||
bf_init(bgp->rd_idspace, UINT16_MAX);
|
||||
/*assign 0th index in the bitfield, so that we start with id 1*/
|
||||
bf_assign_zero_index(bgp->rd_idspace);
|
||||
|
||||
@ -197,7 +197,15 @@ static inline void build_evpn_type3_prefix(struct prefix_evpn *p,
|
||||
p->prefix.ip.ipaddr_v4 = originator_ip;
|
||||
}
|
||||
|
||||
|
||||
extern void evpn_rt_delete_auto(struct bgp*, vni_t, struct list*);
|
||||
extern void bgp_evpn_configure_export_rt_for_vrf(struct bgp*,
|
||||
struct ecommunity*);
|
||||
extern void bgp_evpn_unconfigure_export_rt_for_vrf(struct bgp*,
|
||||
struct ecommunity*);
|
||||
extern void bgp_evpn_configure_import_rt_for_vrf(struct bgp*,
|
||||
struct ecommunity*);
|
||||
extern void bgp_evpn_unconfigure_import_rt_for_vrf(struct bgp*,
|
||||
struct ecommunity*);
|
||||
extern int bgp_evpn_handle_export_rt_change(struct bgp *bgp,
|
||||
struct bgpevpn *vpn);
|
||||
extern void bgp_evpn_handle_rd_change(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
|
||||
@ -1169,40 +1169,15 @@ DEFUN(no_evpnrt5_network,
|
||||
}
|
||||
|
||||
#if defined(HAVE_CUMULUS)
|
||||
static void evpn_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn,
|
||||
struct list *rtl)
|
||||
{
|
||||
struct listnode *node, *nnode, *node_to_del;
|
||||
struct ecommunity *ecom, *ecom_auto;
|
||||
struct ecommunity_val eval;
|
||||
|
||||
encode_route_target_as((bgp->as & 0xFFFF), vpn->vni, &eval);
|
||||
|
||||
ecom_auto = ecommunity_new();
|
||||
ecommunity_add_val(ecom_auto, &eval);
|
||||
node_to_del = NULL;
|
||||
|
||||
for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
|
||||
if (ecommunity_match(ecom, ecom_auto)) {
|
||||
ecommunity_free(&ecom);
|
||||
node_to_del = node;
|
||||
}
|
||||
}
|
||||
|
||||
if (node_to_del)
|
||||
list_delete_node(rtl, node_to_del);
|
||||
|
||||
ecommunity_free(&ecom_auto);
|
||||
}
|
||||
|
||||
static void evpn_import_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
{
|
||||
evpn_rt_delete_auto(bgp, vpn, vpn->import_rtl);
|
||||
evpn_rt_delete_auto(bgp, vpn->vni, vpn->import_rtl);
|
||||
}
|
||||
|
||||
static void evpn_export_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn)
|
||||
{
|
||||
evpn_rt_delete_auto(bgp, vpn, vpn->export_rtl);
|
||||
evpn_rt_delete_auto(bgp, vpn->vni, vpn->export_rtl);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3090,6 +3065,215 @@ static int bgp_evpn_rt_matches_existing(struct list *rtl,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* display L3VNI related info for a VRF instance */
|
||||
DEFUN (show_bgp_vrf_l3vni_info,
|
||||
show_bgp_vrf_l3vni_info_cmd,
|
||||
"show bgp vrf VRFNAME l3vni info",
|
||||
SHOW_STR
|
||||
BGP_STR
|
||||
"show bgp vrf\n"
|
||||
"VRF Name\n"
|
||||
"L3-VNI\n"
|
||||
"L3-VNI info\n")
|
||||
{
|
||||
char buf[ETHER_ADDR_STRLEN];
|
||||
int idx_vrf = 3;
|
||||
const char *name = NULL;
|
||||
struct bgp *bgp = NULL;
|
||||
struct listnode *node = NULL;
|
||||
//struct bgpevpn *vpn = NULL;
|
||||
struct ecommunity *ecom = NULL;
|
||||
|
||||
name = argv[idx_vrf]->arg;
|
||||
bgp = bgp_lookup_by_name(name);
|
||||
if (!bgp) {
|
||||
vty_out(vty, "BGP instance for VRF %s not found",
|
||||
name);
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
vty_out(vty, "BGP VRF: %s\n", name);
|
||||
vty_out(vty, " L3-VNI: %u\n", bgp->l3vni);
|
||||
vty_out(vty, " Rmac: %s\n",
|
||||
prefix_mac2str(&bgp->rmac, buf, sizeof(buf)));
|
||||
/*vty_out(vty, " L2-VNI List:\n");
|
||||
vty_out(vty, " ");
|
||||
for (ALL_LIST_ELEMENTS_RO(bgp->l2vnis, node, vpn))
|
||||
vty_out(vty, "%u ", vpn->vni);
|
||||
vty_out(vty, "\n");*/
|
||||
vty_out(vty, " Export-RTs:\n");
|
||||
vty_out(vty, " ");
|
||||
for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom))
|
||||
vty_out(vty, "%s ", ecommunity_str(ecom));
|
||||
vty_out(vty, "\n");
|
||||
vty_out(vty, " Import-RTs:\n");
|
||||
vty_out(vty, " ");
|
||||
for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom))
|
||||
vty_out(vty, "%s ", ecommunity_str(ecom));
|
||||
vty_out(vty, "\n");
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
/* import/export rt for l3vni-vrf */
|
||||
DEFUN (bgp_evpn_vrf_rt,
|
||||
bgp_evpn_vrf_rt_cmd,
|
||||
"route-target <both|import|export> RT",
|
||||
"Route Target\n"
|
||||
"import and export\n"
|
||||
"import\n"
|
||||
"export\n"
|
||||
"Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
|
||||
{
|
||||
int rt_type;
|
||||
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||
struct ecommunity *ecomadd = NULL;
|
||||
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!strcmp(argv[1]->arg, "import"))
|
||||
rt_type = RT_TYPE_IMPORT;
|
||||
else if (!strcmp(argv[1]->arg, "export"))
|
||||
rt_type = RT_TYPE_EXPORT;
|
||||
else if (!strcmp(argv[1]->arg, "both"))
|
||||
rt_type = RT_TYPE_BOTH;
|
||||
else {
|
||||
vty_out(vty, "%% Invalid Route Target type\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
/* Add/update the import route-target */
|
||||
if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) {
|
||||
ecomadd = ecommunity_str2com(argv[2]->arg,
|
||||
ECOMMUNITY_ROUTE_TARGET, 0);
|
||||
if (!ecomadd) {
|
||||
vty_out(vty, "%% Malformed Route Target list\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ecommunity_str(ecomadd);
|
||||
|
||||
/* Do nothing if we already have this import route-target */
|
||||
if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
|
||||
ecomadd))
|
||||
bgp_evpn_configure_import_rt_for_vrf(bgp, ecomadd);
|
||||
}
|
||||
|
||||
/* Add/update the export route-target */
|
||||
if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) {
|
||||
ecomadd = ecommunity_str2com(argv[2]->arg,
|
||||
ECOMMUNITY_ROUTE_TARGET, 0);
|
||||
if (!ecomadd) {
|
||||
vty_out(vty, "%% Malformed Route Target list\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ecommunity_str(ecomadd);
|
||||
|
||||
/* Do nothing if we already have this export route-target */
|
||||
if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl,
|
||||
ecomadd))
|
||||
bgp_evpn_configure_export_rt_for_vrf(bgp, ecomadd);
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (no_bgp_evpn_vrf_rt,
|
||||
no_bgp_evpn_vrf_rt_cmd,
|
||||
"no route-target <both|import|export> RT",
|
||||
NO_STR
|
||||
"Route Target\n"
|
||||
"import and export\n"
|
||||
"import\n"
|
||||
"export\n"
|
||||
"ASN:XX or A.B.C.D:XX\n")
|
||||
{
|
||||
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
|
||||
int rt_type, found_ecomdel;
|
||||
struct ecommunity *ecomdel = NULL;
|
||||
|
||||
if (!bgp)
|
||||
return CMD_WARNING;
|
||||
|
||||
if (!strcmp(argv[2]->arg, "import"))
|
||||
rt_type = RT_TYPE_IMPORT;
|
||||
else if (!strcmp(argv[2]->arg, "export"))
|
||||
rt_type = RT_TYPE_EXPORT;
|
||||
else if (!strcmp(argv[2]->arg, "both"))
|
||||
rt_type = RT_TYPE_BOTH;
|
||||
else {
|
||||
vty_out(vty, "%% Invalid Route Target type\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
|
||||
if (rt_type == RT_TYPE_IMPORT) {
|
||||
if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
|
||||
vty_out(vty,
|
||||
"%% Import RT is not configured for this VRF\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
} else if (rt_type == RT_TYPE_EXPORT) {
|
||||
if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
|
||||
vty_out(vty,
|
||||
"%% Export RT is not configured for this VRF\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
} else if (rt_type == RT_TYPE_BOTH) {
|
||||
if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)
|
||||
&& !CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
|
||||
vty_out(vty,
|
||||
"%% Import/Export RT is not configured for this VRF\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
ecomdel = ecommunity_str2com(argv[3]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
|
||||
if (!ecomdel) {
|
||||
vty_out(vty, "%% Malformed Route Target list\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
ecommunity_str(ecomdel);
|
||||
|
||||
if (rt_type == RT_TYPE_IMPORT) {
|
||||
if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
|
||||
ecomdel)) {
|
||||
vty_out(vty,
|
||||
"%% RT specified does not match configuration for this VRF\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
bgp_evpn_unconfigure_import_rt_for_vrf(bgp, ecomdel);
|
||||
} else if (rt_type == RT_TYPE_EXPORT) {
|
||||
if (!bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl,
|
||||
ecomdel)) {
|
||||
vty_out(vty,
|
||||
"%% RT specified does not match configuration for this VRF\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
bgp_evpn_unconfigure_export_rt_for_vrf(bgp, ecomdel);
|
||||
} else if (rt_type == RT_TYPE_BOTH) {
|
||||
found_ecomdel = 0;
|
||||
|
||||
if (bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
|
||||
ecomdel)) {
|
||||
bgp_evpn_unconfigure_import_rt_for_vrf(bgp, ecomdel);
|
||||
found_ecomdel = 1;
|
||||
}
|
||||
|
||||
if (bgp_evpn_rt_matches_existing(bgp->vrf_export_rtl,
|
||||
ecomdel)) {
|
||||
bgp_evpn_unconfigure_export_rt_for_vrf(bgp, ecomdel);
|
||||
found_ecomdel = 1;
|
||||
}
|
||||
|
||||
if (!found_ecomdel) {
|
||||
vty_out(vty,
|
||||
"%% RT specified does not match configuration for this VRF\n");
|
||||
return CMD_WARNING;
|
||||
}
|
||||
}
|
||||
|
||||
return CMD_SUCCESS;
|
||||
}
|
||||
|
||||
DEFUN (bgp_evpn_vni_rt,
|
||||
bgp_evpn_vni_rt_cmd,
|
||||
@ -3364,6 +3548,7 @@ void bgp_ethernetvpn_init(void)
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_route_vni_macip_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_route_vni_all_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_evpn_import_rt_cmd);
|
||||
install_element(VIEW_NODE, &show_bgp_vrf_l3vni_info_cmd);
|
||||
|
||||
install_element(BGP_EVPN_NODE, &bgp_evpn_vni_cmd);
|
||||
install_element(BGP_EVPN_NODE, &no_bgp_evpn_vni_cmd);
|
||||
@ -3374,6 +3559,8 @@ void bgp_ethernetvpn_init(void)
|
||||
install_element(BGP_EVPN_VNI_NODE, &bgp_evpn_vni_rt_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rt_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE, &no_bgp_evpn_vni_rt_without_val_cmd);
|
||||
install_element(BGP_NODE, &bgp_evpn_vrf_rt_cmd);
|
||||
install_element(BGP_NODE, &no_bgp_evpn_vrf_rt_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE,
|
||||
&bgp_evpn_advertise_default_gw_vni_cmd);
|
||||
install_element(BGP_EVPN_VNI_NODE,
|
||||
|
||||
@ -418,6 +418,14 @@ struct bgp {
|
||||
/* vrf flags */
|
||||
uint32_t vrf_flags;
|
||||
#define BGP_VRF_AUTO (1 << 0)
|
||||
#define BGP_VRF_IMPORT_RT_CFGD (1 << 1)
|
||||
#define BGP_VRF_EXPORT_RT_CFGD (1 << 2)
|
||||
|
||||
/* import rt list for the vrf instance */
|
||||
struct list *vrf_import_rtl;
|
||||
|
||||
/* export rt list for the vrf instance */
|
||||
struct list *vrf_export_rtl;
|
||||
|
||||
QOBJ_FIELDS
|
||||
};
|
||||
|
||||
Loading…
Reference in New Issue
Block a user