Skip to content

Commit

Permalink
libs: add cli for interface lib debugs
Browse files Browse the repository at this point in the history
Add cli, handlers, and yang model for 'debug interface'. This was
a little awkward; had to put the actual cli in one lib module and
offer some support apis from the interface module.

Signed-off-by: Mark Stapp <[email protected]>
  • Loading branch information
Mark Stapp committed Jan 15, 2025
1 parent a6bcab8 commit 0658790
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 11 deletions.
1 change: 1 addition & 0 deletions lib/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -2465,6 +2465,7 @@ void cmd_show_lib_debugs(struct vty *vty)
{
route_map_show_debug(vty);
debug_status_write(vty);
lib_if_show_debug(vty);
}

void install_default(enum node_type node)
Expand Down
1 change: 1 addition & 0 deletions lib/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ enum node_type {
RPKI_VRF_NODE, /* RPKI node for VRF */
PIM_NODE, /* PIM protocol mode */
PIM6_NODE, /* PIM protocol for IPv6 mode */
INTF_DEBUG_NODE, /* Interface Lib Debug node. */
NODE_TYPE_MAX, /* maximum */
};
/* clang-format on */
Expand Down
93 changes: 84 additions & 9 deletions lib/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ DEFINE_HOOK(if_up, (struct interface *ifp), (ifp));
DEFINE_KOOH(if_down, (struct interface *ifp), (ifp));

/* Control debug output for the lib module */
static bool ifp_debug;
static bool intf_lib_debug;

/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
Expand Down Expand Up @@ -191,7 +191,7 @@ static struct interface *if_new(struct vrf *vrf)

void if_new_via_zapi(struct interface *ifp)
{
if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, vrf %u", __func__, ifp->name,
ifp->vrf->vrf_id);

Expand All @@ -200,7 +200,7 @@ void if_new_via_zapi(struct interface *ifp)

void if_destroy_via_zapi(struct interface *ifp)
{
if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, vrf %u", __func__, ifp->name,
ifp->vrf->vrf_id);

Expand All @@ -215,7 +215,7 @@ void if_destroy_via_zapi(struct interface *ifp)

void if_up_via_zapi(struct interface *ifp)
{
if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, vrf %u", __func__, ifp->name,
ifp->vrf->vrf_id);

Expand All @@ -224,7 +224,7 @@ void if_up_via_zapi(struct interface *ifp)

void if_down_via_zapi(struct interface *ifp)
{
if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, vrf %u", __func__, ifp->name,
ifp->vrf->vrf_id);

Expand Down Expand Up @@ -337,7 +337,7 @@ static struct interface *if_create_name(const char *name, struct vrf *vrf)

if_set_name(ifp, name);

if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, vrf %u", __func__, ifp->name,
ifp->vrf->vrf_id);

Expand All @@ -357,7 +357,7 @@ void if_update_to_new_vrf(struct interface *ifp, vrf_id_t vrf_id)
/* remove interface from old master vrf list */
old_vrf = ifp->vrf;

if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, old vrf %u -> new vrf %u", __func__,
ifp->name, old_vrf->vrf_id, vrf_id);

Expand Down Expand Up @@ -405,7 +405,7 @@ void if_delete(struct interface **ifp)
struct interface *ptr = *ifp;
struct vrf *vrf = ptr->vrf;

if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifp %s, vrf %u", __func__, ptr->name,
vrf->vrf_id);

Expand Down Expand Up @@ -735,7 +735,7 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id,

break;
case VRF_BACKEND_VRF_LITE:
if (ifp_debug)
if (intf_lib_debug)
zlog_debug("%s: ifname %s, vrf_id %i, vrf_name %s",
__func__, name, vrf_id, vrf_name);

Expand Down Expand Up @@ -1523,6 +1523,50 @@ static void if_autocomplete(vector comps, struct cmd_token *token)
}
}

/* Enable, disable lib debugging. The controlling CLI handlers are in another
* lib module...
*/
void lib_if_enable_debug(struct vty *vty, bool enable, bool config)
{
char xpath[XPATH_MAXLEN];

intf_lib_debug = enable;
if (config) {
/* Update northbound */
strlcpy(xpath, "/frr-interface:lib/debug-enable", sizeof(xpath));
nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
enable ? "true" : "false");

nb_cli_apply_changes(vty, NULL);
}
}

int lib_if_debug_write_config(struct vty *vty)
{
int written = 0;
const struct lyd_node *dnode;
bool enabled;

dnode = yang_dnode_get(running_config->dnode,
"/frr-interface:lib/debug-enable");
if (dnode) {
enabled = yang_dnode_get_bool(dnode, NULL);
if (enabled) {
vty_out(vty, "debug interface\n");
written++;
}
}

return written;
}

/* Show lib debugging */
void lib_if_show_debug(struct vty *vty)
{
if (intf_lib_debug)
vty_out(vty, " Interface library debugging is on\n");
}

static const struct cmd_variable_handler if_var_handlers[] = {
{/* "interface NAME" */
.varname = "interface",
Expand Down Expand Up @@ -1863,12 +1907,43 @@ lib_interface_state_phy_address_get_elem(struct nb_cb_get_elem_args *args)
return yang_data_new_mac(args->xpath, &macaddr);
}

/*
* XPath: /frr-interface:lib/debug-enable
*/
static int lib_debug_enable_modify(struct nb_cb_modify_args *args)
{
bool enable;

if (args->event != NB_EV_APPLY)
return NB_OK;

/* Apply begins here */
enable = yang_dnode_get_bool(args->dnode, NULL);
intf_lib_debug = enable;

return NB_OK;
}

static void lib_debug_enable_cli_write(struct vty *vty,
const struct lyd_node *dnode,
bool show_defaults)
{
lib_if_debug_write_config(vty);
}

/* clang-format off */

/* cli_show callbacks are kept here for daemons not yet converted to mgmtd */
const struct frr_yang_module_info frr_interface_info = {
.name = "frr-interface",
.nodes = {
{
.xpath = "/frr-interface:lib/debug-enable",
.cbs = {
.modify = lib_debug_enable_modify,
.cli_show = lib_debug_enable_cli_write,
}
},
{
.xpath = "/frr-interface:lib/interface",
.cbs = {
Expand Down
8 changes: 7 additions & 1 deletion lib/if.h
Original file line number Diff line number Diff line change
Expand Up @@ -623,8 +623,14 @@ struct if_link_params *if_link_params_enable(struct interface *ifp);
struct if_link_params *if_link_params_init(struct interface *ifp);
void if_link_params_free(struct interface *ifp);

/* Northbound. */
/* Forward declaration */
struct vty;

void lib_if_show_debug(struct vty *vty);
void lib_if_enable_debug(struct vty *vty, bool enable, bool config);
int lib_if_debug_write_config(struct vty *vty);

/* Northbound. */
extern void if_vty_config_start(struct vty *vty, struct interface *ifp);
extern void if_vty_config_end(struct vty *vty);
extern void if_cmd_init(int (*config_write)(struct vty *));
Expand Down
31 changes: 31 additions & 0 deletions lib/vty.c
Original file line number Diff line number Diff line change
Expand Up @@ -3512,6 +3512,32 @@ void vty_init_vtysh(void)
/* currently nothing to do, but likely to have future use */
}

/* Control interface lib-level debugs */
DEFPY (intf_lib_debug_s,
intf_lib_debug_cmd,
"[no] debug interface",
NO_STR
DEBUG_STR
"Interface Library Debugging\n")
{
lib_if_enable_debug(vty, no == NULL, vty->node == CONFIG_NODE);

return CMD_SUCCESS;
}

/* Config write for interface lib debugs */
static int intf_lib_write_cfg(struct vty *vty)
{
return lib_if_debug_write_config(vty);
}

/* Config node for interface lib debugs */
static struct cmd_node intf_lib_debug_node = {
.name = "intf debug",
.node = INTF_DEBUG_NODE,
.prompt = "",
.config_write = intf_lib_write_cfg,
};

/*
* These functions allow for CLI handling to be placed inside daemons; however,
Expand Down Expand Up @@ -4306,6 +4332,11 @@ void vty_init(struct event_loop *master_thread, bool do_command_logging)
install_element(VTY_NODE, &no_vty_login_cmd);
install_element(VTY_NODE, &vty_ipv6_access_class_cmd);
install_element(VTY_NODE, &no_vty_ipv6_access_class_cmd);

/* Install interface lib debugs */
install_node(&intf_lib_debug_node);
install_element(ENABLE_NODE, &intf_lib_debug_cmd);
install_element(CONFIG_NODE, &intf_lib_debug_cmd);
}

void vty_terminate(void)
Expand Down
6 changes: 5 additions & 1 deletion vtysh/vtysh_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,9 @@ void vtysh_config_parse_line(void *arg, const char *line)
config = config_get(FORWARDING_NODE, line);
else if (strncmp(line, "debug vrf", strlen("debug vrf")) == 0)
config = config_get(VRF_DEBUG_NODE, line);
else if (strncmp(line, "debug interface",
strlen("debug interface")) == 0)
config = config_get(INTF_DEBUG_NODE, line);
else if (strncmp(line, "debug route-map",
strlen("debug route-map"))
== 0)
Expand Down Expand Up @@ -528,7 +531,8 @@ void vtysh_config_parse_line(void *arg, const char *line)
(I) == PREFIX_IPV6_NODE || (I) == FORWARDING_NODE || \
(I) == DEBUG_NODE || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE || \
(I) == RMAP_DEBUG_NODE || (I) == RESOLVER_DEBUG_NODE || \
(I) == MPLS_NODE || (I) == KEYCHAIN_KEY_NODE)
(I) == MPLS_NODE || (I) == KEYCHAIN_KEY_NODE || \
(I) == INTF_DEBUG_NODE)

static void configvec_dump(vector vec, bool nested)
{
Expand Down
7 changes: 7 additions & 0 deletions yang/frr-interface.yang
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,13 @@ module frr-interface {
}

container lib {
leaf debug-enable {
type boolean;
default false;
description
"Enable library-level debugs.";
}

list interface {
key "name";
description
Expand Down

0 comments on commit 0658790

Please sign in to comment.