summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_evpn_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_evpn_vty.c')
-rw-r--r--bgpd/bgp_evpn_vty.c425
1 files changed, 324 insertions, 101 deletions
diff --git a/bgpd/bgp_evpn_vty.c b/bgpd/bgp_evpn_vty.c
index 5ad5cf8bf..f920a783b 100644
--- a/bgpd/bgp_evpn_vty.c
+++ b/bgpd/bgp_evpn_vty.c
@@ -373,7 +373,7 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
char buf1[INET6_ADDRSTRLEN];
char *ecom_str;
struct listnode *node, *nnode;
- struct ecommunity *ecom;
+ struct vrf_route_target *l3rt;
json_object *json_import_rtl = NULL;
json_object *json_export_rtl = NULL;
char buf2[ETHER_ADDR_STRLEN];
@@ -431,8 +431,8 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
if (!json)
vty_out(vty, " Import Route Target:\n");
- for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, ecom)) {
- ecom_str = ecommunity_ecom2str(ecom,
+ for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_import_rtl, node, nnode, l3rt)) {
+ ecom_str = ecommunity_ecom2str(l3rt->ecom,
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
if (json)
@@ -449,8 +449,8 @@ static void display_l3vni(struct vty *vty, struct bgp *bgp_vrf,
else
vty_out(vty, " Export Route Target:\n");
- for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, ecom)) {
- ecom_str = ecommunity_ecom2str(ecom,
+ for (ALL_LIST_ELEMENTS(bgp_vrf->vrf_export_rtl, node, nnode, l3rt)) {
+ ecom_str = ecommunity_ecom2str(l3rt->ecom,
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
if (json)
@@ -913,7 +913,7 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
char rt_buf[25];
char *ecom_str;
struct listnode *node, *nnode;
- struct ecommunity *ecom;
+ struct vrf_route_target *l3rt;
if (!bgp->l3vni)
return;
@@ -954,8 +954,8 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
&bgp->vrf_prd);
}
- for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode, ecom)) {
- ecom_str = ecommunity_ecom2str(ecom,
+ for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode, l3rt)) {
+ ecom_str = ecommunity_ecom2str(l3rt->ecom,
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
if (json) {
@@ -982,8 +982,8 @@ static void show_l3vni_entry(struct vty *vty, struct bgp *bgp,
if (json)
json_object_object_add(json_vni, "importRTs", json_import_rtl);
- for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode, ecom)) {
- ecom_str = ecommunity_ecom2str(ecom,
+ for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode, l3rt)) {
+ ecom_str = ecommunity_ecom2str(l3rt->ecom,
ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
if (json) {
@@ -1984,12 +1984,12 @@ DEFUN(no_evpnrt5_network,
static void evpn_import_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn)
{
- evpn_rt_delete_auto(bgp, vpn->vni, vpn->import_rtl);
+ evpn_rt_delete_auto(bgp, vpn->vni, vpn->import_rtl, false);
}
static void evpn_export_rt_delete_auto(struct bgp *bgp, struct bgpevpn *vpn)
{
- evpn_rt_delete_auto(bgp, vpn->vni, vpn->export_rtl);
+ evpn_rt_delete_auto(bgp, vpn->vni, vpn->export_rtl, false);
}
/*
@@ -3980,11 +3980,13 @@ DEFUN (bgp_evpn_advertise_type5,
DEFUN (no_bgp_evpn_advertise_type5,
no_bgp_evpn_advertise_type5_cmd,
- "no advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR,
+ "no advertise " BGP_AFI_CMD_STR "" BGP_SAFI_CMD_STR " [route-map WORD]",
NO_STR
"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;
@@ -5654,18 +5656,35 @@ DEFUN (no_bgp_evpn_vni_rd_without_val,
* Loop over all extended-communities in the route-target list rtl and
* return 1 if we find ecomtarget
*/
-static int bgp_evpn_rt_matches_existing(struct list *rtl,
- struct ecommunity *ecomtarget)
+static bool bgp_evpn_rt_matches_existing(struct list *rtl,
+ struct ecommunity *ecomtarget)
{
- struct listnode *node, *nnode;
+ struct listnode *node;
struct ecommunity *ecom;
- for (ALL_LIST_ELEMENTS(rtl, node, nnode, ecom)) {
+ for (ALL_LIST_ELEMENTS_RO(rtl, node, ecom)) {
if (ecommunity_match(ecom, ecomtarget))
- return 1;
+ return true;
}
- return 0;
+ return false;
+}
+
+/*
+ * L3 RT version of above.
+ */
+static bool bgp_evpn_vrf_rt_matches_existing(struct list *rtl,
+ struct ecommunity *ecomtarget)
+{
+ struct listnode *node;
+ struct vrf_route_target *l3rt;
+
+ for (ALL_LIST_ELEMENTS_RO(rtl, node, l3rt)) {
+ if (ecommunity_match(l3rt->ecom, ecomtarget))
+ return true;
+ }
+
+ return false;
}
/* display L3VNI related info for a VRF instance */
@@ -5685,7 +5704,7 @@ DEFUN (show_bgp_vrf_l3vni_info,
struct bgp *bgp = NULL;
struct listnode *node = NULL;
struct bgpevpn *vpn = NULL;
- struct ecommunity *ecom = NULL;
+ struct vrf_route_target *l3rt;
json_object *json = NULL;
json_object *json_vnis = NULL;
json_object *json_export_rts = NULL;
@@ -5735,13 +5754,13 @@ DEFUN (show_bgp_vrf_l3vni_info,
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));
+ for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, l3rt))
+ vty_out(vty, "%s ", ecommunity_str(l3rt->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));
+ for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, l3rt))
+ vty_out(vty, "%s ", ecommunity_str(l3rt->ecom));
vty_out(vty, "\n");
vty_out(vty, " RD: %pRD\n", &bgp->vrf_prd);
} else {
@@ -5765,17 +5784,19 @@ DEFUN (show_bgp_vrf_l3vni_info,
json_object_object_add(json, "l2vnis", json_vnis);
/* export rts */
- for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, ecom))
+ for (ALL_LIST_ELEMENTS_RO(bgp->vrf_export_rtl, node, l3rt))
json_object_array_add(
json_export_rts,
- json_object_new_string(ecommunity_str(ecom)));
+ json_object_new_string(
+ ecommunity_str(l3rt->ecom)));
json_object_object_add(json, "export-rts", json_export_rts);
/* import rts */
- for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, ecom))
+ for (ALL_LIST_ELEMENTS_RO(bgp->vrf_import_rtl, node, l3rt))
json_object_array_add(
json_import_rts,
- json_object_new_string(ecommunity_str(ecom)));
+ json_object_new_string(
+ ecommunity_str(l3rt->ecom)));
json_object_object_add(json, "import-rts", json_import_rts);
json_object_string_addf(json, "rd", "%pRD", &bgp->vrf_prd);
}
@@ -5785,22 +5806,133 @@ DEFUN (show_bgp_vrf_l3vni_info,
return CMD_SUCCESS;
}
+static int add_rt(struct bgp *bgp, struct ecommunity *ecom, bool is_import,
+ bool is_wildcard)
+{
+ /* Do nothing if we already have this route-target */
+ if (is_import) {
+ if (!bgp_evpn_vrf_rt_matches_existing(bgp->vrf_import_rtl,
+ ecom))
+ bgp_evpn_configure_import_rt_for_vrf(bgp, ecom,
+ is_wildcard);
+ else
+ return -1;
+ } else {
+ if (!bgp_evpn_vrf_rt_matches_existing(bgp->vrf_export_rtl,
+ ecom))
+ bgp_evpn_configure_export_rt_for_vrf(bgp, ecom);
+ else
+ return -1;
+ }
+
+ return 0;
+}
+
+static int del_rt(struct bgp *bgp, struct ecommunity *ecom, bool is_import)
+{
+ /* Verify we already have this route-target */
+ if (is_import) {
+ if (!bgp_evpn_vrf_rt_matches_existing(bgp->vrf_import_rtl,
+ ecom))
+ return -1;
+
+ bgp_evpn_unconfigure_import_rt_for_vrf(bgp, ecom);
+ } else {
+ if (!bgp_evpn_vrf_rt_matches_existing(bgp->vrf_export_rtl,
+ ecom))
+ return -1;
+
+ bgp_evpn_unconfigure_export_rt_for_vrf(bgp, ecom);
+ }
+
+ return 0;
+}
+
+static int parse_rtlist(struct bgp *bgp, struct vty *vty, int argc,
+ struct cmd_token **argv, int rt_idx, bool is_add,
+ bool is_import)
+{
+ int ret = CMD_SUCCESS;
+ bool is_wildcard = false;
+ struct ecommunity *ecom = NULL;
+
+ for (int i = rt_idx; i < argc; i++) {
+ is_wildcard = false;
+
+ /*
+ * Special handling for wildcard '*' here.
+ *
+ * Let's just convert it to 0 here so we dont have to modify
+ * the ecommunity parser.
+ */
+ if ((argv[i]->arg)[0] == '*') {
+ if (!is_import) {
+ vty_out(vty,
+ "%% Wildcard '*' only applicable for import\n");
+ ret = CMD_WARNING;
+ continue;
+ }
+
+ (argv[i]->arg)[0] = '0';
+ is_wildcard = true;
+ }
+
+ ecom = ecommunity_str2com(argv[i]->arg, ECOMMUNITY_ROUTE_TARGET,
+ 0);
+
+ /* Put it back as was */
+ if (is_wildcard)
+ (argv[i]->arg)[0] = '*';
+
+ if (!ecom) {
+ vty_out(vty, "%% Malformed Route Target list\n");
+ ret = CMD_WARNING;
+ continue;
+ }
+
+ ecommunity_str(ecom);
+
+ if (is_add) {
+ if (add_rt(bgp, ecom, is_import, is_wildcard) != 0) {
+ vty_out(vty,
+ "%% RT specified already configured for this VRF: %s\n",
+ argv[i]->arg);
+ ecommunity_free(&ecom);
+ ret = CMD_WARNING;
+ }
+
+ } else {
+ if (del_rt(bgp, ecom, is_import) != 0) {
+ vty_out(vty,
+ "%% RT specified does not match configuration for this VRF: %s\n",
+ argv[i]->arg);
+ ret = CMD_WARNING;
+ }
+
+ ecommunity_free(&ecom);
+ }
+ }
+
+ return ret;
+}
+
/* import/export rt for l3vni-vrf */
DEFUN (bgp_evpn_vrf_rt,
bgp_evpn_vrf_rt_cmd,
- "route-target <both|import|export> RT",
+ "route-target <both|import|export> RTLIST...",
"Route Target\n"
"import and export\n"
"import\n"
"export\n"
- "Route target (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
+ "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN|*:OPQR|*:MN)\n")
{
+ int ret = CMD_SUCCESS;
+ int tmp_ret = CMD_SUCCESS;
int rt_type;
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
- struct ecommunity *ecomadd = NULL;
if (!bgp)
- return CMD_WARNING;
+ return CMD_WARNING_CONFIG_FAILED;
if (!strcmp(argv[1]->arg, "import"))
rt_type = RT_TYPE_IMPORT;
@@ -5810,49 +5942,82 @@ DEFUN (bgp_evpn_vrf_rt,
rt_type = RT_TYPE_BOTH;
else {
vty_out(vty, "%% Invalid Route Target type\n");
- return CMD_WARNING;
+ return CMD_WARNING_CONFIG_FAILED;
}
- ecomadd = ecommunity_str2com(argv[2]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
- if (!ecomadd) {
- vty_out(vty, "%% Malformed Route Target list\n");
- return CMD_WARNING;
+ if (strmatch(argv[2]->arg, "auto")) {
+ vty_out(vty, "%% `auto` cannot be configured via list\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- ecommunity_str(ecomadd);
/* Add/update the import route-target */
- if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT) {
- /* 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);
- }
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT)
+ tmp_ret = parse_rtlist(bgp, vty, argc, argv, 2, true, true);
- /* Add/update the export route-target */
- if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT) {
- /* 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);
+ if (ret == CMD_SUCCESS && tmp_ret != CMD_SUCCESS)
+ ret = tmp_ret;
+
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT)
+ tmp_ret = parse_rtlist(bgp, vty, argc, argv, 2, true, false);
+
+ if (ret == CMD_SUCCESS && tmp_ret != CMD_SUCCESS)
+ ret = tmp_ret;
+
+ return ret;
+}
+
+DEFPY (bgp_evpn_vrf_rt_auto,
+ bgp_evpn_vrf_rt_auto_cmd,
+ "route-target <both|import|export>$type auto",
+ "Route Target\n"
+ "import and export\n"
+ "import\n"
+ "export\n"
+ "Automatically derive route target\n")
+{
+ struct bgp *bgp = VTY_GET_CONTEXT(bgp);
+ int rt_type;
+
+ if (!bgp)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (strmatch(type, "import"))
+ rt_type = RT_TYPE_IMPORT;
+ else if (strmatch(type, "export"))
+ rt_type = RT_TYPE_EXPORT;
+ else if (strmatch(type, "both"))
+ rt_type = RT_TYPE_BOTH;
+ else {
+ vty_out(vty, "%% Invalid Route Target type\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT)
+ bgp_evpn_configure_import_auto_rt_for_vrf(bgp);
+
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT)
+ bgp_evpn_configure_export_auto_rt_for_vrf(bgp);
+
return CMD_SUCCESS;
}
DEFUN (no_bgp_evpn_vrf_rt,
no_bgp_evpn_vrf_rt_cmd,
- "no route-target <both|import|export> RT",
+ "no route-target <both|import|export> RTLIST...",
NO_STR
"Route Target\n"
"import and export\n"
"import\n"
"export\n"
- EVPN_ASN_IP_HELP_STR)
+ "Space separated route target list (A.B.C.D:MN|EF:OPQR|GHJK:MN)\n")
{
struct bgp *bgp = VTY_GET_CONTEXT(bgp);
- int rt_type, found_ecomdel;
- struct ecommunity *ecomdel = NULL;
+ int ret = CMD_SUCCESS;
+ int tmp_ret = CMD_SUCCESS;
+ int rt_type;
if (!bgp)
- return CMD_WARNING;
+ return CMD_WARNING_CONFIG_FAILED;
if (!strcmp(argv[2]->arg, "import"))
rt_type = RT_TYPE_IMPORT;
@@ -5862,79 +6027,104 @@ DEFUN (no_bgp_evpn_vrf_rt,
rt_type = RT_TYPE_BOTH;
else {
vty_out(vty, "%% Invalid Route Target type\n");
- return CMD_WARNING;
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+
+ if (!strcmp(argv[3]->arg, "auto")) {
+ vty_out(vty, "%% `auto` cannot be unconfigured via list\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
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;
+ return CMD_WARNING_CONFIG_FAILED;
}
} 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;
+ return CMD_WARNING_CONFIG_FAILED;
}
} 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;
+ return CMD_WARNING_CONFIG_FAILED;
}
}
- ecomdel = ecommunity_str2com(argv[3]->arg, ECOMMUNITY_ROUTE_TARGET, 0);
- if (!ecomdel) {
- vty_out(vty, "%% Malformed Route Target list\n");
- return CMD_WARNING;
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT)
+ tmp_ret = parse_rtlist(bgp, vty, argc, argv, 3, false, true);
+
+ if (ret == CMD_SUCCESS && tmp_ret != CMD_SUCCESS)
+ ret = tmp_ret;
+
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT)
+ tmp_ret = parse_rtlist(bgp, vty, argc, argv, 3, false, false);
+
+ if (ret == CMD_SUCCESS && tmp_ret != CMD_SUCCESS)
+ ret = tmp_ret;
+
+ return ret;
+}
+
+DEFPY (no_bgp_evpn_vrf_rt_auto,
+ no_bgp_evpn_vrf_rt_auto_cmd,
+ "no route-target <both|import|export>$type auto",
+ NO_STR
+ "Route Target\n"
+ "import and export\n"
+ "import\n"
+ "export\n"
+ "Automatically derive route target\n")
+{
+ struct bgp *bgp = VTY_GET_CONTEXT(bgp);
+ int rt_type;
+
+ if (!bgp)
+ return CMD_WARNING_CONFIG_FAILED;
+
+ if (strmatch(type, "import"))
+ rt_type = RT_TYPE_IMPORT;
+ else if (strmatch(type, "export"))
+ rt_type = RT_TYPE_EXPORT;
+ else if (strmatch(type, "both"))
+ rt_type = RT_TYPE_BOTH;
+ else {
+ vty_out(vty, "%% Invalid Route Target type\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- ecommunity_str(ecomdel);
if (rt_type == RT_TYPE_IMPORT) {
- if (!bgp_evpn_rt_matches_existing(bgp->vrf_import_rtl,
- ecomdel)) {
- ecommunity_free(&ecomdel);
+ if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_AUTO_RT_CFGD)) {
vty_out(vty,
- "%% RT specified does not match configuration for this VRF\n");
- return CMD_WARNING;
+ "%% Import AUTO RT is not configured for this VRF\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- 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)) {
- ecommunity_free(&ecomdel);
+ if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_AUTO_RT_CFGD)) {
vty_out(vty,
- "%% RT specified does not match configuration for this VRF\n");
- return CMD_WARNING;
+ "%% Export AUTO RT is not configured for this VRF\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
- 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) {
- ecommunity_free(&ecomdel);
+ if (!CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_AUTO_RT_CFGD) &&
+ !CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_AUTO_RT_CFGD)) {
vty_out(vty,
- "%% RT specified does not match configuration for this VRF\n");
- return CMD_WARNING;
+ "%% Import/Export AUTO RT is not configured for this VRF\n");
+ return CMD_WARNING_CONFIG_FAILED;
}
}
- ecommunity_free(&ecomdel);
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_IMPORT)
+ bgp_evpn_unconfigure_import_auto_rt_for_vrf(bgp);
+
+ if (rt_type == RT_TYPE_BOTH || rt_type == RT_TYPE_EXPORT)
+ bgp_evpn_unconfigure_export_auto_rt_for_vrf(bgp);
+
return CMD_SUCCESS;
}
@@ -6421,31 +6611,62 @@ void bgp_config_write_evpn_info(struct vty *vty, struct bgp *bgp, afi_t afi,
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_RT_CFGD)) {
char *ecom_str;
struct listnode *node, *nnode;
- struct ecommunity *ecom;
+ struct vrf_route_target *l3rt;
for (ALL_LIST_ELEMENTS(bgp->vrf_import_rtl, node, nnode,
- ecom)) {
+ l3rt)) {
+
+ if (CHECK_FLAG(l3rt->flags, BGP_VRF_RT_AUTO))
+ continue;
+
ecom_str = ecommunity_ecom2str(
- ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
- vty_out(vty, " route-target import %s\n", ecom_str);
+ l3rt->ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+
+ if (CHECK_FLAG(l3rt->flags, BGP_VRF_RT_WILD)) {
+ char *vni_str = NULL;
+
+ vni_str = strchr(ecom_str, ':') + 1;
+
+ if (!vni_str)
+ continue; /* This should never happen */
+
+ vty_out(vty, " route-target import *:%s\n",
+ vni_str);
+
+ } else
+ vty_out(vty, " route-target import %s\n",
+ ecom_str);
+
XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
}
}
+ /* import route-target auto */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_IMPORT_AUTO_RT_CFGD))
+ vty_out(vty, " route-target import auto\n");
+
/* export route-target */
if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_RT_CFGD)) {
char *ecom_str;
struct listnode *node, *nnode;
- struct ecommunity *ecom;
+ struct vrf_route_target *l3rt;
for (ALL_LIST_ELEMENTS(bgp->vrf_export_rtl, node, nnode,
- ecom)) {
+ l3rt)) {
+
+ if (CHECK_FLAG(l3rt->flags, BGP_VRF_RT_AUTO))
+ continue;
+
ecom_str = ecommunity_ecom2str(
- ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
+ l3rt->ecom, ECOMMUNITY_FORMAT_ROUTE_MAP, 0);
vty_out(vty, " route-target export %s\n", ecom_str);
XFREE(MTYPE_ECOMMUNITY_STR, ecom_str);
}
}
+
+ /* export route-target auto */
+ if (CHECK_FLAG(bgp->vrf_flags, BGP_VRF_EXPORT_AUTO_RT_CFGD))
+ vty_out(vty, " route-target export auto\n");
}
void bgp_ethernetvpn_init(void)
@@ -6547,6 +6768,8 @@ void bgp_ethernetvpn_init(void)
install_element(BGP_NODE, &no_bgp_evpn_vrf_rd_without_val_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_vrf_rt_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_vrf_rt_cmd);
+ install_element(BGP_EVPN_NODE, &bgp_evpn_vrf_rt_auto_cmd);
+ install_element(BGP_EVPN_NODE, &no_bgp_evpn_vrf_rt_auto_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_ead_es_rt_cmd);
install_element(BGP_EVPN_NODE, &no_bgp_evpn_ead_es_rt_cmd);
install_element(BGP_EVPN_NODE, &bgp_evpn_ead_es_frag_evi_limit_cmd);