mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-05-09 20:20:00 +00:00
Merge pull request #9410 from idryzhov/static-show-run-nb
staticd: output config using NB callbacks instead of operational data
This commit is contained in:
commit
2e69e3852f
@ -21,18 +21,26 @@
|
|||||||
#include "northbound.h"
|
#include "northbound.h"
|
||||||
#include "libfrr.h"
|
#include "libfrr.h"
|
||||||
#include "static_nb.h"
|
#include "static_nb.h"
|
||||||
|
#include "static_vty.h"
|
||||||
|
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
|
||||||
const struct frr_yang_module_info frr_staticd_info = {
|
const struct frr_yang_module_info frr_staticd_info = {
|
||||||
.name = "frr-staticd",
|
.name = "frr-staticd",
|
||||||
.nodes = {
|
.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",
|
.xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-staticd:staticd/route-list",
|
||||||
.cbs = {
|
.cbs = {
|
||||||
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create,
|
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_create,
|
||||||
.destroy = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_destroy,
|
.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 = {
|
.cbs = {
|
||||||
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_path_list_create,
|
.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,
|
.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,
|
.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,
|
.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,
|
.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 = {
|
.cbs = {
|
||||||
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_create,
|
.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,
|
.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 = {
|
.cbs = {
|
||||||
.create = routing_control_plane_protocols_control_plane_protocol_staticd_route_list_src_list_path_list_create,
|
.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,
|
.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,
|
.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,
|
.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,
|
.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,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -122,7 +122,7 @@ struct nexthop_iter {
|
|||||||
static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg)
|
static int nexthop_iter_cb(const struct lyd_node *dnode, void *arg)
|
||||||
{
|
{
|
||||||
struct nexthop_iter *iter = arg;
|
struct nexthop_iter *iter = arg;
|
||||||
int nh_type;
|
enum static_nh_type nh_type;
|
||||||
|
|
||||||
nh_type = yang_dnode_get_enum(dnode, "./nh-type");
|
nh_type = yang_dnode_get_enum(dnode, "./nh-type");
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ static bool static_nexthop_create(struct nb_cb_create_args *args)
|
|||||||
struct static_path *pn;
|
struct static_path *pn;
|
||||||
struct ipaddr ipaddr;
|
struct ipaddr ipaddr;
|
||||||
struct static_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
int nh_type;
|
enum static_nh_type nh_type;
|
||||||
const char *ifname;
|
const char *ifname;
|
||||||
const char *nh_vrf;
|
const char *nh_vrf;
|
||||||
|
|
||||||
@ -304,7 +304,7 @@ static int static_nexthop_mpls_label_modify(struct nb_cb_modify_args *args)
|
|||||||
static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
|
static int static_nexthop_onlink_modify(struct nb_cb_modify_args *args)
|
||||||
{
|
{
|
||||||
struct static_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
static_types nh_type;
|
enum static_nh_type nh_type;
|
||||||
|
|
||||||
switch (args->event) {
|
switch (args->event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
@ -352,7 +352,7 @@ static int static_nexthop_color_destroy(struct nb_cb_destroy_args *args)
|
|||||||
static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
|
static int static_nexthop_bh_type_modify(struct nb_cb_modify_args *args)
|
||||||
{
|
{
|
||||||
struct static_nexthop *nh;
|
struct static_nexthop *nh;
|
||||||
static_types nh_type;
|
enum static_nh_type nh_type;
|
||||||
|
|
||||||
switch (args->event) {
|
switch (args->event) {
|
||||||
case NB_EV_VALIDATE:
|
case NB_EV_VALIDATE:
|
||||||
|
@ -186,7 +186,8 @@ void static_del_route(struct route_node *rn)
|
|||||||
route_unlock_node(rn);
|
route_unlock_node(rn);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool static_add_nexthop_validate(const char *nh_vrf_name, static_types type,
|
bool static_add_nexthop_validate(const char *nh_vrf_name,
|
||||||
|
enum static_nh_type type,
|
||||||
struct ipaddr *ipaddr)
|
struct ipaddr *ipaddr)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct vrf *vrf;
|
||||||
@ -257,7 +258,7 @@ void static_del_path(struct static_path *pn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct static_nexthop *static_add_nexthop(struct static_path *pn,
|
struct static_nexthop *static_add_nexthop(struct static_path *pn,
|
||||||
static_types type,
|
enum static_nh_type type,
|
||||||
struct ipaddr *ipaddr,
|
struct ipaddr *ipaddr,
|
||||||
const char *ifname,
|
const char *ifname,
|
||||||
const char *nh_vrf, uint32_t color)
|
const char *nh_vrf, uint32_t color)
|
||||||
@ -772,7 +773,7 @@ void static_ifindex_update(struct interface *ifp, bool up)
|
|||||||
static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST);
|
static_ifindex_update_af(ifp, up, AFI_IP6, SAFI_MULTICAST);
|
||||||
}
|
}
|
||||||
|
|
||||||
void static_get_nh_type(static_types stype, char *type, size_t size)
|
void static_get_nh_type(enum static_nh_type stype, char *type, size_t size)
|
||||||
{
|
{
|
||||||
switch (stype) {
|
switch (stype) {
|
||||||
case STATIC_IFNAME:
|
case STATIC_IFNAME:
|
||||||
|
@ -47,14 +47,14 @@ enum static_blackhole_type {
|
|||||||
* The order for below macros should be in sync with
|
* The order for below macros should be in sync with
|
||||||
* yang model typedef nexthop-type
|
* yang model typedef nexthop-type
|
||||||
*/
|
*/
|
||||||
typedef enum {
|
enum static_nh_type {
|
||||||
STATIC_IFNAME = 1,
|
STATIC_IFNAME = 1,
|
||||||
STATIC_IPV4_GATEWAY,
|
STATIC_IPV4_GATEWAY,
|
||||||
STATIC_IPV4_GATEWAY_IFNAME,
|
STATIC_IPV4_GATEWAY_IFNAME,
|
||||||
STATIC_IPV6_GATEWAY,
|
STATIC_IPV6_GATEWAY,
|
||||||
STATIC_IPV6_GATEWAY_IFNAME,
|
STATIC_IPV6_GATEWAY_IFNAME,
|
||||||
STATIC_BLACKHOLE,
|
STATIC_BLACKHOLE,
|
||||||
} static_types;
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Route Creation gives us:
|
* Route Creation gives us:
|
||||||
@ -123,7 +123,7 @@ struct static_nexthop {
|
|||||||
enum static_install_states state;
|
enum static_install_states state;
|
||||||
|
|
||||||
/* Flag for this static route's type. */
|
/* Flag for this static route's type. */
|
||||||
static_types type;
|
enum static_nh_type type;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Nexthop value.
|
* Nexthop value.
|
||||||
@ -169,7 +169,7 @@ extern struct zebra_privs_t static_privs;
|
|||||||
void static_fixup_vrf_ids(struct static_vrf *svrf);
|
void static_fixup_vrf_ids(struct static_vrf *svrf);
|
||||||
|
|
||||||
extern struct static_nexthop *
|
extern struct static_nexthop *
|
||||||
static_add_nexthop(struct static_path *pn, static_types type,
|
static_add_nexthop(struct static_path *pn, enum static_nh_type type,
|
||||||
struct ipaddr *ipaddr, const char *ifname,
|
struct ipaddr *ipaddr, const char *ifname,
|
||||||
const char *nh_vrf, uint32_t color);
|
const char *nh_vrf, uint32_t color);
|
||||||
extern void static_install_nexthop(struct static_nexthop *nh);
|
extern void static_install_nexthop(struct static_nexthop *nh);
|
||||||
@ -194,9 +194,10 @@ extern struct static_path *static_add_path(struct route_node *rn,
|
|||||||
uint32_t table_id, uint8_t distance);
|
uint32_t table_id, uint8_t distance);
|
||||||
extern void static_del_path(struct static_path *pn);
|
extern void static_del_path(struct static_path *pn);
|
||||||
|
|
||||||
extern void static_get_nh_type(static_types stype, char *type, size_t size);
|
extern void static_get_nh_type(enum static_nh_type stype, char *type,
|
||||||
|
size_t size);
|
||||||
extern bool static_add_nexthop_validate(const char *nh_vrf_name,
|
extern bool static_add_nexthop_validate(const char *nh_vrf_name,
|
||||||
static_types type,
|
enum static_nh_type type,
|
||||||
struct ipaddr *ipaddr);
|
struct ipaddr *ipaddr);
|
||||||
extern struct stable_info *static_get_stable_info(struct route_node *rn);
|
extern struct stable_info *static_get_stable_info(struct route_node *rn);
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@
|
|||||||
#include "nexthop.h"
|
#include "nexthop.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
#include "srcdest_table.h"
|
#include "srcdest_table.h"
|
||||||
|
#include "northbound_cli.h"
|
||||||
|
|
||||||
#include "static_vrf.h"
|
#include "static_vrf.h"
|
||||||
#include "static_routes.h"
|
#include "static_routes.h"
|
||||||
#include "static_zebra.h"
|
#include "static_zebra.h"
|
||||||
#include "static_vty.h"
|
|
||||||
|
|
||||||
DEFINE_MTYPE_STATIC(STATIC, STATIC_RTABLE_INFO, "Static Route Table Info");
|
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)
|
static int static_vrf_config_write(struct vty *vty)
|
||||||
{
|
{
|
||||||
struct vrf *vrf;
|
struct lyd_node *dnode;
|
||||||
|
int written = 0;
|
||||||
|
|
||||||
RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
|
dnode = yang_dnode_get(running_config->dnode, "/frr-routing:routing");
|
||||||
if (vrf->vrf_id != VRF_DEFAULT)
|
if (dnode) {
|
||||||
vty_frame(vty, "vrf %s\n", vrf->name);
|
nb_cli_show_dnode_cmds(vty, dnode, false);
|
||||||
|
written = 1;
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
void static_vrf_init(void)
|
void static_vrf_init(void)
|
||||||
|
@ -56,7 +56,7 @@ static int static_route_leak(struct vty *vty, const char *svrf,
|
|||||||
int ret;
|
int ret;
|
||||||
struct prefix p, src;
|
struct prefix p, src;
|
||||||
struct in_addr mask;
|
struct in_addr mask;
|
||||||
uint8_t type;
|
enum static_nh_type type;
|
||||||
const char *bh_type;
|
const char *bh_type;
|
||||||
char xpath_prefix[XPATH_MAXLEN];
|
char xpath_prefix[XPATH_MAXLEN];
|
||||||
char xpath_nexthop[XPATH_MAXLEN];
|
char xpath_nexthop[XPATH_MAXLEN];
|
||||||
@ -357,129 +357,6 @@ static int static_route(struct vty *vty, afi_t afi, safi_t safi,
|
|||||||
table_str, false, NULL);
|
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. */
|
/* Static unicast routes for multicast RPF lookup. */
|
||||||
DEFPY_YANG (ip_mroute_dist,
|
DEFPY_YANG (ip_mroute_dist,
|
||||||
ip_mroute_dist_cmd,
|
ip_mroute_dist_cmd,
|
||||||
@ -1124,6 +1001,278 @@ DEFPY_YANG(ipv6_route_vrf,
|
|||||||
ifname, flag, tag_str, distance_str, label,
|
ifname, flag, tag_str, distance_str, label,
|
||||||
table_str, false, color_str);
|
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,
|
DEFPY_YANG(debug_staticd, debug_staticd_cmd,
|
||||||
"[no] debug static [{events$events|route$route}]",
|
"[no] debug static [{events$events|route$route}]",
|
||||||
NO_STR DEBUG_STR STATICD_STR
|
NO_STR DEBUG_STR STATICD_STR
|
||||||
|
@ -23,8 +23,17 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int static_config(struct vty *vty, struct static_vrf *svrf,
|
void static_cli_show(struct vty *vty, struct lyd_node *dnode,
|
||||||
afi_t afi, safi_t safi, const char *cmd);
|
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);
|
void static_vty_init(void);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user