Skip to content
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
26 changes: 26 additions & 0 deletions clear/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from config.plugins.pbh import serialize_pbh_counters
from . import plugins
from . import stp

# This is from the aliases example:
# https://github.com/pallets/click/blob/57c6f09611fc47ca80db0bd010f05998b3c0aa95/examples/aliases/aliases.py
class Config(object):
Expand Down Expand Up @@ -149,6 +150,31 @@ def ipv6():
#
cli.add_command(stp.spanning_tree)


# 'LLR'
#
@cli.group(cls=clicommon.AliasedGroup)
def llr():
"""Clear LLR (Link Layer Retry) counters"""
pass


@llr.group(name='counters', invoke_without_command=True, cls=clicommon.AliasedGroup)
@click.pass_context
def llr_counters(ctx):
"""Clear LLR counter statistics (all ports)"""
if ctx.invoked_subcommand is None:
command = ["llrstat", "-c"]
run_command(command)


@llr_counters.command(name='interface')
@click.argument('interface_name', metavar='<interface-name>')
def llr_counters_interface(interface_name):
"""Clear LLR counter statistics for a specific interface"""
command = ["llrstat", "-c", "-i", str(interface_name)]
run_command(command)

#
# Inserting BGP functionality into cli's clear parse-chain.
# BGP commands are determined by the routing-stack being elected.
Expand Down
111 changes: 111 additions & 0 deletions config/llr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
import click
import utilities_common.cli as clicommon
from swsscommon.swsscommon import SonicV2Connector

LLR_CAPABLE_KEY = "SWITCH_CAPABILITY|switch"
LLR_CAPABLE_FIELD = "LLR_CAPABLE"


def _check_llr_capability():
"""
Check STATE_DB SWITCH_CAPABILITY|switch for LLR_CAPABLE == "true".
Returns True if supported, False otherwise.
"""
state_db = SonicV2Connector(host="127.0.0.1")
state_db.connect(state_db.STATE_DB)
val = state_db.get(state_db.STATE_DB, LLR_CAPABLE_KEY, LLR_CAPABLE_FIELD)
return val == "true"


def _validate_port_exists(db, interface_name):
"""
Validate that the given interface exists in PORT table of CONFIG_DB.
Returns True if the port exists, False otherwise.
"""
entry = db.get_entry("PORT", interface_name)
return len(entry) > 0


def _validate_llr_static_mode(cfgdb, interface_name, command_name):
"""
Common validation for local/remote commands
"""
if not _check_llr_capability():
click.echo("Error: LLR is not supported on this platform.")
raise SystemExit(1)

if not _validate_port_exists(cfgdb, interface_name):
click.echo("Error: Interface {} does not exist.".format(interface_name))
raise SystemExit(1)

entry = cfgdb.get_entry("LLR_PORT", interface_name)
mode = entry.get("llr_mode", "static")
if mode != "static":
click.echo("Error: 'config llr interface {}' is only applicable "
"when llr_mode is 'static' (current mode: '{}').".format(
command_name, mode))
raise SystemExit(1)


##############################################################################
# 'llr' group ("config llr ...")
##############################################################################

@click.group(cls=clicommon.AliasedGroup)
@click.pass_context
def llr(ctx):
"""Configure LLR (Link Layer Retry)"""
pass


##############################################################################
# 'config llr interface ...'
##############################################################################

@llr.group(name='interface', cls=clicommon.AliasedGroup)
@click.pass_context
def llr_interface(ctx):
"""Configure LLR on a per-port basis"""
pass


@llr_interface.command(name='mode')
@click.argument('interface_name', metavar='<interface-name>')
@click.argument('llr_mode', metavar='<static>', type=click.Choice(['static']))
@click.pass_context
def llr_interface_mode(ctx, interface_name, llr_mode):
"""Configure LLR mode on an interface"""
if not _check_llr_capability():
click.echo("Error: LLR is not supported on this platform.")
raise SystemExit(1)

cfgdb = ctx.obj.cfgdb
if not _validate_port_exists(cfgdb, interface_name):
click.echo("Error: Interface {} does not exist.".format(interface_name))
raise SystemExit(1)

cfgdb.mod_entry("LLR_PORT", interface_name, {"llr_mode": llr_mode})


@llr_interface.command(name='local')
@click.argument('interface_name', metavar='<interface-name>')
@click.argument('state', metavar='{enabled|disabled}',
type=click.Choice(['enabled', 'disabled']))
@click.pass_context
def llr_interface_local(ctx, interface_name, state):
"""Enable/disable LLR local on an interface"""
cfgdb = ctx.obj.cfgdb
_validate_llr_static_mode(cfgdb, interface_name, "local")
cfgdb.mod_entry("LLR_PORT", interface_name, {"llr_local": state})


@llr_interface.command(name='remote')
@click.argument('interface_name', metavar='<interface-name>')
@click.argument('state', metavar='{enabled|disabled}',
type=click.Choice(['enabled', 'disabled']))
@click.pass_context
def llr_interface_remote(ctx, interface_name, state):
"""Enable/disable LLR remote on an interface"""
cfgdb = ctx.obj.cfgdb
_validate_llr_static_mode(cfgdb, interface_name, "remote")
cfgdb.mod_entry("LLR_PORT", interface_name, {"llr_remote": state})
4 changes: 4 additions & 0 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@
from . import dns
from . import bgp_cli
from . import stp
from . import llr

# mock masic APIs for unit test
try:
Expand Down Expand Up @@ -1772,6 +1773,9 @@ def config(ctx):
# add stp commands
config.add_command(stp.spanning_tree)

# add llr commands
config.add_command(llr.llr)

# add mclag commands
config.add_command(mclag.mclag)
config.add_command(mclag.mclag_member)
Expand Down
52 changes: 51 additions & 1 deletion counterpoll/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from sonic_py_common import device_info, multi_asic
from tabulate import tabulate
from flow_counter_util.route import exit_if_route_flow_counter_not_support
from swsscommon.swsscommon import ConfigDBConnector, SonicDBConfig
from swsscommon.swsscommon import ConfigDBConnector, SonicDBConfig, SonicV2Connector
from swsscommon.swsscommon import CFG_FLEX_COUNTER_TABLE_NAME as CFG_FLEX_COUNTER_TABLE

BUFFER_POOL_WATERMARK = "BUFFER_POOL_WATERMARK"
Expand Down Expand Up @@ -772,6 +772,51 @@ def switch_disable(ctx):
ctx.obj.mod_entry(table, key, data)


# LLR counter commands
def _check_llr_capability():
"""Check STATE_DB SWITCH_CAPABILITY|switch for LLR_CAPABLE == 'true'."""
state_db = SonicV2Connector(host="127.0.0.1")
state_db.connect(state_db.STATE_DB)
val = state_db.get(state_db.STATE_DB, "SWITCH_CAPABILITY|switch", "LLR_CAPABLE")
return val == "true"


@cli.group()
@click.option('-n', '--namespace', help='Namespace name',
required=False,
type=click.Choice(get_valid_namespace_choices()),
default=multi_asic.get_current_namespace())
@click.pass_context
def llr(ctx, namespace):
""" LLR port counter commands """
if not _check_llr_capability():
click.echo("Error: LLR is not supported on this platform.")
raise SystemExit(1)
ctx.obj = connect_to_db(namespace)


@llr.command(name='interval')
@click.argument('poll_interval', type=click.IntRange(100, 30000))
@click.pass_context
def llr_interval(ctx, poll_interval):
""" Set LLR port counter query interval """
ctx.obj.mod_entry(CFG_FLEX_COUNTER_TABLE, "LLR", {"POLL_INTERVAL": poll_interval})


@llr.command(name='enable')
@click.pass_context
def llr_enable(ctx):
""" Enable LLR port counter query """
ctx.obj.mod_entry(CFG_FLEX_COUNTER_TABLE, "LLR", {"FLEX_COUNTER_STATUS": ENABLE})


@llr.command(name='disable')
@click.pass_context
def llr_disable(ctx):
""" Disable LLR port counter query """
ctx.obj.mod_entry(CFG_FLEX_COUNTER_TABLE, "LLR", {"FLEX_COUNTER_STATUS": DISABLE})


@cli.command()
@click.option('-n', '--namespace', help='Namespace name',
required=False,
Expand Down Expand Up @@ -799,6 +844,7 @@ def show(namespace):
wred_port_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'WRED_ECN_PORT')
srv6_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'SRV6')
switch_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'SWITCH')
llr_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'LLR')

header = ("Type", "Interval (in ms)", "Status")
data = []
Expand Down Expand Up @@ -845,6 +891,10 @@ def show(namespace):
switch_info.get("POLL_INTERVAL", DEFLT_60_SEC),
switch_info.get("FLEX_COUNTER_STATUS", DISABLE)
])
if llr_info:
data.append(["LLR_STAT",
llr_info.get("POLL_INTERVAL", DEFLT_10_SEC),
llr_info.get("FLEX_COUNTER_STATUS", DISABLE)])
dpu = is_dpu(configdb)
if dpu and eni_info:
data.append(["ENI_STAT", eni_info.get("POLL_INTERVAL", DEFLT_10_SEC),
Expand Down
Loading
Loading