From 19dc275e1f22d6821c60ef50759b591849fad40a Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Wed, 3 Feb 2016 09:00:25 -0500 Subject: [PATCH] lib, vtysh, zebra: Better VRF debug handling Fixup the debug handling of vrf's to be a bit more explicit how we create a vrf internally. Add code to turn on/off debugging of vrf's. Ticket: CM-9063 Testing: Manual Signed-off-by: Donald Sharp --- lib/command.c | 3 ++ lib/command.h | 1 + lib/vrf.c | 104 ++++++++++++++++++++++++++++++++++++++----- lib/vrf.h | 4 ++ vtysh/Makefile.am | 1 + vtysh/extract.pl.in | 3 ++ vtysh/vtysh_config.c | 4 +- zebra/rt_netlink.c | 4 +- 8 files changed, 109 insertions(+), 15 deletions(-) diff --git a/lib/command.c b/lib/command.c index ed337cbccf..4d4a72a03a 100644 --- a/lib/command.c +++ b/lib/command.c @@ -32,6 +32,7 @@ Boston, MA 02111-1307, USA. */ #include "vty.h" #include "command.h" #include "workqueue.h" +#include "vrf.h" /* Command vector which includes some level of command lists. Normally each daemon maintains each own cmdvec. */ @@ -4194,6 +4195,8 @@ cmd_init (int terminal) install_element (ENABLE_NODE, &clear_thread_cpu_cmd); install_element (VIEW_NODE, &show_work_queues_cmd); install_element (ENABLE_NODE, &show_work_queues_cmd); + + vrf_install_commands (); } srand(time(NULL)); } diff --git a/lib/command.h b/lib/command.h index c964b8a807..1b3c0b45ca 100644 --- a/lib/command.h +++ b/lib/command.h @@ -70,6 +70,7 @@ enum node_type CONFIG_NODE, /* Config node. Default mode of config file. */ SERVICE_NODE, /* Service node. */ DEBUG_NODE, /* Debug node. */ + VRF_DEBUG_NODE, /* Vrf Debug node. */ AAA_NODE, /* AAA node. */ KEYCHAIN_NODE, /* Key-chain node. */ KEYCHAIN_KEY_NODE, /* Key-chain key node. */ diff --git a/lib/vrf.c b/lib/vrf.c index d425a8d8eb..45cc8735a2 100644 --- a/lib/vrf.c +++ b/lib/vrf.c @@ -28,6 +28,13 @@ #include "table.h" #include "log.h" #include "memory.h" +#include "command.h" + +/* + * Turn on/off debug code + * for vrf. + */ +int debug_vrf = 0; /* Holding VRF hooks */ struct vrf_master @@ -160,15 +167,28 @@ vrf_get (vrf_id_t vrf_id, const char *name) if (vrf_list_lookup_by_name (vrf->name) == NULL) listnode_add_sort (vrf_list, vrf); } + if (debug_vrf) + zlog_debug ("VRF(%u) %s Found %p", vrf_id, (name) ? name : "(NULL)", + vrf); } else { if (name) vrf = vrf_get_by_name(name); - if (!vrf) - vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); - + if (vrf) + { + if (debug_vrf) + zlog_debug ("VRF(%u) %s lookup by name is successful", + vrf_id, (name) ? name : "(NULL)"); + } + else + { + vrf = XCALLOC (MTYPE_VRF, sizeof (struct vrf)); + if (debug_vrf) + zlog_debug ("VRF(%u) %s is created.", + vrf_id, (name) ? name : "(NULL)"); + } vrf->vrf_id = vrf_id; rn->info = vrf; vrf->node = rn; @@ -177,11 +197,6 @@ vrf_get (vrf_id_t vrf_id, const char *name) if_init (vrf_id, &vrf->iflist); } - if (name) - zlog_info ("VRF %s with id %u is created.", name, vrf_id); - else - zlog_info ("VRF %u is created.", vrf_id); - if (vrf_master.vrf_new_hook && name) { (*vrf_master.vrf_new_hook) (vrf_id, name, &vrf->info); @@ -195,7 +210,8 @@ vrf_get (vrf_id_t vrf_id, const char *name) void vrf_delete (struct vrf *vrf) { - zlog_info ("VRF %u is to be deleted.", vrf->vrf_id); + if (debug_vrf) + zlog_debug ("VRF %u is to be deleted.", vrf->vrf_id); if (vrf_is_enabled (vrf)) vrf_disable (vrf); @@ -264,7 +280,8 @@ vrf_enable (struct vrf *vrf) // /* Till now, only the default VRF can be enabled. */ // if (vrf->vrf_id == VRF_DEFAULT) // { - zlog_info ("VRF %u is enabled.", vrf->vrf_id); + if (debug_vrf) + zlog_debug ("VRF %u is enabled.", vrf->vrf_id); if (vrf_master.vrf_enable_hook) (*vrf_master.vrf_enable_hook) (vrf->vrf_id, vrf->name, &vrf->info); @@ -285,7 +302,8 @@ vrf_disable (struct vrf *vrf) { if (vrf_is_enabled (vrf)) { - zlog_info ("VRF %u is to be disabled.", vrf->vrf_id); + if (debug_vrf) + zlog_debug ("VRF %u is to be disabled.", vrf->vrf_id); /* Till now, nothing to be done for the default VRF. */ //Pending: see why this statement. @@ -300,6 +318,10 @@ vrf_disable (struct vrf *vrf) void vrf_add_hook (int type, int (*func)(vrf_id_t, const char *, void **)) { + if (debug_vrf) + zlog_debug ("%s: Add Hook %d to function %p", __PRETTY_FUNCTION__, + type, func); + switch (type) { case VRF_NEW_HOOK: vrf_master.vrf_new_hook = func; @@ -638,6 +660,9 @@ vrf_init (void) { struct vrf *default_vrf; + if (debug_vrf) + zlog_debug ("%s: Initializing VRF subsystem", __PRETTY_FUNCTION__); + vrf_list = list_new (); vrf_list->cmp = (int (*)(void *, void *))vrf_cmp_func; @@ -667,6 +692,9 @@ vrf_terminate (void) struct route_node *rn; struct vrf *vrf; + if (debug_vrf) + zlog_debug ("%s: Shutting down vrf subsystem", __PRETTY_FUNCTION__); + for (rn = route_top (vrf_table); rn; rn = route_next (rn)) if ((vrf = rn->info) != NULL) vrf_delete (vrf); @@ -681,8 +709,60 @@ vrf_socket (int domain, int type, int protocol, vrf_id_t vrf_id) { int ret = -1; - ret = socket (domain, type, protocol); + ret = socket (domain, type, protocol); return ret; } +/* + * Debug CLI for vrf's + */ +DEFUN (vrf_debug, + vrf_debug_cmd, + "debug vrf", + DEBUG_STR + "VRF Debugging\n") +{ + debug_vrf = 1; + + return CMD_SUCCESS; +} + +DEFUN (no_vrf_debug, + no_vrf_debug_cmd, + "no debug vrf", + NO_STR + DEBUG_STR + "VRF Debugging\n") +{ + debug_vrf = 0; + + return CMD_SUCCESS; +} + +static int +vrf_write_host (struct vty *vty) +{ + if (debug_vrf) + vty_out (vty, "debug vrf%s", VTY_NEWLINE); + + return 1; +} + +static struct cmd_node vrf_debug_node = +{ + VRF_DEBUG_NODE, + "", + 1 +}; + +void +vrf_install_commands (void) +{ + install_node (&vrf_debug_node, vrf_write_host); + + install_element (CONFIG_NODE, &vrf_debug_cmd); + install_element (ENABLE_NODE, &vrf_debug_cmd); + install_element (CONFIG_NODE, &no_vrf_debug_cmd); + install_element (ENABLE_NODE, &no_vrf_debug_cmd); +} diff --git a/lib/vrf.h b/lib/vrf.h index 70bd54263e..3ef2979dc1 100644 --- a/lib/vrf.h +++ b/lib/vrf.h @@ -208,5 +208,9 @@ extern void vrf_terminate (void); /* Create a socket serving for the given VRF */ extern int vrf_socket (int, int, int, vrf_id_t); +/* + * VRF Debugging + */ +extern void vrf_install_commands (void); #endif /*_ZEBRA_VRF_H*/ diff --git a/vtysh/Makefile.am b/vtysh/Makefile.am index 473e830b62..82b5888568 100644 --- a/vtysh/Makefile.am +++ b/vtysh/Makefile.am @@ -29,6 +29,7 @@ vtysh_cmd_FILES = $(top_srcdir)/bgpd/*.c $(top_srcdir)/isisd/*.c \ $(top_srcdir)/lib/filter.c $(top_srcdir)/lib/plist.c \ $(top_srcdir)/lib/distribute.c $(top_srcdir)/lib/if_rmap.c \ $(top_srcdir)/lib/vty.c $(top_srcdir)/zebra/debug.c \ + $(top_srcdir)/lib/vrf.c \ $(top_srcdir)/zebra/interface.c \ $(top_srcdir)/zebra/irdp_interface.c \ $(top_srcdir)/zebra/rtadv.c $(top_srcdir)/zebra/zebra_vty.c \ diff --git a/vtysh/extract.pl.in b/vtysh/extract.pl.in index cee63190be..808031e928 100755 --- a/vtysh/extract.pl.in +++ b/vtysh/extract.pl.in @@ -100,6 +100,9 @@ foreach (@ARGV) { elsif ($file =~ /lib\/routemap\.c$/) { $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA"; } + elsif ($file =~ /lib\/vrf\.c$/) { + $protocol = "VTYSH_RIPD|VTYSH_RIPNGD|VTYSH_OSPFD|VTYSH_OSPF6D|VTYSH_BGPD|VTYSH_ZEBRA"; + } elsif ($file =~ /lib\/filter\.c$/) { $protocol = "VTYSH_ALL"; } diff --git a/vtysh/vtysh_config.c b/vtysh/vtysh_config.c index 2fe08f10dc..3643c29ece 100644 --- a/vtysh/vtysh_config.c +++ b/vtysh/vtysh_config.c @@ -250,6 +250,8 @@ vtysh_config_parse_line (const char *line) config = config_get (FORWARDING_NODE, line); else if (strncmp (line, "service", strlen ("service")) == 0) config = config_get (SERVICE_NODE, line); + else if (strncmp (line, "debug vrf", strlen ("debug vrf")) == 0) + config = config_get (VRF_DEBUG_NODE, line); else if (strncmp (line, "debug", strlen ("debug")) == 0) config = config_get (DEBUG_NODE, line); else if (strncmp (line, "password", strlen ("password")) == 0 @@ -308,7 +310,7 @@ vtysh_config_parse (char *line) || (I) == AS_LIST_NODE || (I) == COMMUNITY_LIST_NODE || \ (I) == ACCESS_IPV6_NODE || (I) == PREFIX_IPV6_NODE \ || (I) == SERVICE_NODE || (I) == FORWARDING_NODE || (I) == DEBUG_NODE \ - || (I) == AAA_NODE) + || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE) /* Display configuration to file pointer. */ void diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 2921a11ff7..31d64c8829 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -537,8 +537,8 @@ netlink_vrf_change (struct nlmsghdr *h, struct rtattr *tb, const char *name) { if (IS_ZEBRA_DEBUG_KERNEL) - zlog_debug ("%s: RTM_NEWLINK for VRF index %u, table %u", __func__, - ifi->ifi_index, nl_table_id); + zlog_debug ("%s: RTM_NEWLINK for VRF(%s) index %u, table %u", __func__, + name, ifi->ifi_index, nl_table_id); vrf = vrf_get((vrf_id_t)ifi->ifi_index, name); // It would create vrf if (!vrf) -- 2.39.5