]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: import/export rt for BGP vrf
authorMitesh Kanjariya <mitesh@cumulusnetworks.com>
Mon, 9 Oct 2017 01:34:29 +0000 (18:34 -0700)
committerMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Thu, 14 Dec 2017 18:57:05 +0000 (10:57 -0800)
Signed-off-by: Mitesh Kanjariya <mitesh@cumulusnetworks.com>
bgpd/bgp_evpn.c
bgpd/bgp_evpn_private.h
bgpd/bgp_evpn_vty.c
bgpd/bgpd.h

index a477da78d9d8be4da290df0eb1e435339e049f57..bf7d9a369ca3f0b861cf195b11e8dd6537078214 100644 (file)
@@ -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);
index 2a3e98ce4f6528d333cea3004df04d4cf914c555..c5166890578aee3868cf0c40ab27d3871903023f 100644 (file)
@@ -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,
index 91d54d78e6fb91aac20091a2b1836059ccebca5f..57a31866aa251dca57dbd3b33880acda497bab1e 100644 (file)
@@ -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,
index edcaed84a731a7aaa59d9c02c6844a013e042b84..b050f917c569d4ce466c0f571ad53aa299db8a51 100644 (file)
@@ -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
 };