From 48d0ecf7c4fabcdccaedc876bc042ca1f7dd5fd3 Mon Sep 17 00:00:00 2001 From: Rodny Molina Date: Tue, 15 May 2018 16:55:25 -0700 Subject: [PATCH] Enabling/fixing debug/undebug feature for quagga/frr With this PR I'm taking care of the following issues: * Fixed debug/undebug cli commands for bgp and zebra processes. * Added a new cli command to activate/deactivate the generation of debuging info. * Added two separated command structures for Quagga and FRR routing-stacks -- notice that they don't fully match. * Also notice that FRR's approach doesn't require the explicit definition of all subcommands, as we're passing this information to FRR's vtysh daemon. New debug/undebug stanzas now look like this: Quagga example ============== admin@lnos-x1-a-csw01:~$ debug ? Usage: debug [OPTIONS] COMMAND [ARGS]... SONiC command line - 'debug' command Options: -?, -h, --help Show this message and exit. Commands: bgp debug bgp events disable disable debugging for routing events enable enable debugging for routing events zebra debug bgp events admin@lnos-x1-a-csw01:~$ debug bgp ? Usage: debug bgp [OPTIONS] COMMAND [ARGS]... debug bgp events Options: -?, -h, --help Show this message and exit. Commands: as4 debug bgp AS4 actions events debug bgp events filters debug bgp filters fsm debug bgp fsm keepalives debug bgp keepalives updates debug bgp updates zebra debug bgp zebra messages admin@lnos-x1-a-csw01:~$ debug zebra ? Usage: debug zebra [OPTIONS] COMMAND [ARGS]... debug bgp events Options: -?, -h, --help Show this message and exit. Commands: events debug zebra events fpm debug zebra fpm events kernel debug zebra's kernel-interface events packet debug zebra packets rib debug zebra RIB events FRR example ============ admin@lnos-x1-a-csw02:~$ debug ? Usage: debug [OPTIONS] COMMAND [ARGS]... SONiC debugging commands for routing events Options: -?, -h, --help Show this message and exit. Commands: bgp Debug BGP information disable Disable debugging for routing events enable Enable debugging for routing events zebra Debug Zebra information admin@lnos-x1-a-csw02:~$ debug bgp ? Command: sudo vtysh -c "debug bgp ?" allow-martians BGP allow martian next hops as4 BGP AS4 actions bestpath BGP bestpath keepalives BGP keepalives neighbor-events BGP Neighbor Events nht BGP nexthop tracking events update-groups BGP update-groups updates BGP updates zebra BGP Zebra messages admin@lnos-x1-a-csw02:~$ debug zebra ? Command: sudo vtysh -c "debug zebra ?" events Debug option set for zebra events fpm Debug zebra FPM events kernel Debug option set for zebra between kernel interface mpls Debug option set for zebra MPLS LSPs nht Debug option set for zebra next hop tracking packet Debug option set for zebra packet pseudowires Debug option set for zebra pseudowires rib Debug RIB events UT's ==== admin@lnos-x1-a-csw02:~$ debug enable Command: sudo vtysh -c "configure terminal" -c "log syslog debugging" admin@lnos-x1-a-csw02:~$ debug bgp ? Command: sudo vtysh -c "debug bgp ?" allow-martians BGP allow martian next hops as4 BGP AS4 actions bestpath BGP bestpath keepalives BGP keepalives neighbor-events BGP Neighbor Events nht BGP nexthop tracking events update-groups BGP update-groups updates BGP updates zebra BGP Zebra messages admin@lnos-x1-a-csw02:~$ debug bgp keepalive Command: sudo vtysh -c "debug bgp keepalive" BGP keepalives debugging is on admin@lnos-x1-a-csw02:~$ sudo tail -f /var/log/syslog [ destination log file is as per /etc/rsyslog.d/00-sonic.conf ] ... May 9 23:51:48.525961 lnos-x1-a-csw02 DEBUG bgpd[65]: fc00:2:2::2 sending KEEPALIVE May 9 23:51:48.526019 lnos-x1-a-csw02 DEBUG bgpd[65]: 10.2.2.2 sending KEEPALIVE May 9 23:51:48.526054 lnos-x1-a-csw02 DEBUG bgpd[65]: fc00:2:2::2 KEEPALIVE rcvd May 9 23:51:48.526123 lnos-x1-a-csw02 DEBUG bgpd[65]: 10.2.2.2 KEEPALIVE rcvd ... admin@lnos-x1-a-csw02:~$ undebug bgp keepalive Command: sudo vtysh -c "no debug bgp keepalive" BGP keepalives debugging is off --- debug/debug_quagga.py | 100 ++++++++++++++++++++++++++++++++++++++ debug/main.py | 68 +++++++++++++++++--------- show/main.py | 42 ++++++---------- undebug/main.py | 59 ++++++++++++---------- undebug/undebug_quagga.py | 100 ++++++++++++++++++++++++++++++++++++++ 5 files changed, 296 insertions(+), 73 deletions(-) create mode 100644 debug/debug_quagga.py create mode 100644 undebug/undebug_quagga.py diff --git a/debug/debug_quagga.py b/debug/debug_quagga.py new file mode 100644 index 0000000000..189737f86b --- /dev/null +++ b/debug/debug_quagga.py @@ -0,0 +1,100 @@ +import click +from debug.main import * + + +############################################################################### +# +# 'debug bgp' cli stanza +# +############################################################################### + + +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def bgp(): + """debug bgp events """ + pass + +@bgp.command() +def as4(): + """debug bgp AS4 actions """ + command = 'sudo vtysh -c "debug bgp as4"' + run_command(command) + +@bgp.command() +def events(): + """debug bgp events """ + command = 'sudo vtysh -c "debug bgp events"' + run_command(command) + +@bgp.command() +def filters(): + """debug bgp filters """ + command = 'sudo vtysh -c "debug bgp filters"' + run_command(command) + +@bgp.command() +def fsm(): + """debug bgp fsm """ + command = 'sudo vtysh -c "debug bgp fsm"' + run_command(command) + +@bgp.command() +def keepalives(): + """debug bgp keepalives """ + command = 'sudo vtysh -c "debug bgp keepalives"' + run_command(command) + +@bgp.command() +def updates(): + """debug bgp updates """ + command = 'sudo vtysh -c "debug bgp updates"' + run_command(command) + +@bgp.command() +def zebra(): + """debug bgp zebra messages """ + command = 'sudo vtysh -c "debug bgp zebra"' + run_command(command) + + +############################################################################### +# +# 'debug zebra' cli stanza +# +############################################################################### + + +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def zebra(): + """debug zebra events """ + pass + +@zebra.command() +def events(): + """debug zebra events """ + command = 'sudo vtysh -c "debug zebra events"' + run_command(command) + +@zebra.command() +def fpm(): + """debug zebra fpm events """ + command = 'sudo vtysh -c "debug zebra fpm"' + run_command(command) + +@zebra.command() +def kernel(): + """debug zebra's kernel-interface events """ + command = 'sudo vtysh -c "debug zebra kernel"' + run_command(command) + +@zebra.command() +def packet(): + """debug zebra packets """ + command = 'sudo vtysh -c "debug zebra packet"' + run_command(command) + +@zebra.command() +def rib(): + """debug zebra RIB events """ + command = 'sudo vtysh -c "debug zebra rib"' + run_command(command) diff --git a/debug/main.py b/debug/main.py index 1b3a6dfc25..b0b3772b2d 100755 --- a/debug/main.py +++ b/debug/main.py @@ -5,6 +5,7 @@ import os import subprocess from click_default_group import DefaultGroup +from sonic_platform import get_system_routing_stack try: import ConfigParser as configparser @@ -99,34 +100,57 @@ def run_command(command, pager=False): @click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) def cli(): - """SONiC command line - 'debug' command""" + """SONiC debugging commands for routing events""" pass -# -# 'bgp' group ### -# - -@cli.group(cls=AliasedGroup, default_if_no_args=True) -def bgp(): - """debug bgp on """ - pass - -@bgp.command(default=True) -def default(): - command = 'sudo vtysh -c "debug bgp"' +@cli.command() +def enable(): + """Enable debugging for routing events """ + command = 'sudo vtysh -c "configure terminal" -c "log syslog debugging"' run_command(command) -@bgp.command() -def events(): - """debug bgp events on """ - command = 'sudo vtysh -c "debug bgp events"' +@cli.command() +def disable(): + """Disable debugging for routing events """ + command = 'sudo vtysh -c "configure terminal" -c "no log syslog debugging"' run_command(command) -@bgp.command() -def updates(): - """debug bgp events on """ - command = 'sudo vtysh -c "debug bgp updates"' - run_command(command) + +# +# Inserting 'debug' functionality into cli's parse-chain. Debugging commands are +# determined by the routing-stack being elected. +# +routing_stack = get_system_routing_stack() + +if routing_stack == "quagga": + + from .debug_quagga import bgp + cli.add_command(bgp) + from .debug_quagga import zebra + cli.add_command(zebra) + +elif routing_stack == "frr": + + @cli.command() + @click.argument('debug_args', nargs = -1, required = False) + def bgp(debug_args): + """Debug BGP information""" + debug_cmd = "debug bgp" + for arg in debug_args: + debug_cmd += " " + str(arg) + command = 'sudo vtysh -c "{}"'.format(debug_cmd) + run_command(command) + + @cli.command() + @click.argument('debug_args', nargs = -1, required = False) + def zebra(debug_args): + """Debug Zebra information""" + debug_cmd = "debug zebra" + for arg in debug_args: + debug_cmd += " " + str(arg) + command = 'sudo vtysh -c "{}"'.format(debug_cmd) + run_command(command) + if __name__ == '__main__': cli() diff --git a/show/main.py b/show/main.py index db3ba8a285..d1cc7df6ef 100755 --- a/show/main.py +++ b/show/main.py @@ -11,6 +11,7 @@ from natsort import natsorted from tabulate import tabulate from swsssdk import ConfigDBConnector +from sonic_platform import get_system_routing_stack try: # noinspection PyPep8Naming @@ -87,31 +88,6 @@ def get_command(self, ctx, cmd_name): ctx.fail('Too many matches: %s' % ', '.join(sorted(matches))) -# To be enhanced. Routing-stack information should be collected from a global -# location (configdb?), so that we prevent the continous execution of this -# bash oneliner. To be revisited once routing-stack info is tracked somewhere. -def get_routing_stack(): - command = "sudo docker ps | grep bgp | awk '{print$2}' | cut -d'-' -f3 | cut -d':' -f1" - - try: - proc = subprocess.Popen(command, - stdout=subprocess.PIPE, - shell=True, - stderr=subprocess.STDOUT) - stdout = proc.communicate()[0] - proc.wait() - result = stdout.rstrip('\n') - - except OSError, e: - raise OSError("Cannot detect routing-stack") - - return (result) - - -# Global Routing-Stack variable -routing_stack = get_routing_stack() - - def run_command(command, display_cmd=False): if display_cmd: click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green')) @@ -489,12 +465,17 @@ def protocol(verbose): # Inserting BGP functionality into cli's show parse-chain. # BGP commands are determined by the routing-stack being elected. # +routing_stack = get_system_routing_stack() + if routing_stack == "quagga": + from .bgp_quagga_v4 import bgp ip.add_command(bgp) from .bgp_quagga_v6 import bgp ipv6.add_command(bgp) + elif routing_stack == "frr": + @cli.command() @click.argument('bgp_args', nargs = -1, required = False) @click.option('--verbose', is_flag=True, help="Enable verbose output") @@ -506,6 +487,15 @@ def bgp(bgp_args, verbose): cmd = 'sudo vtysh -c "{}"'.format(bgp_cmd) run_command(cmd, display_cmd=verbose) + @cli.command() + @click.argument('debug_args', nargs = -1, required = False) + def debug(debug_args): + """Show debuggging configuration state""" + debug_cmd = "show debugging" + for arg in debug_args: + debug_cmd += " " + str(arg) + command = 'sudo vtysh -c "{}"'.format(debug_cmd) + run_command(command) # # 'lldp' group ("show lldp ...") @@ -692,7 +682,7 @@ def cpu(verbose): # Run top in batch mode to prevent unexpected newline after each newline cmd = "top -bn 1 -o %CPU" run_command(cmd, display_cmd=verbose) - + # 'memory' subcommand @processes.command() @click.option('--verbose', is_flag=True, help="Enable verbose output") diff --git a/undebug/main.py b/undebug/main.py index 0203d10d22..2c1a8cac81 100644 --- a/undebug/main.py +++ b/undebug/main.py @@ -2,6 +2,7 @@ import os import subprocess from click_default_group import DefaultGroup +from sonic_platform import get_system_routing_stack try: import ConfigParser as configparser @@ -96,36 +97,44 @@ def run_command(command, pager=False): @click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS) def cli(): - """SONiC command line - 'undebug' command""" + """SONiC undebugging commands for routing events""" pass - # -# 'bgp' group ### +# Inserting 'undebug' functionality into cli's parse-chain. Undebugging commands +# are determined by the routing-stack being elected. # +routing_stack = get_system_routing_stack() + +if routing_stack == "quagga": + + from .undebug_quagga import bgp + cli.add_command(bgp) + from .undebug_quagga import zebra + cli.add_command(zebra) + +elif routing_stack == "frr": + + @cli.command() + @click.argument('debug_args', nargs = -1, required = False) + def bgp(debug_args): + """Debug BGP information""" + debug_cmd = "no debug bgp" + for arg in debug_args: + debug_cmd += " " + str(arg) + command = 'sudo vtysh -c "{}"'.format(debug_cmd) + run_command(command) + + @cli.command() + @click.argument('debug_args', nargs = -1, required = False) + def zebra(debug_args): + """Debug Zebra information""" + debug_cmd = "no debug zebra" + for arg in debug_args: + debug_cmd += " " + str(arg) + command = 'sudo vtysh -c "{}"'.format(debug_cmd) + run_command(command) -# This allows us to add commands to both cli and ip groups, allowing for -@cli.group(cls=AliasedGroup, default_if_no_args=True) -def bgp(): - """undebug bgp on """ - pass - -@bgp.command(default=True) -def default(): - command = 'sudo vtysh -c "undebug bgp"' - run_command(command) - -@bgp.command() -def events(): - """undebug bgp events on """ - command = 'sudo vtysh -c "undebug bgp events"' - run_command(command) - -@bgp.command() -def updates(): - """undebug bgp events on """ - command = 'sudo vtysh -c "undebug bgp updates"' - run_command(command) if __name__ == '__main__': cli() diff --git a/undebug/undebug_quagga.py b/undebug/undebug_quagga.py new file mode 100644 index 0000000000..9a0d703867 --- /dev/null +++ b/undebug/undebug_quagga.py @@ -0,0 +1,100 @@ +import click +from undebug.main import * + + +############################################################################### +# +# 'undebug bgp' cli stanza +# +############################################################################### + + +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def bgp(): + """undebug bgp events """ + pass + +@bgp.command() +def as4(): + """undebug bgp AS4 actions """ + command = 'sudo vtysh -c "no debug bgp as4"' + run_command(command) + +@bgp.command() +def events(): + """undebug bgp events """ + command = 'sudo vtysh -c "no debug bgp events"' + run_command(command) + +@bgp.command() +def filters(): + """undebug bgp filters """ + command = 'sudo vtysh -c "no debug bgp filters"' + run_command(command) + +@bgp.command() +def fsm(): + """undebug bgp fsm """ + command = 'sudo vtysh -c "no debug bgp fsm"' + run_command(command) + +@bgp.command() +def keepalives(): + """undebug bgp keepalives """ + command = 'sudo vtysh -c "no debug bgp keepalives"' + run_command(command) + +@bgp.command() +def updates(): + """undebug bgp updates """ + command = 'sudo vtysh -c "no debug bgp updates"' + run_command(command) + +@bgp.command() +def zebra(): + """undebug bgp zebra messages """ + command = 'sudo vtysh -c "no debug bgp zebra"' + run_command(command) + + +############################################################################### +# +# 'undebug zebra' cli stanza +# +############################################################################### + + +@cli.group(cls=AliasedGroup, default_if_no_args=False) +def zebra(): + """undebug zebra events """ + pass + +@zebra.command() +def events(): + """undebug zebra events """ + command = 'sudo vtysh -c "no debug zebra events"' + run_command(command) + +@zebra.command() +def fpm(): + """undebug zebra fpm events """ + command = 'sudo vtysh -c "no debug zebra fpm"' + run_command(command) + +@zebra.command() +def kernel(): + """undebug zebra's kernel-interface events """ + command = 'sudo vtysh -c "no debug zebra kernel"' + run_command(command) + +@zebra.command() +def packet(): + """undebug zebra packets """ + command = 'sudo vtysh -c "no debug zebra packet"' + run_command(command) + +@zebra.command() +def rib(): + """undebug zebra RIB events """ + command = 'sudo vtysh -c "no debug zebra rib"' + run_command(command)