Skip to content

Fixed 'show ip route' command: ipv6 -> ipv4. #179

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

Open
wants to merge 22 commits into
base: 201709
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
51fc8ee
[FastReboot]: Update FR to make it working with 1.0.3 (#95)
pavel-shirshov Aug 14, 2017
a7be3b7
Merge remote-tracking branch 'origin/v1.0.3'
Sep 15, 2017
b48573f
Adapt to new minigraph_parser schema (#103)
taoyl-ms Sep 19, 2017
85dd072
Added syncd SAI dump to sysdump script (#89)
Sep 19, 2017
cdf2fe6
[generate_dump]: Skip the sparse file /var/log/lastlog (#104)
Sep 20, 2017
0338eee
Add 'ipv6' group along with 'bgp' and 'route' subcommands; Remove dup…
jleveque Sep 20, 2017
70422b5
[show]: Add 'show interfaces alias' command to display port name/alia…
jleveque Sep 27, 2017
206aabe
CLI support for Layer 2 MAC/FDB show (#106)
prsunny Sep 27, 2017
4b036b9
Fixed parser logic to handle non mandatory TLV.
Sep 28, 2017
63f05ad
Enhancement of 'show' commands and addition of 'debug', and 'undebug'…
samaity Oct 2, 2017
b27d4f9
Flush DB first when loading from minigraph (#114)
taoyl-ms Oct 3, 2017
2c63a41
Reorder dependencies to fix wheel build (#117)
jleveque Oct 4, 2017
ddadc2b
[show]: Fix improper indents (#119)
jleveque Oct 5, 2017
635735d
[lldpshow]: Fixed parser logic to handle non mandatory TLV (#110)
Oct 5, 2017
52dd13e
[show]: Remove default commands; add missing docstrings (#121)
jleveque Oct 5, 2017
2dab9da
[config load_mgmt_config] add default route (#123)
taoyl-ms Oct 6, 2017
3a40ff9
[sonic-installer] Fix an issue that old config is not preserved in ab…
taoyl-ms Oct 6, 2017
77c9f81
Remove explicit dependency on swsssdk (#124)
jleveque Oct 6, 2017
991ff2d
Merge pull request #2 from nazarii-gnydyn/201709-lldpshow-parser-fix
Oct 31, 2017
2ca13e2
Merge remote-tracking branch 'upstream/201709' into 201709
Nov 30, 2017
eeb840f
Merge remote-tracking branch 'origin/master-201709-update' into 20170…
Dec 19, 2017
9d0280e
Fixed 'show ip route' command: ipv6 -> ipv4.
Dec 20, 2017
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
27 changes: 26 additions & 1 deletion config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,20 @@ def load(filename):
command = "{} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, filename)
run_command(command, display_cmd=True)

@cli.command()
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false,
expose_value=False, prompt='Clear current and reload all config?')
@click.argument('filename', default='/etc/sonic/config_db.json', type=click.Path(exists=True))
def reload(filename):
"""Clear current configuration and import a previous saved config DB dump file."""
config_db = ConfigDBConnector()
config_db.connect()
client = config_db.redis_clients[config_db.CONFIG_DB]
client.flushdb()
command = "{} -j {} --write-to-db".format(SONIC_CFGGEN_PATH, filename)
run_command(command, display_cmd=True)
client.set(config_db.INIT_INDICATOR, True)

@cli.command()
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false,
expose_value=False, prompt='Reload mgmt config?')
Expand All @@ -131,18 +145,29 @@ def load_mgmt_config(filename):
hostname = config_data['DEVICE_METADATA']['localhost']['hostname']
_change_hostname(hostname)
mgmt_conf = netaddr.IPNetwork(config_data['MGMT_INTERFACE'].keys()[0][1])
gw_addr = config_data['MGMT_INTERFACE'].values()[0]['gwaddr']
command = "ifconfig eth0 {} netmask {}".format(str(mgmt_conf.ip), str(mgmt_conf.netmask))
run_command(command, display_cmd=True)
command = "ip route add default via {} dev eth0 table default".format(gw_addr)
run_command(command, display_cmd=True)
command = "ip rule add from {} table default".format(str(mgmt_conf.ip))
run_command(command, display_cmd=True)
command = "[ -f /var/run/dhclient.eth0.pid ] && kill `cat /var/run/dhclient.eth0.pid` && rm -f /var/run/dhclient.eth0.pid"
run_command(command, display_cmd=True)
print "Please note loaded setting will be lost after system reboot. To preserve setting, run `config save`."

@cli.command()
@click.option('-y', '--yes', is_flag=True, callback=_abort_if_false,
expose_value=False, prompt='Reload config from minigraph?')
def load_minigraph():
"""Reconfigure based on minigraph."""
config_db = ConfigDBConnector()
config_db.connect()
client = config_db.redis_clients[config_db.CONFIG_DB]
client.flushdb()
command = "{} -m --write-to-db".format(SONIC_CFGGEN_PATH)
run_command(command, display_cmd=True)
client.set(config_db.INIT_INDICATOR, True)
command = "{} -m -v \"DEVICE_METADATA['localhost']['hostname']\"".format(SONIC_CFGGEN_PATH)
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
p.wait()
Expand All @@ -159,7 +184,7 @@ def load_minigraph():
run_command("service lldp restart", display_cmd=True)
run_command("service snmp restart", display_cmd=True)
run_command("service dhcp_relay restart", display_cmd=True)

print "Please note setting loaded from minigraph will be lost after system reboot. To preserve setting, run `config save`."
#
# 'bgp' group
#
Expand Down
8 changes: 8 additions & 0 deletions data/etc/bash_completion.d/debug
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_debug_completion() {
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_DEBUG_COMPLETE=complete $1 ) )
return 0
}

complete -F _debug_completion -o default debug;
8 changes: 8 additions & 0 deletions data/etc/bash_completion.d/undebug
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
_undebug_completion() {
COMPREPLY=( $( env COMP_WORDS="${COMP_WORDS[*]}" \
COMP_CWORD=$COMP_CWORD \
_UNDEBUG_COMPLETE=complete $1 ) )
return 0
}

complete -F _undebug_completion -o default undebug;
Empty file added debug/__init__.py
Empty file.
5 changes: 5 additions & 0 deletions debug/aliases.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[aliases]
running-configuration=runningconfiguration
running-config=runningconfiguration
startup-configuration=startupconfiguration
startup-config=startupconfiguration
132 changes: 132 additions & 0 deletions debug/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
#! /usr/bin/python -u
# date: 07/12/17

import click
import os
import subprocess
from click_default_group import DefaultGroup

try:
import ConfigParser as configparser
except ImportError:
import configparser


# This is from the aliases example:
# https://github.com/pallets/click/blob/57c6f09611fc47ca80db0bd010f05998b3c0aa95/examples/aliases/aliases.py
class Config(object):
"""Object to hold CLI config"""

def __init__(self):
self.path = os.getcwd()
self.aliases = {}

def read_config(self, filename):
parser = configparser.RawConfigParser()
parser.read([filename])
try:
self.aliases.update(parser.items('aliases'))
except configparser.NoSectionError:
pass


# Global Config object
_config = None


# This aliased group has been modified from click examples to inherit from DefaultGroup instead of click.Group.
# DefaultFroup is a superclass of click.Group which calls a default subcommand instead of showing
# a help message if no subcommand is passed
class AliasedGroup(DefaultGroup):
"""This subclass of a DefaultGroup supports looking up aliases in a config
file and with a bit of magic.
"""

def get_command(self, ctx, cmd_name):
global _config

# If we haven't instantiated our global config, do it now and load current config
if _config is None:
_config = Config()

# Load our config file
cfg_file = os.path.join(os.path.dirname(__file__), 'aliases.ini')
_config.read_config(cfg_file)

# Try to get builtin commands as normal
rv = click.Group.get_command(self, ctx, cmd_name)
if rv is not None:
return rv

# No builtin found. Look up an explicit command alias in the config
if cmd_name in _config.aliases:
actual_cmd = _config.aliases[cmd_name]
return click.Group.get_command(self, ctx, actual_cmd)

# Alternative option: if we did not find an explicit alias we
# allow automatic abbreviation of the command. "status" for
# instance will match "st". We only allow that however if
# there is only one command.
matches = [x for x in self.list_commands(ctx)
if x.lower().startswith(cmd_name.lower())]
if not matches:
# No command name matched. Issue Default command.
ctx.arg0 = cmd_name
cmd_name = self.default_cmd_name
return DefaultGroup.get_command(self, ctx, cmd_name)
elif len(matches) == 1:
return DefaultGroup.get_command(self, ctx, matches[0])
ctx.fail('Too many matches: %s' % ', '.join(sorted(matches)))


def run_command(command, pager=False):
if pager is True:
click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green'))
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
click.echo_via_pager(p.stdout.read())
else:
click.echo(click.style("Command: ", fg='cyan') + click.style(command, fg='green'))
p = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
click.echo(p.stdout.read())


CONTEXT_SETTINGS = dict(help_option_names=['-h', '--help', '-?'])


#
# 'cli' group (root group) ###
#

@click.group(cls=AliasedGroup, context_settings=CONTEXT_SETTINGS)
def cli():
"""SONiC command line - 'debug' command"""
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"'
run_command(command)

@bgp.command()
def events():
"""debug bgp events on """
command = 'sudo vtysh -c "debug bgp events"'
run_command(command)

@bgp.command()
def updates():
"""debug bgp events on """
command = 'sudo vtysh -c "debug bgp updates"'
run_command(command)

if __name__ == '__main__':
cli()
66 changes: 54 additions & 12 deletions scripts/fast-reboot-dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from pprint import pprint


def generate_arp_entries(filename):
def generate_arp_entries(filename, all_available_macs):
db = swsssdk.SonicV2Connector()
db.connect(db.APPL_DB, False) # Make one attempt only

Expand All @@ -15,9 +15,13 @@ def generate_arp_entries(filename):
keys = db.keys(db.APPL_DB, 'NEIGH_TABLE:*')
keys = [] if keys is None else keys
for key in keys:
entry = db.get_all(db.APPL_DB, key)
if entry['neigh'].lower() not in all_available_macs:
# print me to log
continue
obj = {
'OP': 'SET',
key: db.get_all(db.APPL_DB, key)
key: entry,
'OP': 'SET'
}
arp_output.append(obj)

Expand Down Expand Up @@ -49,24 +53,56 @@ def get_vlan_ifaces():

return vlans

def get_bridge_port_id_2_port_id(db):
bridge_port_id_2_port_id = {}
keys = db.keys(db.ASIC_DB, 'ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:*')
keys = [] if keys is None else keys
for key in keys:
value = db.get_all(db.ASIC_DB, key)
port_type = value['SAI_BRIDGE_PORT_ATTR_TYPE']
if port_type != 'SAI_BRIDGE_PORT_TYPE_PORT':
continue
port_id = value['SAI_BRIDGE_PORT_ATTR_PORT_ID']
# ignore admin status
bridge_id = key.replace('ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:', '')
bridge_port_id_2_port_id[bridge_id] = port_id

return bridge_port_id_2_port_id

def get_map_port_id_2_iface_name(db):
port_id_2_iface = {}
keys = db.keys(db.ASIC_DB, 'ASIC_STATE:SAI_OBJECT_TYPE_HOSTIF:oid:*')
keys = [] if keys is None else keys
for key in keys:
value = db.get_all(db.ASIC_DB, key)
port_id = value['SAI_HOSTIF_ATTR_RIF_OR_PORT_ID']
port_id = value['SAI_HOSTIF_ATTR_OBJ_ID']
iface_name = value['SAI_HOSTIF_ATTR_NAME']
port_id_2_iface[port_id] = iface_name

return port_id_2_iface

def get_fdb(db, vlan_id, port_id_2_iface):
def get_map_bridge_port_id_2_iface_name(db):
bridge_port_id_2_port_id = get_bridge_port_id_2_port_id(db)
port_id_2_iface = get_map_port_id_2_iface_name(db)

bridge_port_id_2_iface_name = {}

for bridge_port_id, port_id in bridge_port_id_2_port_id.items():
if port_id in port_id_2_iface:
bridge_port_id_2_iface_name[bridge_port_id] = port_id_2_iface[port_id]
else:
print "Not found"

return bridge_port_id_2_iface_name

def get_fdb(db, vlan_id, bridge_id_2_iface):
fdb_types = {
'SAI_FDB_ENTRY_TYPE_DYNAMIC': 'dynamic',
'SAI_FDB_ENTRY_TYPE_STATIC' : 'static'
}

available_macs = set()

entries = []
keys = db.keys(db.ASIC_DB, 'ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{*\"vlan\":\"%d\"}' % vlan_id)
keys = [] if keys is None else keys
Expand All @@ -76,12 +112,15 @@ def get_fdb(db, vlan_id, port_id_2_iface):
mac = str(key_obj['mac'])
if not is_mac_unicast(mac):
continue
available_macs.add(mac.lower())
mac = mac.replace(':', '-')
# FIXME: mac is unicast
# get attributes
value = db.get_all(db.ASIC_DB, key)
type = fdb_types[value['SAI_FDB_ENTRY_ATTR_TYPE']]
port = port_id_2_iface[value['SAI_FDB_ENTRY_ATTR_PORT_ID']]
if value['SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID'] not in bridge_id_2_iface:
continue
port = bridge_id_2_iface[value['SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID']]

obj = {
'FDB_TABLE:Vlan%d:%s' % (vlan_id, mac) : {
Expand All @@ -93,7 +132,7 @@ def get_fdb(db, vlan_id, port_id_2_iface):

entries.append(obj)

return entries
return entries, available_macs


def generate_fdb_entries(filename):
Expand All @@ -102,24 +141,27 @@ def generate_fdb_entries(filename):
db = swsssdk.SonicV2Connector()
db.connect(db.ASIC_DB, False) # Make one attempt only

port_id_2_iface = get_map_port_id_2_iface_name(db)
bridge_id_2_iface = get_map_bridge_port_id_2_iface_name(db)

vlan_ifaces = get_vlan_ifaces()

all_available_macs = set()
for vlan in vlan_ifaces:
vlan_id = int(vlan.replace('Vlan', ''))
fdb_entries.extend(get_fdb(db, vlan_id, port_id_2_iface))
fdb_entry, available_macs = get_fdb(db, vlan_id, bridge_id_2_iface)
all_available_macs |= available_macs
fdb_entries.extend(fdb_entry)

db.close(db.ASIC_DB)

with open(filename, 'w') as fp:
json.dump(fdb_entries, fp, indent=2, separators=(',', ': '))

return
return all_available_macs

def main():
generate_arp_entries('/tmp/arp.json')
generate_fdb_entries('/tmp/fdb.json')
all_available_macs = generate_fdb_entries('/tmp/fdb.json')
generate_arp_entries('/tmp/arp.json', all_available_macs)

return

Expand Down
Loading