Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

lib: add debugs for interface lib module events #15522

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
110 changes: 110 additions & 0 deletions lib/if.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ DEFINE_KOOH(if_unreal, (struct interface *ifp), (ifp));
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 intf_lib_debug;

/* Compare interface names, returning an integer greater than, equal to, or
* less than 0, (following the strcmp convention), according to the
* relationship between ifp1 and ifp2. Interface names consist of an
Expand Down Expand Up @@ -188,11 +191,19 @@ static struct interface *if_new(struct vrf *vrf)

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

hook_call(if_real, ifp);
}

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

hook_call(if_unreal, ifp);

ifp->oldifindex = ifp->ifindex;
Expand All @@ -204,11 +215,19 @@ void if_destroy_via_zapi(struct interface *ifp)

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

hook_call(if_up, ifp);
}

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

hook_call(if_down, ifp);
}

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

if_set_name(ifp, name);

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

if (if_notify_oper_changes && ifp->state)
if_update_state(ifp);

Expand All @@ -334,6 +357,10 @@ 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 (intf_lib_debug)
zlog_debug("%s: ifp %s, old vrf %u -> new vrf %u", __func__,
ifp->name, old_vrf->vrf_id, vrf_id);

if (ifp->name[0] != '\0') {
IFNAME_RB_REMOVE(old_vrf, ifp);
if_update_state_remove(ifp);
Expand Down Expand Up @@ -378,6 +405,10 @@ void if_delete(struct interface **ifp)
struct interface *ptr = *ifp;
struct vrf *vrf = ptr->vrf;

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

IFNAME_RB_REMOVE(vrf, ptr);
if (ptr->ifindex != IFINDEX_INTERNAL)
IFINDEX_RB_REMOVE(vrf, ptr);
Expand Down Expand Up @@ -704,6 +735,10 @@ struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id,

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

ifp = if_lookup_by_name_all_vrf(name);
if (ifp) {
/* If it came from the kernel or by way of zclient,
Expand Down Expand Up @@ -1488,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 @@ -1828,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
16 changes: 16 additions & 0 deletions zebra/zapi_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,10 @@ int zsend_interface_add(struct zserv *client, struct interface *ifp)
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);

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

zclient_create_header(s, ZEBRA_INTERFACE_ADD, ifp->vrf->vrf_id);
zserv_encode_interface(s, ifp);

Expand All @@ -187,6 +191,10 @@ int zsend_interface_delete(struct zserv *client, struct interface *ifp)
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);

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

zclient_create_header(s, ZEBRA_INTERFACE_DELETE, ifp->vrf->vrf_id);
zserv_encode_interface(s, ifp);

Expand All @@ -198,6 +206,10 @@ int zsend_vrf_add(struct zserv *client, struct zebra_vrf *zvrf)
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);

if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: %s vrf %s(%u)", __func__, zvrf->vrf->name,
zvrf_id(zvrf));

zclient_create_header(s, ZEBRA_VRF_ADD, zvrf_id(zvrf));
zserv_encode_vrf(s, zvrf);

Expand All @@ -211,6 +223,10 @@ int zsend_vrf_delete(struct zserv *client, struct zebra_vrf *zvrf)
{
struct stream *s = stream_new(ZEBRA_MAX_PACKET_SIZ);

if (IS_ZEBRA_DEBUG_EVENT)
zlog_debug("MESSAGE: %s vrf %s(%u)", __func__, zvrf->vrf->name,
zvrf_id(zvrf));

zclient_create_header(s, ZEBRA_VRF_DELETE, zvrf_id(zvrf));
zserv_encode_vrf(s, zvrf);

Expand Down
Loading