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

Broadcast Unknown-multicast and Unknown-unicast Storm-control #928

Merged
merged 39 commits into from
May 18, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
46a0f9a
CLICK CLI - Configuration and show commands for BUM Storm-control fea…
mohan-selvaraj Jun 1, 2020
c5385d5
Merge branch 'master' of https:/Azure/sonic-utilities int…
mohan-selvaraj Nov 2, 2021
6be166a
Merge branch 'Azure-master' into storm_control
mohan-selvaraj Nov 2, 2021
a073d93
Update parameters to interface_alias_to_name and interface_name_is_va…
mohan-selvaraj Nov 2, 2021
37b41f0
addressed review comments.
mohan-selvaraj Nov 3, 2021
f5b354e
utilities test code for storm-control
mohan-selvaraj Nov 9, 2021
55768bd
mohan-selvaraj Nov 9, 2021
7542172
mohan-selvaraj Nov 9, 2021
4c9945f
Merge branch 'Azure:master' into storm_control
mohan-selvaraj Nov 15, 2021
8147999
Merge branch 'master' into storm_control
mohan-selvaraj Nov 17, 2021
91e70f5
mohan-selvaraj Nov 23, 2021
e6aec85
Merge branch 'storm_control' of https:/mohan-selvaraj/son…
mohan-selvaraj Nov 23, 2021
5194411
Modified storm-control configuration commands to
mohan-selvaraj Nov 23, 2021
6297b03
Merge branch 'Azure:master' into storm_control
mohan-selvaraj Nov 24, 2021
90d6f5f
Merge branch 'master' into storm_control
mohan-selvaraj Nov 24, 2021
12d7ce6
Merge branch 'storm_control' of https:/mohan-selvaraj/son…
mohan-selvaraj Nov 24, 2021
61e2107
modified storm-control show commands
mohan-selvaraj Nov 24, 2021
30c6fa7
mohan-selvaraj Nov 24, 2021
0e3fbd2
Merge branch 'Azure:master' into storm_control
mohan-selvaraj Nov 26, 2021
779ab88
support for capability check before proceeding with updating CONFIG_D…
mohan-selvaraj Nov 30, 2021
46433b8
Merge branch 'Azure:master' into storm_control
mohan-selvaraj Nov 30, 2021
7c850c8
mohan-selvaraj Nov 30, 2021
44996b7
Merge branch 'storm_control' of https:/mohan-selvaraj/son…
mohan-selvaraj Nov 30, 2021
f1996c5
mohan-selvaraj Nov 30, 2021
60dc372
mohan-selvaraj Dec 1, 2021
df63165
mohan-selvaraj Dec 1, 2021
e250b6a
Merge branch 'Azure:master' into storm_control
mohan-selvaraj Dec 1, 2021
d5c7f15
Merge branch 'master' into storm_control
mohan-selvaraj Dec 23, 2021
4c0e8ba
Merge branch 'Azure:master' into storm_control
mohan-selvaraj Apr 11, 2022
991210c
Merge branch 'Azure:master' into storm_control
mohan-selvaraj May 5, 2022
1ed0c15
Merge branch 'master' into storm_control
mohan-selvaraj May 5, 2022
93c01c3
Merge branch 'storm_control' of https:/mohan-selvaraj/son…
mohan-selvaraj May 5, 2022
d288b08
storm-control config/show test code
mohan-selvaraj May 5, 2022
9a85aad
mohan-selvaraj May 5, 2022
5b63779
mohan-selvaraj May 5, 2022
f1bb1cb
mohan-selvaraj May 5, 2022
e4389e5
mohan-selvaraj May 5, 2022
afe1122
Merge branch 'master' into storm_control
mohan-selvaraj May 9, 2022
f2c32ca
Merge branch 'Azure:master' into storm_control
mohan-selvaraj May 11, 2022
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
150 changes: 150 additions & 0 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,72 @@ def _change_hostname(hostname):
run_command('sed -i "/\s{}$/d" /etc/hosts'.format(current_hostname), display_cmd=True)
run_command('echo "127.0.0.1 {}" >> /etc/hosts'.format(hostname), display_cmd=True)

def storm_control_interface_validate(port_name):
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
if get_interface_naming_mode() == "alias":
port_name = interface_alias_to_name(port_name)
if port_name is None:
click.echo("'port_name' is None!")
return False

if (port_name.startswith("Ethernet")):
if interface_name_is_valid(port_name) is False:
click.echo("Interface name %s is invalid. Please enter a valid interface name" %(port_name))
return False
else:
click.echo("Storm-control is supported only on Ethernet interfaces. Not supported on %s" %(port_name))
return False

return True

def storm_control_bps_validate(bps):
# if bps not in range(0,100000000001):
# click.echo("bps value must be in range 0-100000000000")
# return False
return True
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

def storm_control_set_entry(port_name, kbps, storm_type):
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_interface_validate(port_name) is False:
return False

if storm_control_bps_validate(kbps) is False:
return False
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

config_db = ConfigDBConnector()
config_db.connect()
key = port_name + '|' + storm_type
entry = config_db.get_entry('PORT_STORM_CONTROL',key)
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if len(entry) == 0:
config_db.set_entry('PORT_STORM_CONTROL', key, {'kbps':kbps})
else:
kbps_value = int(entry.get('kbps',0))
click.echo("Existing value of bps %d"%(kbps_value))
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
if kbps_value != kbps:
config_db.mod_entry('PORT_STORM_CONTROL',key,{'kbps':kbps})
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

return True

def storm_control_delete_entry(port_name, storm_type):
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_interface_validate(port_name) is False:
return False

config_db = ConfigDBConnector()
config_db.connect()
key = port_name + '|' + storm_type
entry = config_db.get_entry('PORT_STORM_CONTROL',key)
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if len(entry) == 0:
click.echo("%s storm-control not enabled on interface %s"%(storm_type, port_name))
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
return False
else:
config_db.set_entry('PORT_STORM_CONTROL',key,None)
click.echo("deleted %s storm-control from interface %s"%(storm_type, port_name))
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

return True


def _clear_qos():
QOS_TABLE_NAMES = [
'TC_TO_PRIORITY_GROUP_MAP',
Expand Down Expand Up @@ -1410,6 +1476,90 @@ def naming_mode_alias():
"""Set CLI interface naming mode to ALIAS (Vendor port alias)"""
set_interface_naming_mode('alias')

@interface.group('storm-control')
@click.pass_context
def storm_control(ctx):
""" Configure storm-control"""
pass

@storm_control.group('broadcast')
def broadcast():
""" Configure broadcast storm-control"""
pass

@broadcast.command('add')
@click.argument('port_name',metavar='<port_name>', required=True)
@click.argument('kbps',metavar='<kbps_value>', required=True, type=click.IntRange(0,100000000))
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
@click.pass_context
def add_broadcast_storm(ctx,port_name,kbps):
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
print"add broadcast storm-control"
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_set_entry(port_name, kbps, 'broadcast') is False:
ctx.fail("Unable to add broadcast storm-control")

@broadcast.command('del')
@click.argument('port_name',metavar='<port_name>', required=True)
#@click.argument('bps',metavar='<bps_value>', required=True, type=int)
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
@click.pass_context
#def del_broadcast_storm(ctx,port_name,bps):
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
def del_broadcast_storm(ctx,port_name):
print"del broadcast storm-control"
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_delete_entry(port_name, 'broadcast') is False:
ctx.fail("Unable to delete broadcast storm-control")

@storm_control.group('unknown-unicast')
def unknown_unicast():
""" Configure unknown-unicast storm-control"""
pass

@unknown_unicast.command('add')
@click.argument('port_name',metavar='<port_name>', required=True)
@click.argument('kbps',metavar='<kbps_value>', required=True, type=click.IntRange(0,100000000))
@click.pass_context
def add_unknown_unicast_storm(ctx,port_name,kbps):
print"add unknown-unicast storm-control"
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_set_entry(port_name, kbps, 'unknown-unicast') is False:
ctx.fail("Unable to add unknown-unicast storm-control")

@unknown_unicast.command('del')
@click.argument('port_name',metavar='<port_name>', required=True)
#@click.argument('bps',metavar='<bps_value>', required=True, type=int)
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
@click.pass_context
#def del_unknown_unicast_storm(ctx,port_name,bps):
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
def del_unknown_unicast_storm(ctx,port_name):
print"del unknown-unicast storm-control"
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_delete_entry(port_name, 'unknown-unicast') is False:
ctx.fail("Unable to delete unknown-unicast storm-control")

@storm_control.group('unknown-multicast')
def unknown_multicast():
""" Configure unknown-multicast storm-control"""
pass

@unknown_multicast.command('add')
@click.argument('port_name',metavar='<port_name>', required=True)
@click.argument('kbps',metavar='<kbps_value>', required=True, type=click.IntRange(0,100000000))
@click.pass_context
def add_unknown_multicast_storm(ctx,port_name,kbps):
print"add unknown-multicast storm-control"
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_set_entry(port_name, kbps, 'unknown-multicast') is False:
ctx.fail("Unable to add unknown-multicast storm-control")

@unknown_multicast.command('del')
@click.argument('port_name',metavar='<port_name>', required=True)
#@click.argument('bps',metavar='<bps_value>', required=True, type=int)
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
@click.pass_context
#def del_unknown_multicast_storm(ctx,port_name,bps):
def del_unknown_multicast_storm(ctx,port_name):
print"del unknown-multicast storm-control"
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

if storm_control_delete_entry(port_name, 'unknown-multicast') is False:
ctx.fail("Unable to delete unknown-multicast storm-control")

#
# 'syslog' group ('config syslog ...')
#
Expand Down
66 changes: 66 additions & 0 deletions show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,72 @@ def alias(interfacename):

click.echo(tabulate(body, header))

@cli.group('storm-control')
def storm_control():
""" show storm-control """
pass
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
@storm_control.command('all')
def storm_control_all():
""" Show storm-control """
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

header = ['Interface Name', 'Storm Type', 'Rate (kbps)']
body = []

config_db = ConfigDBConnector()
config_db.connect()

table = config_db.get_table('PORT_STORM_CONTROL')

#To avoid further looping below
if not table:
return
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

sorted_table = natsorted(table)

for storm_key in sorted_table:
interface_name = storm_key[0]
storm_type = storm_key[1]
#interface_name, storm_type = storm_key.split(':')
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved
data = config_db.get_entry('PORT_STORM_CONTROL', storm_key)

if not data:
return

kbps = data['kbps']

body.append([interface_name, storm_type, kbps])
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

click.echo(tabulate(body, header, tablefmt="grid"))

@storm_control.command('interface')
@click.argument('interfacename', required=True)
def storm_control_interface(interfacename):
""" Show storm-control """
mohan-selvaraj marked this conversation as resolved.
Show resolved Hide resolved

storm_type_list = ['broadcast','unknown-unicast','unknown-multicast']

header = ['Interface Name', 'Storm Type', 'Rate (kbps)']
body = []

config_db = ConfigDBConnector()
config_db.connect()

table = config_db.get_table('PORT_STORM_CONTROL')

#To avoid further looping below
if not table:
return

for storm_type in storm_type_list:
storm_key = interfacename + '|' + storm_type
data = config_db.get_entry('PORT_STORM_CONTROL', storm_key)

if data:
kbps = data['kbps']
body.append([interfacename, storm_type, kbps])

click.echo(tabulate(body, header, tablefmt="grid"))

#
# 'neighbor' group ###
#
Expand Down