summaryrefslogtreecommitdiff
path: root/staticd/static_vty.c
diff options
context:
space:
mode:
Diffstat (limited to 'staticd/static_vty.c')
-rw-r--r--staticd/static_vty.c1195
1 files changed, 417 insertions, 778 deletions
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index 75bce82eef..ac18f6adf4 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -27,6 +27,10 @@
#include "table.h"
#include "srcdest_table.h"
#include "mpls.h"
+#include "northbound.h"
+#include "libfrr.h"
+#include "routing_nb.h"
+#include "northbound_cli.h"
#include "static_vrf.h"
#include "static_memory.h"
@@ -36,251 +40,43 @@
#ifndef VTYSH_EXTRACT_PL
#include "staticd/static_vty_clippy.c"
#endif
+#include "static_nb.h"
#define STATICD_STR "Static route daemon\n"
-static struct static_vrf *static_vty_get_unknown_vrf(struct vty *vty,
- const char *vrf_name)
+static int static_route_leak(struct vty *vty, const char *svrf,
+ const char *nh_svrf, afi_t afi, safi_t safi,
+ const char *negate, const char *dest_str,
+ const char *mask_str, const char *src_str,
+ const char *gate_str, const char *ifname,
+ const char *flag_str, const char *tag_str,
+ const char *distance_str, const char *label_str,
+ const char *table_str, bool onlink)
{
- struct static_vrf *svrf;
- struct vrf *vrf;
-
- svrf = static_vrf_lookup_by_name(vrf_name);
-
- if (svrf)
- return svrf;
-
- vrf = vrf_get(VRF_UNKNOWN, vrf_name);
- if (!vrf) {
- vty_out(vty, "%% Could not create vrf %s\n", vrf_name);
- return NULL;
- }
- svrf = vrf->info;
- if (!svrf) {
- vty_out(vty, "%% Could not create vrf-info %s\n",
- vrf_name);
- return NULL;
- }
- /* Mark as having FRR configuration */
- vrf_set_user_cfged(vrf);
-
- return svrf;
-}
-
-struct static_hold_route {
- char *vrf_name;
- char *nhvrf_name;
- afi_t afi;
- safi_t safi;
- char *dest_str;
- char *mask_str;
- char *src_str;
- char *gate_str;
- char *ifname;
- char *flag_str;
- char *tag_str;
- char *distance_str;
- char *label_str;
- char *table_str;
- bool onlink;
-
- /* processed & masked destination, used for config display */
- struct prefix dest;
-};
-
-static struct list *static_list;
-
-static int static_list_compare_helper(const char *s1, const char *s2)
-{
- /* extra (!s1 && !s2) to keep SA happy */
- if (s1 == s2 || (!s1 && !s2))
- return 0;
-
- if (!s1 && s2)
- return -1;
-
- if (s1 && !s2)
- return 1;
-
- return strcmp(s1, s2);
-}
-
-static void static_list_delete(struct static_hold_route *shr)
-{
- XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name);
- XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name);
- XFREE(MTYPE_STATIC_ROUTE, shr->dest_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->mask_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->src_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->gate_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->ifname);
- XFREE(MTYPE_STATIC_ROUTE, shr->flag_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->tag_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->distance_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->label_str);
- XFREE(MTYPE_STATIC_ROUTE, shr->table_str);
-
- XFREE(MTYPE_STATIC_ROUTE, shr);
-}
-
-static int static_list_compare(void *arg1, void *arg2)
-{
- struct static_hold_route *shr1 = arg1;
- struct static_hold_route *shr2 = arg2;
int ret;
-
- ret = strcmp(shr1->vrf_name, shr2->vrf_name);
- if (ret)
- return ret;
-
- ret = strcmp(shr1->nhvrf_name, shr2->nhvrf_name);
- if (ret)
- return ret;
-
- ret = shr1->afi - shr2->afi;
- if (ret)
- return ret;
-
- ret = shr1->safi - shr2->safi;
- if (ret)
- return ret;
-
- ret = prefix_cmp(&shr1->dest, &shr2->dest);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->src_str, shr2->src_str);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->gate_str, shr2->gate_str);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->ifname, shr2->ifname);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->flag_str, shr2->flag_str);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->tag_str, shr2->tag_str);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->distance_str,
- shr2->distance_str);
- if (ret)
- return ret;
-
- ret = static_list_compare_helper(shr1->table_str,
- shr2->table_str);
- if (ret)
- return ret;
-
- return static_list_compare_helper(shr1->label_str, shr2->label_str);
-}
-
-
-/* General function for static route. */
-static int zebra_static_route_holdem(
- struct static_vrf *svrf, struct static_vrf *nh_svrf, afi_t afi,
- safi_t safi, const char *negate, struct prefix *dest,
- const char *dest_str, const char *mask_str, const char *src_str,
- const char *gate_str, const char *ifname, const char *flag_str,
- const char *tag_str, const char *distance_str, const char *label_str,
- const char *table_str, bool onlink)
-{
- struct static_hold_route *shr, *lookup;
- struct listnode *node;
-
- zlog_warn("Static Route to %s not installed currently because dependent config not fully available",
- dest_str);
-
- shr = XCALLOC(MTYPE_STATIC_ROUTE, sizeof(*shr));
- shr->vrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, svrf->vrf->name);
- shr->nhvrf_name = XSTRDUP(MTYPE_STATIC_ROUTE, nh_svrf->vrf->name);
- shr->afi = afi;
- shr->safi = safi;
- shr->onlink = onlink;
- if (dest)
- prefix_copy(&shr->dest, dest);
- if (dest_str)
- shr->dest_str = XSTRDUP(MTYPE_STATIC_ROUTE, dest_str);
- if (mask_str)
- shr->mask_str = XSTRDUP(MTYPE_STATIC_ROUTE, mask_str);
- if (src_str)
- shr->src_str = XSTRDUP(MTYPE_STATIC_ROUTE, src_str);
- if (gate_str)
- shr->gate_str = XSTRDUP(MTYPE_STATIC_ROUTE, gate_str);
- if (ifname)
- shr->ifname = XSTRDUP(MTYPE_STATIC_ROUTE, ifname);
- if (flag_str)
- shr->flag_str = XSTRDUP(MTYPE_STATIC_ROUTE, flag_str);
- if (tag_str)
- shr->tag_str = XSTRDUP(MTYPE_STATIC_ROUTE, tag_str);
- if (distance_str)
- shr->distance_str = XSTRDUP(MTYPE_STATIC_ROUTE, distance_str);
- if (label_str)
- shr->label_str = XSTRDUP(MTYPE_STATIC_ROUTE, label_str);
- if (table_str)
- shr->table_str = XSTRDUP(MTYPE_STATIC_ROUTE, table_str);
-
- for (ALL_LIST_ELEMENTS_RO(static_list, node, lookup)) {
- if (static_list_compare(shr, lookup) == 0)
- break;
- }
-
- if (lookup) {
- if (negate) {
- listnode_delete(static_list, lookup);
- static_list_delete(shr);
- static_list_delete(lookup);
-
- return CMD_SUCCESS;
- }
-
- /*
- * If a person enters the same line again
- * we need to silently accept it
- */
- goto shr_cleanup;
- }
-
- if (!negate) {
- listnode_add_sort(static_list, shr);
- return CMD_SUCCESS;
- }
-
- shr_cleanup:
- XFREE(MTYPE_STATIC_ROUTE, shr->nhvrf_name);
- XFREE(MTYPE_STATIC_ROUTE, shr->vrf_name);
- XFREE(MTYPE_STATIC_ROUTE, shr);
-
- return CMD_SUCCESS;
-}
-
-static int static_route_leak(
- struct vty *vty, struct static_vrf *svrf, struct static_vrf *nh_svrf,
- afi_t afi, safi_t safi, const char *negate, const char *dest_str,
- const char *mask_str, const char *src_str, const char *gate_str,
- const char *ifname, const char *flag_str, const char *tag_str,
- const char *distance_str, const char *label_str, const char *table_str,
- bool onlink)
-{
- int ret;
- uint8_t distance;
struct prefix p, src;
- struct prefix_ipv6 *src_p = NULL;
- union g_addr gate;
- union g_addr *gatep = NULL;
struct in_addr mask;
- enum static_blackhole_type bh_type = 0;
- route_tag_t tag = 0;
uint8_t type;
- struct static_nh_label snh_label;
+ const char *bh_type;
+ char xpath_prefix[XPATH_MAXLEN];
+ char xpath_nexthop[XPATH_MAXLEN];
+ char xpath_mpls[XPATH_MAXLEN];
+ char xpath_label[XPATH_MAXLEN];
+ char ab_xpath[XPATH_MAXLEN];
+ char buf_prefix[PREFIX_STRLEN];
+ char buf_src_prefix[PREFIX_STRLEN];
+ char buf_nh_type[PREFIX_STRLEN];
+ char buf_tag[PREFIX_STRLEN];
+ char buf_tableid[PREFIX_STRLEN];
+ uint8_t label_stack_id = 0;
+ const char *buf_gate_str;
+ uint8_t distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
+ route_tag_t tag = 0;
uint32_t table_id = 0;
+ const struct lyd_node *dnode;
+
+ memset(buf_src_prefix, 0, PREFIX_STRLEN);
+ memset(buf_nh_type, 0, PREFIX_STRLEN);
ret = str2prefix(dest_str, &p);
if (ret <= 0) {
@@ -322,7 +118,6 @@ static int static_route_leak(
__func__, src_str);
return CMD_WARNING_CONFIG_FAILED;
}
- src_p = (struct prefix_ipv6 *)&src;
}
break;
default:
@@ -332,29 +127,29 @@ static int static_route_leak(
/* Apply mask for given prefix. */
apply_mask(&p);
- if (svrf->vrf->vrf_id == VRF_UNKNOWN
- || nh_svrf->vrf->vrf_id == VRF_UNKNOWN) {
- vrf_set_user_cfged(svrf->vrf);
- return zebra_static_route_holdem(
- svrf, nh_svrf, afi, safi, negate, &p, dest_str,
- mask_str, src_str, gate_str, ifname, flag_str, tag_str,
- distance_str, label_str, table_str, onlink);
- }
+ prefix2str(&p, buf_prefix, sizeof(buf_prefix));
- if (table_str) {
- /* table configured. check consistent with vrf config
- */
- if (svrf->vrf->data.l.table_id != RT_TABLE_MAIN) {
- if (vty)
- vty_out(vty,
- "%% Table %s overlaps vrf table %u\n",
- table_str, svrf->vrf->data.l.table_id);
- else
- zlog_warn("%s: Table %s overlaps vrf table %u",
- __func__, table_str,
- svrf->vrf->data.l.table_id);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (src_str)
+ prefix2str(&src, buf_src_prefix, sizeof(buf_src_prefix));
+ if (gate_str)
+ buf_gate_str = gate_str;
+ else
+ buf_gate_str = "";
+
+ if (gate_str == NULL && ifname == NULL)
+ type = STATIC_BLACKHOLE;
+ else if (gate_str && ifname) {
+ if (afi == AFI_IP)
+ type = STATIC_IPV4_GATEWAY_IFNAME;
+ else
+ type = STATIC_IPV6_GATEWAY_IFNAME;
+ } else if (ifname)
+ type = STATIC_IFNAME;
+ else {
+ if (afi == AFI_IP)
+ type = STATIC_IPV4_GATEWAY;
+ else
+ type = STATIC_IPV6_GATEWAY;
}
/* Administrative distance. */
@@ -367,169 +162,160 @@ static int static_route_leak(
if (tag_str)
tag = strtoul(tag_str, NULL, 10);
- /* Labels */
- memset(&snh_label, 0, sizeof(struct static_nh_label));
- if (label_str) {
- if (!mpls_enabled) {
- if (vty)
- vty_out(vty,
- "%% MPLS not turned on in kernel, ignoring command\n");
- else
- zlog_warn(
- "%s: MPLS not turned on in kernel ignoring static route to %s",
- __func__, dest_str);
- return CMD_WARNING_CONFIG_FAILED;
- }
- int rc = mpls_str2label(label_str, &snh_label.num_labels,
- snh_label.label);
- if (rc < 0) {
- switch (rc) {
- case -1:
- if (vty)
- vty_out(vty, "%% Malformed label(s)\n");
- else
- zlog_warn(
- "%s: Malformed labels specified for route %s",
- __func__, dest_str);
- break;
- case -2:
- if (vty)
- vty_out(vty,
- "%% Cannot use reserved label(s) (%d-%d)\n",
- MPLS_LABEL_RESERVED_MIN,
- MPLS_LABEL_RESERVED_MAX);
- else
- zlog_warn(
- "%s: Cannot use reserved labels (%d-%d) for %s",
- __func__,
- MPLS_LABEL_RESERVED_MIN,
- MPLS_LABEL_RESERVED_MAX,
- dest_str);
- break;
- case -3:
- if (vty)
- vty_out(vty,
- "%% Too many labels. Enter %d or fewer\n",
- MPLS_MAX_LABELS);
- else
- zlog_warn(
- "%s: Too many labels, Enter %d or fewer for %s",
- __func__, MPLS_MAX_LABELS,
- dest_str);
- break;
- }
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
/* TableID */
if (table_str)
table_id = atol(table_str);
- /* Null0 static route. */
- if (ifname != NULL) {
- if (strcasecmp(ifname, "Null0") == 0
- || strcasecmp(ifname, "reject") == 0
- || strcasecmp(ifname, "blackhole") == 0) {
- if (vty)
- vty_out(vty,
- "%% Nexthop interface name can not be from reserved keywords (Null0, reject, blackhole)\n");
- else
- zlog_warn(
- "%s: %s: Nexthop interface name can not be from reserved keywords (Null0, reject, blackhole)",
- __func__, dest_str);
- return CMD_WARNING_CONFIG_FAILED;
- }
- }
-
- /* Route flags */
- if (flag_str) {
- switch (flag_str[0]) {
- case 'r':
- bh_type = STATIC_BLACKHOLE_REJECT;
- break;
- case 'b':
- bh_type = STATIC_BLACKHOLE_DROP;
- break;
- case 'N':
- bh_type = STATIC_BLACKHOLE_NULL;
- break;
- default:
- if (vty)
- vty_out(vty, "%% Malformed flag %s \n",
- flag_str);
- else
- zlog_warn("%s: Malformed flag %s for %s",
- __func__, flag_str, dest_str);
- return CMD_WARNING_CONFIG_FAILED;
+ static_get_nh_type(type, buf_nh_type, PREFIX_STRLEN);
+ if (!negate) {
+ /* route + path procesing */
+ if (src_str)
+ snprintf(xpath_prefix, sizeof(xpath_prefix),
+ FRR_S_ROUTE_SRC_INFO_KEY_XPATH,
+ "frr-staticd:staticd", "staticd", svrf,
+ buf_prefix,
+ yang_afi_safi_value2identity(afi, safi),
+ buf_src_prefix, distance);
+ else
+ snprintf(xpath_prefix, sizeof(xpath_prefix),
+ FRR_STATIC_ROUTE_INFO_KEY_XPATH,
+ "frr-staticd:staticd", "staticd", svrf,
+ buf_prefix,
+ yang_afi_safi_value2identity(afi, safi),
+ distance);
+
+ nb_cli_enqueue_change(vty, xpath_prefix, NB_OP_CREATE, NULL);
+
+ /* Tag processing */
+ snprintf(buf_tag, sizeof(buf_tag), "%u", tag);
+ strlcpy(ab_xpath, xpath_prefix, sizeof(ab_xpath));
+ strlcat(ab_xpath, FRR_STATIC_ROUTE_PATH_TAG_XPATH,
+ sizeof(ab_xpath));
+ nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tag);
+
+ /* Table-Id processing */
+ snprintf(buf_tableid, sizeof(buf_tableid), "%u", table_id);
+ strlcpy(ab_xpath, xpath_prefix, sizeof(ab_xpath));
+ strlcat(ab_xpath, FRR_STATIC_ROUTE_PATH_TABLEID_XPATH,
+ sizeof(ab_xpath));
+ nb_cli_enqueue_change(vty, ab_xpath, NB_OP_MODIFY, buf_tableid);
+ /* nexthop processing */
+
+ snprintf(ab_xpath, sizeof(ab_xpath),
+ FRR_STATIC_ROUTE_NH_KEY_XPATH, buf_nh_type, nh_svrf,
+ buf_gate_str, ifname);
+ strlcpy(xpath_nexthop, xpath_prefix, sizeof(xpath_nexthop));
+ strlcat(xpath_nexthop, ab_xpath, sizeof(xpath_nexthop));
+ nb_cli_enqueue_change(vty, xpath_nexthop, NB_OP_CREATE, NULL);
+
+ if (type == STATIC_BLACKHOLE) {
+ strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
+ strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_BH_XPATH,
+ sizeof(ab_xpath));
+
+ /* Route flags */
+ if (flag_str) {
+ switch (flag_str[0]) {
+ case 'r':
+ bh_type = "reject";
+ break;
+ case 'b':
+ bh_type = "unspec";
+ break;
+ case 'N':
+ bh_type = "null";
+ break;
+ default:
+ bh_type = NULL;
+ break;
+ }
+ nb_cli_enqueue_change(vty, ab_xpath,
+ NB_OP_MODIFY, bh_type);
+ } else {
+ nb_cli_enqueue_change(vty, ab_xpath,
+ NB_OP_MODIFY, "null");
+ }
}
- }
-
- if (gate_str) {
- if (inet_pton(afi2family(afi), gate_str, &gate) != 1) {
- if (vty)
- vty_out(vty,
- "%% Malformed nexthop address %s\n",
- gate_str);
+ if (type == STATIC_IPV4_GATEWAY_IFNAME
+ || type == STATIC_IPV6_GATEWAY_IFNAME) {
+ strlcpy(ab_xpath, xpath_nexthop, sizeof(ab_xpath));
+ strlcat(ab_xpath, FRR_STATIC_ROUTE_NH_ONLINK_XPATH,
+ sizeof(ab_xpath));
+
+ if (onlink)
+ nb_cli_enqueue_change(vty, ab_xpath,
+ NB_OP_MODIFY, "true");
else
- zlog_warn(
- "%s: Malformed nexthop address %s for %s",
- __func__, gate_str, dest_str);
- return CMD_WARNING_CONFIG_FAILED;
+ nb_cli_enqueue_change(vty, ab_xpath,
+ NB_OP_MODIFY, "false");
}
- gatep = &gate;
-
- if (afi == AFI_IP && !negate) {
- if (if_lookup_exact_address(&gatep->ipv4, AF_INET,
- svrf->vrf->vrf_id))
- if (vty)
- vty_out(vty,
- "%% Warning!! Local connected address is configured as Gateway IP(%s)\n",
- gate_str);
- } else if (afi == AFI_IP6 && !negate) {
- if (if_lookup_exact_address(&gatep->ipv6, AF_INET6,
- svrf->vrf->vrf_id))
- if (vty)
- vty_out(vty,
- "%% Warning!! Local connected address is configured as Gateway IPv6(%s)\n",
- gate_str);
+ if (label_str) {
+ /* copy of label string (start) */
+ char *ostr;
+ /* pointer to next segment */
+ char *nump;
+
+ strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls));
+ strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH,
+ sizeof(xpath_mpls));
+
+ nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
+ NULL);
+
+ ostr = XSTRDUP(MTYPE_TMP, label_str);
+ while ((nump = strsep(&ostr, "/")) != NULL) {
+ snprintf(ab_xpath, sizeof(ab_xpath),
+ FRR_STATIC_ROUTE_NHLB_KEY_XPATH,
+ label_stack_id);
+ strlcpy(xpath_label, xpath_mpls,
+ sizeof(xpath_label));
+ strlcat(xpath_label, ab_xpath,
+ sizeof(xpath_label));
+ nb_cli_enqueue_change(vty, xpath_label,
+ NB_OP_MODIFY, nump);
+ label_stack_id++;
+ }
+ XFREE(MTYPE_TMP, ostr);
+ } else {
+ strlcpy(xpath_mpls, xpath_nexthop, sizeof(xpath_mpls));
+ strlcat(xpath_mpls, FRR_STATIC_ROUTE_NH_LABEL_XPATH,
+ sizeof(xpath_mpls));
+ nb_cli_enqueue_change(vty, xpath_mpls, NB_OP_DESTROY,
+ NULL);
}
-
- }
-
- if (gate_str == NULL && ifname == NULL)
- type = STATIC_BLACKHOLE;
- else if (gate_str && ifname) {
- if (afi == AFI_IP)
- type = STATIC_IPV4_GATEWAY_IFNAME;
- else
- type = STATIC_IPV6_GATEWAY_IFNAME;
- } else if (ifname)
- type = STATIC_IFNAME;
- else {
- if (afi == AFI_IP)
- type = STATIC_IPV4_GATEWAY;
- else
- type = STATIC_IPV6_GATEWAY;
- }
-
- if (!negate) {
- static_add_route(afi, safi, type, &p, src_p, gatep, ifname,
- bh_type, tag, distance, svrf, nh_svrf,
- &snh_label, table_id, onlink);
- /* Mark as having FRR configuration */
- vrf_set_user_cfged(svrf->vrf);
+ ret = nb_cli_apply_changes(vty, xpath_prefix);
} else {
- static_delete_route(afi, safi, type, &p, src_p, gatep, ifname,
- tag, distance, svrf, &snh_label, table_id);
- /* If no other FRR config for this VRF, mark accordingly. */
- if (!static_vrf_has_config(svrf))
- vrf_reset_user_cfged(svrf->vrf);
+ if (src_str)
+ snprintf(ab_xpath, sizeof(ab_xpath),
+ FRR_DEL_S_ROUTE_SRC_NH_KEY_XPATH,
+ "frr-staticd:staticd", "staticd", svrf,
+ buf_prefix,
+ yang_afi_safi_value2identity(afi, safi),
+ buf_src_prefix, distance, buf_nh_type, nh_svrf,
+ buf_gate_str, ifname);
+ else
+ snprintf(ab_xpath, sizeof(ab_xpath),
+ FRR_DEL_S_ROUTE_NH_KEY_XPATH,
+ "frr-staticd:staticd", "staticd", svrf,
+ buf_prefix,
+ yang_afi_safi_value2identity(afi, safi),
+ distance, buf_nh_type, nh_svrf, buf_gate_str,
+ ifname);
+
+ dnode = yang_dnode_get(vty->candidate_config->dnode, ab_xpath);
+ if (!dnode)
+ return ret;
+
+ dnode = yang_get_subtree_with_no_sibling(dnode);
+ assert(dnode);
+ yang_dnode_get_path(dnode, ab_xpath, XPATH_MAXLEN);
+
+ nb_cli_enqueue_change(vty, ab_xpath, NB_OP_DESTROY, NULL);
+ ret = nb_cli_apply_changes(vty, ab_xpath);
}
- return CMD_SUCCESS;
+ return ret;
}
-
static int static_route(struct vty *vty, afi_t afi, safi_t safi,
const char *negate, const char *dest_str,
const char *mask_str, const char *src_str,
@@ -538,77 +324,28 @@ static int static_route(struct vty *vty, afi_t afi, safi_t safi,
const char *distance_str, const char *vrf_name,
const char *label_str, const char *table_str)
{
- struct static_vrf *svrf;
-
- /* VRF id */
- svrf = static_vrf_lookup_by_name(vrf_name);
-
- /* When trying to delete, the VRF must exist. */
- if (negate && !svrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf_name);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!vrf_name)
+ vrf_name = VRF_DEFAULT_NAME;
- /* When trying to create, create the VRF if it doesn't exist.
- * Note: The VRF isn't active until we hear about it from the kernel.
- */
- if (!svrf) {
- svrf = static_vty_get_unknown_vrf(vty, vrf_name);
- if (!svrf)
- return CMD_WARNING_CONFIG_FAILED;
- }
- return static_route_leak(vty, svrf, svrf, afi, safi, negate, dest_str,
- mask_str, src_str, gate_str, ifname, flag_str,
- tag_str, distance_str, label_str, table_str,
- false);
-}
-
-void static_config_install_delayed_routes(struct static_vrf *svrf)
-{
- struct listnode *node, *nnode;
- struct static_hold_route *shr;
- struct static_vrf *osvrf, *nh_svrf;
- int installed;
-
- for (ALL_LIST_ELEMENTS(static_list, node, nnode, shr)) {
- osvrf = static_vrf_lookup_by_name(shr->vrf_name);
- nh_svrf = static_vrf_lookup_by_name(shr->nhvrf_name);
-
- if (osvrf != svrf && nh_svrf != svrf)
- continue;
-
- if (osvrf->vrf->vrf_id == VRF_UNKNOWN
- || nh_svrf->vrf->vrf_id == VRF_UNKNOWN)
- continue;
-
- installed = static_route_leak(
- NULL, osvrf, nh_svrf, shr->afi, shr->safi, NULL,
- shr->dest_str, shr->mask_str, shr->src_str,
- shr->gate_str, shr->ifname, shr->flag_str, shr->tag_str,
- shr->distance_str, shr->label_str, shr->table_str,
- shr->onlink);
-
- if (installed != CMD_SUCCESS)
- zlog_debug(
- "%s: Attempt to install %s as a route and it was rejected",
- __func__, shr->dest_str);
- listnode_delete(static_list, shr);
- static_list_delete(shr);
- }
+ return static_route_leak(vty, vrf_name, vrf_name, afi, safi, negate,
+ dest_str, mask_str, src_str, gate_str, ifname,
+ flag_str, tag_str, distance_str, label_str,
+ table_str, false);
}
/* Write static route configuration. */
int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi,
safi_t safi, const char *cmd)
{
- struct static_hold_route *shr;
- struct listnode *node;
char spacing[100];
struct route_node *rn;
- struct static_route *si;
+ struct static_nexthop *nh;
+ struct static_path *pn;
struct route_table *stable;
+ struct static_route_info *si;
char buf[SRCDEST2STR_BUFFER];
int write = 0;
+ struct stable_info *info;
stable = svrf->stable[afi][safi];
if (stable == NULL)
@@ -617,125 +354,104 @@ int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi,
snprintf(spacing, sizeof(spacing), "%s%s",
(svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", cmd);
- /*
- * Static routes for vrfs not fully inited
- */
- for (ALL_LIST_ELEMENTS_RO(static_list, node, shr)) {
- if (shr->afi != afi || shr->safi != safi)
+ for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
+ si = static_route_info_from_rnode(rn);
+ if (!si)
continue;
-
- if (strcmp(svrf->vrf->name, shr->vrf_name) != 0)
- continue;
-
- char dest_str[PREFIX_STRLEN];
-
- prefix2str(&shr->dest, dest_str, sizeof(dest_str));
-
- vty_out(vty, "%s ", spacing);
- if (shr->dest_str)
- vty_out(vty, "%s ", dest_str);
- if (shr->src_str)
- vty_out(vty, "from %s ", shr->src_str);
- if (shr->gate_str)
- vty_out(vty, "%s ", shr->gate_str);
- if (shr->ifname)
- vty_out(vty, "%s ", shr->ifname);
- if (shr->flag_str)
- vty_out(vty, "%s ", shr->flag_str);
- if (shr->tag_str)
- vty_out(vty, "tag %s ", shr->tag_str);
- if (shr->distance_str)
- vty_out(vty, "%s ", shr->distance_str);
- if (shr->label_str)
- vty_out(vty, "label %s ", shr->label_str);
- if (shr->table_str)
- vty_out(vty, "table %s", shr->table_str);
- if (strcmp(shr->vrf_name, shr->nhvrf_name) != 0)
- vty_out(vty, "nexthop-vrf %s ", shr->nhvrf_name);
- if (shr->onlink)
- vty_out(vty, "onlink");
- vty_out(vty, "\n");
- }
-
- for (rn = route_top(stable); rn; rn = srcdest_route_next(rn))
- for (si = rn->info; si; si = si->next) {
- vty_out(vty, "%s %s", spacing,
- srcdest_rnode2str(rn, buf, sizeof(buf)));
-
- switch (si->type) {
- case STATIC_IPV4_GATEWAY:
- vty_out(vty, " %s", inet_ntoa(si->addr.ipv4));
- break;
- case STATIC_IPV6_GATEWAY:
- vty_out(vty, " %s",
- inet_ntop(AF_INET6, &si->addr.ipv6, buf,
- sizeof(buf)));
- break;
- case STATIC_IFNAME:
- vty_out(vty, " %s", si->ifname);
- break;
- case STATIC_BLACKHOLE:
- switch (si->bh_type) {
- case STATIC_BLACKHOLE_DROP:
- vty_out(vty, " blackhole");
+ info = static_get_stable_info(rn);
+ frr_each(static_path_list, &si->path_list, pn) {
+ frr_each(static_nexthop_list, &pn->nexthop_list, nh) {
+ vty_out(vty, "%s %s", spacing,
+ srcdest_rnode2str(rn, buf,
+ sizeof(buf)));
+
+ switch (nh->type) {
+ case STATIC_IPV4_GATEWAY:
+ vty_out(vty, " %s",
+ inet_ntoa(nh->addr.ipv4));
break;
- case STATIC_BLACKHOLE_NULL:
- vty_out(vty, " Null0");
+ case STATIC_IPV6_GATEWAY:
+ vty_out(vty, " %s",
+ inet_ntop(AF_INET6,
+ &nh->addr.ipv6, buf,
+ sizeof(buf)));
break;
- case STATIC_BLACKHOLE_REJECT:
- vty_out(vty, " reject");
+ case STATIC_IFNAME:
+ vty_out(vty, " %s", nh->ifname);
+ break;
+ case STATIC_BLACKHOLE:
+ switch (nh->bh_type) {
+ case STATIC_BLACKHOLE_DROP:
+ vty_out(vty, " blackhole");
+ break;
+ case STATIC_BLACKHOLE_NULL:
+ vty_out(vty, " Null0");
+ break;
+ case STATIC_BLACKHOLE_REJECT:
+ vty_out(vty, " reject");
+ break;
+ }
+ break;
+ case STATIC_IPV4_GATEWAY_IFNAME:
+ vty_out(vty, " %s %s",
+ inet_ntop(AF_INET,
+ &nh->addr.ipv4, buf,
+ sizeof(buf)),
+ nh->ifname);
+ break;
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ vty_out(vty, " %s %s",
+ inet_ntop(AF_INET6,
+ &nh->addr.ipv6, buf,
+ sizeof(buf)),
+ nh->ifname);
break;
}
- break;
- case STATIC_IPV4_GATEWAY_IFNAME:
- vty_out(vty, " %s %s",
- inet_ntop(AF_INET, &si->addr.ipv4, buf,
- sizeof(buf)),
- si->ifname);
- break;
- case STATIC_IPV6_GATEWAY_IFNAME:
- vty_out(vty, " %s %s",
- inet_ntop(AF_INET6, &si->addr.ipv6, buf,
- sizeof(buf)),
- si->ifname);
- break;
- }
- if (si->tag)
- vty_out(vty, " tag %" ROUTE_TAG_PRI, si->tag);
-
- if (si->distance != ZEBRA_STATIC_DISTANCE_DEFAULT)
- vty_out(vty, " %d", si->distance);
-
- /* Label information */
- if (si->snh_label.num_labels)
- vty_out(vty, " label %s",
- mpls_label2str(si->snh_label.num_labels,
- si->snh_label.label, buf,
- sizeof(buf), 0));
-
- if (si->nh_vrf_id != si->vrf_id)
- vty_out(vty, " nexthop-vrf %s", si->nh_vrfname);
-
- /*
- * table ID from VRF overrides configured
- */
- if (si->table_id &&
- svrf->vrf->data.l.table_id == RT_TABLE_MAIN)
- vty_out(vty, " table %u", si->table_id);
-
- if (si->onlink)
- vty_out(vty, " onlink");
-
- vty_out(vty, "\n");
-
- write = 1;
+ if (pn->tag)
+ vty_out(vty, " tag %" ROUTE_TAG_PRI,
+ pn->tag);
+
+ if (pn->distance
+ != ZEBRA_STATIC_DISTANCE_DEFAULT)
+ vty_out(vty, " %u", pn->distance);
+
+ /* Label information */
+ if (nh->snh_label.num_labels)
+ vty_out(vty, " label %s",
+ mpls_label2str(
+ nh->snh_label
+ .num_labels,
+ nh->snh_label.label,
+ buf, sizeof(buf), 0));
+
+ if (nh->nh_vrf_id != GET_STABLE_VRF_ID(info))
+ vty_out(vty, " nexthop-vrf %s",
+ nh->nh_vrfname);
+
+ /*
+ * table ID from VRF overrides
+ * configured
+ */
+ if (pn->table_id
+ && svrf->vrf->data.l.table_id
+ == RT_TABLE_MAIN)
+ vty_out(vty, " table %u", pn->table_id);
+
+ if (nh->onlink)
+ vty_out(vty, " onlink");
+
+ vty_out(vty, "\n");
+
+ write = 1;
+ }
}
+ }
return write;
}
/* Static unicast routes for multicast RPF lookup. */
-DEFPY (ip_mroute_dist,
+DEFPY_YANG (ip_mroute_dist,
ip_mroute_dist_cmd,
"[no] ip mroute A.B.C.D/M$prefix <A.B.C.D$gate|INTERFACE$ifname> [(1-255)$distance]",
NO_STR
@@ -752,7 +468,7 @@ DEFPY (ip_mroute_dist,
}
/* Static route configuration. */
-DEFPY(ip_route_blackhole,
+DEFPY_YANG(ip_route_blackhole,
ip_route_blackhole_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
@@ -790,7 +506,7 @@ DEFPY(ip_route_blackhole,
distance_str, vrf, label, table_str);
}
-DEFPY(ip_route_blackhole_vrf,
+DEFPY_YANG(ip_route_blackhole_vrf,
ip_route_blackhole_vrf_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
@@ -815,28 +531,29 @@ DEFPY(ip_route_blackhole_vrf,
"Table to configure\n"
"The table number to configure\n")
{
- VTY_DECLVAR_CONTEXT(vrf, vrf);
- struct static_vrf *svrf = vrf->info;
+ const struct lyd_node *vrf_dnode;
+ const char *vrfname;
- if (table_str && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
+ vrf_dnode =
+ yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!vrf_dnode) {
+ vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
-
+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
/*
* Coverity is complaining that prefix could
* be dereferenced, but we know that prefix will
* valid. Add an assert to make it happy
*/
assert(prefix);
- return static_route_leak(vty, svrf, svrf, AFI_IP, SAFI_UNICAST, no,
- prefix, mask_str, NULL, NULL, NULL, flag,
+ return static_route_leak(vty, vrfname, vrfname, AFI_IP, SAFI_UNICAST,
+ no, prefix, mask_str, NULL, NULL, NULL, flag,
tag_str, distance_str, label, table_str,
false);
}
-DEFPY(ip_route_address_interface,
+DEFPY_YANG(ip_route_address_interface,
ip_route_address_interface_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
@@ -869,44 +586,28 @@ DEFPY(ip_route_address_interface,
VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface\n")
{
- struct static_vrf *svrf;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
-
- svrf = static_vty_get_unknown_vrf(vty, vrf);
- if (!svrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- if (table_str && vrf && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!vrf)
+ vrf = VRF_DEFAULT_NAME;
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
+ nh_vrf = vrf;
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return static_route_leak(vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no,
+ return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no,
prefix, mask_str, NULL, gate_str, ifname, flag,
tag_str, distance_str, label, table_str,
!!onlink);
}
-DEFPY(ip_route_address_interface_vrf,
+DEFPY_YANG(ip_route_address_interface_vrf,
ip_route_address_interface_vrf_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
@@ -937,39 +638,35 @@ DEFPY(ip_route_address_interface_vrf,
VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface\n")
{
- VTY_DECLVAR_CONTEXT(vrf, vrf);
+ const char *nh_vrf;
const char *flag = NULL;
- struct static_vrf *svrf = vrf->info;
- struct static_vrf *nh_svrf;
+ const struct lyd_node *vrf_dnode;
+ const char *vrfname;
- if (table_str && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
+ vrf_dnode =
+ yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!vrf_dnode) {
+ vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
-
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
-
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ nh_vrf = vrfname;
- return static_route_leak(vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no,
+ return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no,
prefix, mask_str, NULL, gate_str, ifname, flag,
tag_str, distance_str, label, table_str,
!!onlink);
}
-DEFPY(ip_route,
+DEFPY_YANG(ip_route,
ip_route_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
@@ -999,44 +696,29 @@ DEFPY(ip_route,
"The table number to configure\n"
VRF_CMD_HELP_STR)
{
- struct static_vrf *svrf;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
- if (table_str && vrf && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
- svrf = static_vty_get_unknown_vrf(vty, vrf);
- if (!svrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!vrf)
+ vrf = VRF_DEFAULT_NAME;
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
+ nh_vrf = vrf;
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str, false);
+ return static_route_leak(vty, vrf, nh_vrf, AFI_IP, SAFI_UNICAST, no,
+ prefix, mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label, table_str,
+ false);
}
-DEFPY(ip_route_vrf,
+DEFPY_YANG(ip_route_vrf,
ip_route_vrf_cmd,
"[no] ip route\
<A.B.C.D/M$prefix|A.B.C.D$prefix A.B.C.D$mask> \
@@ -1064,39 +746,36 @@ DEFPY(ip_route_vrf,
"The table number to configure\n"
VRF_CMD_HELP_STR)
{
- VTY_DECLVAR_CONTEXT(vrf, vrf);
- struct static_vrf *svrf = vrf->info;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
+ const struct lyd_node *vrf_dnode;
+ const char *vrfname;
- if (table_str && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
+ vrf_dnode =
+ yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!vrf_dnode) {
+ vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
+
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
-
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
-
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ nh_vrf = vrfname;
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP, SAFI_UNICAST, no, prefix, mask_str,
- NULL, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str, false);
+ return static_route_leak(vty, vrfname, nh_vrf, AFI_IP, SAFI_UNICAST, no,
+ prefix, mask_str, NULL, gate_str, ifname, flag,
+ tag_str, distance_str, label, table_str,
+ false);
}
-DEFPY(ipv6_route_blackhole,
+DEFPY_YANG(ipv6_route_blackhole,
ipv6_route_blackhole_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
<reject|blackhole>$flag \
@@ -1134,7 +813,7 @@ DEFPY(ipv6_route_blackhole,
distance_str, vrf, label, table_str);
}
-DEFPY(ipv6_route_blackhole_vrf,
+DEFPY_YANG(ipv6_route_blackhole_vrf,
ipv6_route_blackhole_vrf_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
<reject|blackhole>$flag \
@@ -1159,14 +838,16 @@ DEFPY(ipv6_route_blackhole_vrf,
"Table to configure\n"
"The table number to configure\n")
{
- VTY_DECLVAR_CONTEXT(vrf, vrf);
- struct static_vrf *svrf = vrf->info;
+ const struct lyd_node *vrf_dnode;
+ const char *vrfname;
- if (table_str && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
+ vrf_dnode =
+ yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!vrf_dnode) {
+ vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
/*
* Coverity is complaining that prefix could
@@ -1174,13 +855,14 @@ DEFPY(ipv6_route_blackhole_vrf,
* valid. Add an assert to make it happy
*/
assert(prefix);
- return static_route_leak(
- vty, svrf, svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, NULL, NULL, flag, tag_str, distance_str, label,
- table_str, false);
+
+ return static_route_leak(vty, vrfname, vrfname, AFI_IP6, SAFI_UNICAST,
+ no, prefix_str, NULL, from_str, NULL, NULL,
+ flag, tag_str, distance_str, label, table_str,
+ false);
}
-DEFPY(ipv6_route_address_interface,
+DEFPY_YANG(ipv6_route_address_interface,
ipv6_route_address_interface_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
X:X::X:X$gate \
@@ -1213,44 +895,29 @@ DEFPY(ipv6_route_address_interface,
VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface\n")
{
- struct static_vrf *svrf;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
- if (table_str && vrf && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
- return CMD_WARNING_CONFIG_FAILED;
+ if (ifname && !strncasecmp(ifname, "Null0", 5)) {
+ flag = "Null0";
+ ifname = NULL;
}
- svrf = static_vty_get_unknown_vrf(vty, vrf);
- if (!svrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!vrf)
+ vrf = VRF_DEFAULT_NAME;
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
-
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ nh_vrf = vrf;
- if (ifname && !strncasecmp(ifname, "Null0", 5)) {
- flag = "Null0";
- ifname = NULL;
- }
-
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str, !!onlink);
+ return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no,
+ prefix_str, NULL, from_str, gate_str, ifname,
+ flag, tag_str, distance_str, label, table_str,
+ !!onlink);
}
-DEFPY(ipv6_route_address_interface_vrf,
+DEFPY_YANG(ipv6_route_address_interface_vrf,
ipv6_route_address_interface_vrf_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
X:X::X:X$gate \
@@ -1281,39 +948,35 @@ DEFPY(ipv6_route_address_interface_vrf,
VRF_CMD_HELP_STR
"Treat the nexthop as directly attached to the interface\n")
{
- VTY_DECLVAR_CONTEXT(vrf, vrf);
- struct static_vrf *svrf = vrf->info;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
+ const struct lyd_node *vrf_dnode;
+ const char *vrfname;
- if (table_str && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
+ vrf_dnode =
+ yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!vrf_dnode) {
+ vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
-
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ nh_vrf = vrfname;
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
-
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str, !!onlink);
+ return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST,
+ no, prefix_str, NULL, from_str, gate_str,
+ ifname, flag, tag_str, distance_str, label,
+ table_str, !!onlink);
}
-DEFPY(ipv6_route,
+DEFPY_YANG(ipv6_route,
ipv6_route_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
<X:X::X:X$gate|<INTERFACE|Null0>$ifname> \
@@ -1343,44 +1006,28 @@ DEFPY(ipv6_route,
"The table number to configure\n"
VRF_CMD_HELP_STR)
{
- struct static_vrf *svrf;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
- if (table_str && vrf && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- svrf = static_vty_get_unknown_vrf(vty, vrf);
- if (!svrf) {
- vty_out(vty, "%% vrf %s is not defined\n", vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ if (!vrf)
+ vrf = VRF_DEFAULT_NAME;
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
-
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ nh_vrf = vrf;
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
-
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str, false);
+ return static_route_leak(vty, vrf, nh_vrf, AFI_IP6, SAFI_UNICAST, no,
+ prefix_str, NULL, from_str, gate_str, ifname,
+ flag, tag_str, distance_str, label, table_str,
+ false);
}
-DEFPY(ipv6_route_vrf,
+DEFPY_YANG(ipv6_route_vrf,
ipv6_route_vrf_cmd,
"[no] ipv6 route X:X::X:X/M$prefix [from X:X::X:X/M] \
<X:X::X:X$gate|<INTERFACE|Null0>$ifname> \
@@ -1408,38 +1055,34 @@ DEFPY(ipv6_route_vrf,
"The table number to configure\n"
VRF_CMD_HELP_STR)
{
- VTY_DECLVAR_CONTEXT(vrf, vrf);
- struct static_vrf *svrf = vrf->info;
- struct static_vrf *nh_svrf;
+ const char *nh_vrf;
const char *flag = NULL;
+ const struct lyd_node *vrf_dnode;
+ const char *vrfname;
- if (table_str && !vrf_is_backend_netns()) {
- vty_out(vty,
- "%% table param only available when running on netns-based vrfs\n");
+ vrf_dnode =
+ yang_dnode_get(vty->candidate_config->dnode, VTY_CURR_XPATH);
+ if (!vrf_dnode) {
+ vty_out(vty, "%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}
+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
if (nexthop_vrf)
- nh_svrf = static_vty_get_unknown_vrf(vty, nexthop_vrf);
+ nh_vrf = nexthop_vrf;
else
- nh_svrf = svrf;
-
- if (!nh_svrf) {
- vty_out(vty, "%% nexthop vrf %s is not defined\n", nexthop_vrf);
- return CMD_WARNING_CONFIG_FAILED;
- }
+ nh_vrf = vrfname;
if (ifname && !strncasecmp(ifname, "Null0", 5)) {
flag = "Null0";
ifname = NULL;
}
-
- return static_route_leak(
- vty, svrf, nh_svrf, AFI_IP6, SAFI_UNICAST, no, prefix_str, NULL,
- from_str, gate_str, ifname, flag, tag_str, distance_str, label,
- table_str, false);
+ return static_route_leak(vty, vrfname, nh_vrf, AFI_IP6, SAFI_UNICAST,
+ no, prefix_str, NULL, from_str, gate_str,
+ ifname, flag, tag_str, distance_str, label,
+ table_str, false);
}
-DEFPY(debug_staticd,
+DEFPY_YANG(debug_staticd,
debug_staticd_cmd,
"[no] debug static [{events$events}]",
NO_STR
@@ -1500,8 +1143,4 @@ void static_vty_init(void)
install_element(VIEW_NODE, &show_debugging_static_cmd);
install_element(VIEW_NODE, &debug_staticd_cmd);
install_element(CONFIG_NODE, &debug_staticd_cmd);
-
- static_list = list_new();
- static_list->cmp = (int (*)(void *, void *))static_list_compare;
- static_list->del = (void (*)(void *))static_list_delete;
}