summaryrefslogtreecommitdiffstats
path: root/staticd
diff options
context:
space:
mode:
authorIgor Ryzhov <iryzhov@nfware.com>2021-08-16 19:01:48 +0200
committerIgor Ryzhov <iryzhov@nfware.com>2021-08-31 16:59:44 +0200
commit6cc73dad918984fc940369523a5a3c61538f0fdf (patch)
tree2defd669b49669469daf6e912c1a9a2dc3421be4 /staticd
parentstaticd: convert typedef to enum (diff)
downloadfrr-6cc73dad918984fc940369523a5a3c61538f0fdf.tar.xz
frr-6cc73dad918984fc940369523a5a3c61538f0fdf.zip
staticd: output config using NB callbacks instead of operational data
Signed-off-by: Igor Ryzhov <iryzhov@nfware.com>
Diffstat (limited to 'staticd')
-rw-r--r--staticd/static_nb.c17
-rw-r--r--staticd/static_vrf.c24
-rw-r--r--staticd/static_vty.c395
-rw-r--r--staticd/static_vty.h13
4 files changed, 307 insertions, 142 deletions
diff --git a/staticd/static_nb.c b/staticd/static_nb.c
index c1a6253a1..5935364d5 100644
--- a/staticd/static_nb.c
+++ b/staticd/static_nb.c
@@ -21,7 +21,7 @@
#include "northbound.h"
#include "libfrr.h"
#include "static_nb.h"
-
+#include "static_vty.h"
/* clang-format off */
@@ -29,10 +29,18 @@ const struct frr_yang_module_info frr_staticd_info = {
.name = "frr-staticd",
.nodes = {
{
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd",
+ .cbs = {
+ .cli_show = static_cli_show,
+ .cli_show_end = static_cli_show_end,
+ }
+ },
+ {
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list",
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy,
+ .cli_cmp = static_route_list_cli_cmp,
}
},
{
@@ -40,6 +48,7 @@ const struct frr_yang_module_info frr_staticd_info = {
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_destroy,
+ .cli_cmp = static_path_list_cli_cmp,
}
},
{
@@ -55,6 +64,8 @@ const struct frr_yang_module_info frr_staticd_info = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_destroy,
.pre_validate = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate,
+ .cli_show = static_nexthop_cli_show,
+ .cli_cmp = static_nexthop_cli_cmp,
}
},
{
@@ -110,6 +121,7 @@ const struct frr_yang_module_info frr_staticd_info = {
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_destroy,
+ .cli_cmp = static_src_list_cli_cmp,
}
},
{
@@ -117,6 +129,7 @@ const struct frr_yang_module_info frr_staticd_info = {
.cbs = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_destroy,
+ .cli_cmp = static_path_list_cli_cmp,
}
},
{
@@ -132,6 +145,8 @@ const struct frr_yang_module_info frr_staticd_info = {
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_create,
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_frr_nexthops_nexthop_destroy,
.pre_validate = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_frr_nexthops_nexthop_pre_validate,
+ .cli_show = static_src_nexthop_cli_show,
+ .cli_cmp = static_nexthop_cli_cmp,
}
},
{
diff --git a/staticd/static_vrf.c b/staticd/static_vrf.c
index 740d90469..4bea3075c 100644
--- a/staticd/static_vrf.c
+++ b/staticd/static_vrf.c
@@ -23,11 +23,11 @@
#include "nexthop.h"
#include "table.h"
#include "srcdest_table.h"
+#include "northbound_cli.h"
#include "static_vrf.h"
#include "static_routes.h"
#include "static_zebra.h"
-#include "static_vty.h"
DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info");
@@ -150,24 +150,16 @@ struct static_vrf *static_vrf_lookup_by_name(const char *name)
static int static_vrf_config_write(struct vty *vty)
{
- struct vrf *vrf;
-
- RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
- if (vrf->vrf_id != VRF_DEFAULT)
- vty_frame(vty, "vrf %s\n", vrf->name);
+ struct lyd_node *dnode;
+ int written = 0;
- static_config(vty, vrf->info, AFI_IP,
- SAFI_UNICAST, "ip route");
- static_config(vty, vrf->info, AFI_IP,
- SAFI_MULTICAST, "ip mroute");
- static_config(vty, vrf->info, AFI_IP6,
- SAFI_UNICAST, "ipv6 route");
-
- if (vrf->vrf_id != VRF_DEFAULT)
- vty_endframe(vty, "exit-vrf\n!\n");
+ dnode = yang_dnode_get(running_config->dnode, "/frr-routing:routing");
+ if (dnode) {
+ nb_cli_show_dnode_cmds(vty, dnode, false);
+ written = 1;
}
- return 0;
+ return written;
}
void static_vrf_init(void)
diff --git a/staticd/static_vty.c b/staticd/static_vty.c
index f4cb13434..751a26277 100644
--- a/staticd/static_vty.c
+++ b/staticd/static_vty.c
@@ -357,129 +357,6 @@ static int static_route(struct vty *vty, afi_t afi, safi_t safi,
table_str, false, NULL);
}
-/* Write static route configuration. */
-int static_config(struct vty *vty, struct static_vrf *svrf, afi_t afi,
- safi_t safi, const char *cmd)
-{
- char spacing[100];
- struct route_node *rn;
- 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)
- return write;
-
- snprintf(spacing, sizeof(spacing), "%s%s",
- (svrf->vrf->vrf_id == VRF_DEFAULT) ? "" : " ", cmd);
-
- for (rn = route_top(stable); rn; rn = srcdest_route_next(rn)) {
- si = static_route_info_from_rnode(rn);
- if (!si)
- continue;
- 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, " %pI4", &nh->addr.ipv4);
- break;
- case STATIC_IPV6_GATEWAY:
- vty_out(vty, " %s",
- inet_ntop(AF_INET6,
- &nh->addr.ipv6, buf,
- sizeof(buf)));
- break;
- 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;
- }
-
- 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 (!strmatch(nh->nh_vrfname,
- info->svrf->vrf->name))
- 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");
-
- /*
- * SR-TE color
- */
- if (nh->color != 0)
- vty_out(vty, " color %u", nh->color);
-
- vty_out(vty, "\n");
-
- write = 1;
- }
- }
- }
- return write;
-}
-
/* Static unicast routes for multicast RPF lookup. */
DEFPY_YANG (ip_mroute_dist,
ip_mroute_dist_cmd,
@@ -1124,6 +1001,278 @@ DEFPY_YANG(ipv6_route_vrf,
ifname, flag, tag_str, distance_str, label,
table_str, false, color_str);
}
+
+void static_cli_show(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ const char *vrf;
+
+ vrf = yang_dnode_get_string(dnode, "../vrf");
+ if (strcmp(vrf, VRF_DEFAULT_NAME))
+ vty_out(vty, "vrf %s\n", vrf);
+}
+
+void static_cli_show_end(struct vty *vty, struct lyd_node *dnode)
+{
+ const char *vrf;
+
+ vrf = yang_dnode_get_string(dnode, "../vrf");
+ if (strcmp(vrf, VRF_DEFAULT_NAME))
+ vty_out(vty, "exit-vrf\n");
+}
+
+struct mpls_label_iter {
+ struct vty *vty;
+ bool first;
+};
+
+static int mpls_label_iter_cb(const struct lyd_node *dnode, void *arg)
+{
+ struct mpls_label_iter *iter = arg;
+
+ if (yang_dnode_exists(dnode, "./label")) {
+ if (iter->first)
+ vty_out(iter->vty, " label %s",
+ yang_dnode_get_string(dnode, "./label"));
+ else
+ vty_out(iter->vty, "/%s",
+ yang_dnode_get_string(dnode, "./label"));
+ iter->first = false;
+ }
+
+ return YANG_ITER_CONTINUE;
+}
+
+static void nexthop_cli_show(struct vty *vty, const struct lyd_node *route,
+ const struct lyd_node *src,
+ const struct lyd_node *path,
+ const struct lyd_node *nexthop, bool show_defaults)
+{
+ const char *vrf;
+ const char *afi_safi;
+ afi_t afi;
+ safi_t safi;
+ enum static_nh_type nh_type;
+ enum static_blackhole_type bh_type;
+ uint32_t tag;
+ uint8_t distance;
+ struct mpls_label_iter iter;
+ const char *nexthop_vrf;
+ uint32_t table_id;
+ bool onlink;
+
+ vrf = yang_dnode_get_string(route, "../../vrf");
+
+ afi_safi = yang_dnode_get_string(route, "./afi-safi");
+ yang_afi_safi_identity2value(afi_safi, &afi, &safi);
+
+ if (afi == AFI_IP)
+ vty_out(vty, "%sip",
+ strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " ");
+ else
+ vty_out(vty, "%sipv6",
+ strmatch(vrf, VRF_DEFAULT_NAME) ? "" : " ");
+
+ if (safi == SAFI_UNICAST)
+ vty_out(vty, " route");
+ else
+ vty_out(vty, " mroute");
+
+ vty_out(vty, " %s", yang_dnode_get_string(route, "./prefix"));
+
+ if (src)
+ vty_out(vty, " from %s",
+ yang_dnode_get_string(src, "./src-prefix"));
+
+ nh_type = yang_dnode_get_enum(nexthop, "./nh-type");
+ switch (nh_type) {
+ case STATIC_IFNAME:
+ vty_out(vty, " %s",
+ yang_dnode_get_string(nexthop, "./interface"));
+ break;
+ case STATIC_IPV4_GATEWAY:
+ case STATIC_IPV6_GATEWAY:
+ vty_out(vty, " %s",
+ yang_dnode_get_string(nexthop, "./gateway"));
+ break;
+ case STATIC_IPV4_GATEWAY_IFNAME:
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ vty_out(vty, " %s",
+ yang_dnode_get_string(nexthop, "./gateway"));
+ vty_out(vty, " %s",
+ yang_dnode_get_string(nexthop, "./interface"));
+ break;
+ case STATIC_BLACKHOLE:
+ bh_type = yang_dnode_get_enum(nexthop, "./bh-type");
+ switch (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;
+ }
+
+ if (yang_dnode_exists(path, "./tag")) {
+ tag = yang_dnode_get_uint32(path, "./tag");
+ if (tag != 0 || show_defaults)
+ vty_out(vty, " tag %" PRIu32, tag);
+ }
+
+ distance = yang_dnode_get_uint8(path, "./distance");
+ if (distance != ZEBRA_STATIC_DISTANCE_DEFAULT || show_defaults)
+ vty_out(vty, " %" PRIu8, distance);
+
+ iter.vty = vty;
+ iter.first = true;
+ yang_dnode_iterate(mpls_label_iter_cb, &iter, nexthop,
+ "./mpls-label-stack/entry");
+
+ nexthop_vrf = yang_dnode_get_string(nexthop, "./vrf");
+ if (strcmp(vrf, nexthop_vrf))
+ vty_out(vty, " nexthop-vrf %s", nexthop_vrf);
+
+ table_id = yang_dnode_get_uint32(path, "./table-id");
+ if (table_id || show_defaults)
+ vty_out(vty, " table %" PRIu32, table_id);
+
+ if (yang_dnode_exists(nexthop, "./onlink")) {
+ onlink = yang_dnode_get_bool(nexthop, "./onlink");
+ if (onlink)
+ vty_out(vty, " onlink");
+ }
+
+ if (yang_dnode_exists(nexthop, "./srte-color"))
+ vty_out(vty, " color %s",
+ yang_dnode_get_string(nexthop, "./srte-color"));
+
+ vty_out(vty, "\n");
+}
+
+void static_nexthop_cli_show(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list");
+ const struct lyd_node *route =
+ yang_dnode_get_parent(path, "route-list");
+
+ nexthop_cli_show(vty, route, NULL, path, dnode, show_defaults);
+}
+
+void static_src_nexthop_cli_show(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults)
+{
+ const struct lyd_node *path = yang_dnode_get_parent(dnode, "path-list");
+ const struct lyd_node *src = yang_dnode_get_parent(path, "src-list");
+ const struct lyd_node *route = yang_dnode_get_parent(src, "route-list");
+
+ nexthop_cli_show(vty, route, src, path, dnode, show_defaults);
+}
+
+int static_nexthop_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2)
+{
+ enum static_nh_type nh_type1, nh_type2;
+ struct prefix prefix1, prefix2;
+ int ret = 0;
+
+ nh_type1 = yang_dnode_get_enum(dnode1, "./nh-type");
+ nh_type2 = yang_dnode_get_enum(dnode2, "./nh-type");
+
+ if (nh_type1 != nh_type2)
+ return (int)nh_type1 - (int)nh_type2;
+
+ switch (nh_type1) {
+ case STATIC_IFNAME:
+ ret = if_cmp_name_func(
+ yang_dnode_get_string(dnode1, "./interface"),
+ yang_dnode_get_string(dnode2, "./interface"));
+ break;
+ case STATIC_IPV4_GATEWAY:
+ case STATIC_IPV6_GATEWAY:
+ yang_dnode_get_prefix(&prefix1, dnode1, "./gateway");
+ yang_dnode_get_prefix(&prefix2, dnode2, "./gateway");
+ ret = prefix_cmp(&prefix1, &prefix2);
+ break;
+ case STATIC_IPV4_GATEWAY_IFNAME:
+ case STATIC_IPV6_GATEWAY_IFNAME:
+ yang_dnode_get_prefix(&prefix1, dnode1, "./gateway");
+ yang_dnode_get_prefix(&prefix2, dnode2, "./gateway");
+ ret = prefix_cmp(&prefix1, &prefix2);
+ if (!ret)
+ ret = if_cmp_name_func(
+ yang_dnode_get_string(dnode1, "./interface"),
+ yang_dnode_get_string(dnode2, "./interface"));
+ break;
+ case STATIC_BLACKHOLE:
+ /* There's only one blackhole nexthop per route */
+ ret = 0;
+ break;
+ }
+
+ if (ret)
+ return ret;
+
+ return if_cmp_name_func(yang_dnode_get_string(dnode1, "./vrf"),
+ yang_dnode_get_string(dnode2, "./vrf"));
+}
+
+int static_route_list_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2)
+{
+ const char *afi_safi1, *afi_safi2;
+ afi_t afi1, afi2;
+ safi_t safi1, safi2;
+ struct prefix prefix1, prefix2;
+
+ afi_safi1 = yang_dnode_get_string(dnode1, "./afi-safi");
+ yang_afi_safi_identity2value(afi_safi1, &afi1, &safi1);
+
+ afi_safi2 = yang_dnode_get_string(dnode2, "./afi-safi");
+ yang_afi_safi_identity2value(afi_safi2, &afi2, &safi2);
+
+ if (afi1 != afi2)
+ return (int)afi1 - (int)afi2;
+
+ if (safi1 != safi2)
+ return (int)safi1 - (int)safi2;
+
+ yang_dnode_get_prefix(&prefix1, dnode1, "./prefix");
+ yang_dnode_get_prefix(&prefix2, dnode2, "./prefix");
+
+ return prefix_cmp(&prefix1, &prefix2);
+}
+
+int static_src_list_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2)
+{
+ struct prefix prefix1, prefix2;
+
+ yang_dnode_get_prefix(&prefix1, dnode1, "./src-prefix");
+ yang_dnode_get_prefix(&prefix2, dnode2, "./src-prefix");
+
+ return prefix_cmp(&prefix1, &prefix2);
+}
+
+int static_path_list_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2)
+{
+ uint32_t table_id1, table_id2;
+ uint8_t distance1, distance2;
+
+ table_id1 = yang_dnode_get_uint32(dnode1, "./table-id");
+ table_id2 = yang_dnode_get_uint32(dnode2, "./table-id");
+
+ if (table_id1 != table_id2)
+ return (int)table_id1 - (int)table_id2;
+
+ distance1 = yang_dnode_get_uint8(dnode1, "./distance");
+ distance2 = yang_dnode_get_uint8(dnode2, "./distance");
+
+ return (int)distance1 - (int)distance2;
+}
+
DEFPY_YANG(debug_staticd, debug_staticd_cmd,
"[no] debug static [{events$events|route$route}]",
NO_STR DEBUG_STR STATICD_STR
diff --git a/staticd/static_vty.h b/staticd/static_vty.h
index 01577685e..8861afa46 100644
--- a/staticd/static_vty.h
+++ b/staticd/static_vty.h
@@ -23,8 +23,17 @@
extern "C" {
#endif
-int static_config(struct vty *vty, struct static_vrf *svrf,
- afi_t afi, safi_t safi, const char *cmd);
+void static_cli_show(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+void static_cli_show_end(struct vty *vty, struct lyd_node *dnode);
+void static_nexthop_cli_show(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+void static_src_nexthop_cli_show(struct vty *vty, struct lyd_node *dnode,
+ bool show_defaults);
+int static_nexthop_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2);
+int static_route_list_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2);
+int static_src_list_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2);
+int static_path_list_cli_cmp(struct lyd_node *dnode1, struct lyd_node *dnode2);
void static_vty_init(void);