Skip to content
Merged
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
109 changes: 94 additions & 15 deletions config/plugins/sonic-trimming.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,20 @@
CFG_SWITCH_TRIMMING,
STATE_SWITCH_CAPABILITY,
STATE_CAP_TRIMMING_CAPABLE_KEY,
STATE_CAP_DSCP_MODE_KEY,
STATE_CAP_DSCP_MODE_DSCP_VALUE,
STATE_CAP_DSCP_MODE_FROM_TC,
STATE_CAP_QUEUE_MODE_KEY,
STATE_CAP_QUEUE_MODE_DYNAMIC,
STATE_CAP_QUEUE_MODE_STATIC,
STATE_CAP_TC_NUM_KEY,
STATE_CAP_QUEUE_NUM_KEY,
CFG_TRIM_DSCP_VALUE_FROM_TC,
CFG_TRIM_QUEUE_INDEX_DYNAMIC,
CFG_TRIM_KEY,
STATE_CAP_KEY,
DSCP_MIN,
DSCP_MAX,
UINT32_MAX,
UINT8_MAX,
SYSLOG_IDENTIFIER,
Expand All @@ -32,6 +40,14 @@
# Validators ----------------------------------------------------------------------------------------------------------
#

def generic_validator(ctx, db):
""" Generic configuration validator """
entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, STATE_CAP_KEY))
value = entry.get(STATE_CAP_TRIMMING_CAPABLE_KEY, "false")

if value != "true":
ctx.fail("Failed to configure switch trimming: operation is not supported")


class SizeTypeValidator(click.ParamType):
""" Size option validator """
Expand All @@ -44,10 +60,68 @@ def convert(self, value, param, ctx):

class DscpTypeValidator(click.ParamType):
""" Dscp option validator """
name = "text"

def get_metavar(self, param):
db = get_db(click.get_current_context())

entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, STATE_CAP_KEY))
entry.setdefault(STATE_CAP_DSCP_MODE_KEY, "N/A")

cap_list = entry[STATE_CAP_DSCP_MODE_KEY].split(',')

if cap_list.count(STATE_CAP_DSCP_MODE_FROM_TC) == len(cap_list):
return "from-tc"
elif cap_list.count(STATE_CAP_DSCP_MODE_DSCP_VALUE) == len(cap_list):
return "INTEGER"

return "[INTEGER|from-tc]"

def convert(self, value, param, ctx):
db = get_db(ctx)

entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, STATE_CAP_KEY))
entry.setdefault(STATE_CAP_DSCP_MODE_KEY, "N/A")

if not entry[STATE_CAP_DSCP_MODE_KEY]:
raise click.UsageError("Failed to configure {}: no dscp resolution mode capabilities".format(
param.get_error_hint(ctx)), ctx
)

verify_cap = True

if entry[STATE_CAP_DSCP_MODE_KEY] == "N/A":
verify_cap = False

cap_list = entry[STATE_CAP_DSCP_MODE_KEY].split(',')

if value == CFG_TRIM_DSCP_VALUE_FROM_TC:
if verify_cap and (STATE_CAP_DSCP_MODE_FROM_TC not in cap_list):
self.fail("asymmetric dscp resolution mode is not supported", param, ctx)
else:
if verify_cap and (STATE_CAP_DSCP_MODE_DSCP_VALUE not in cap_list):
self.fail("symmetric dscp resolution mode is not supported", param, ctx)

click.IntRange(DSCP_MIN, DSCP_MAX).convert(value, param, ctx)

return value


class TcTypeValidator(click.ParamType):
""" Tc option validator """
name = "integer"

def convert(self, value, param, ctx):
click.IntRange(0, UINT8_MAX).convert(value, param, ctx)
db = get_db(ctx)

entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, STATE_CAP_KEY))
entry.setdefault(STATE_CAP_TC_NUM_KEY, "N/A")

if entry[STATE_CAP_TC_NUM_KEY] == "N/A":
click.IntRange(0, UINT8_MAX).convert(value, param, ctx)
else:
click.IntRange(0, int(entry[STATE_CAP_TC_NUM_KEY])-1).convert(value, param, ctx)

return value


Expand All @@ -74,14 +148,8 @@ def convert(self, value, param, ctx):
db = get_db(ctx)

entry = db.get_all(db.STATE_DB, "{}|{}".format(STATE_SWITCH_CAPABILITY, STATE_CAP_KEY))

entry.setdefault(STATE_CAP_TRIMMING_CAPABLE_KEY, "false")
entry.setdefault(STATE_CAP_QUEUE_MODE_KEY, "N/A")

if entry[STATE_CAP_TRIMMING_CAPABLE_KEY] == "false":
raise click.UsageError("Failed to configure {}: operation is not supported".format(
param.get_error_hint(ctx)), ctx
)
entry.setdefault(STATE_CAP_QUEUE_NUM_KEY, "N/A")

if not entry[STATE_CAP_QUEUE_MODE_KEY]:
raise click.UsageError("Failed to configure {}: no queue resolution mode capabilities".format(
Expand All @@ -102,7 +170,10 @@ def convert(self, value, param, ctx):
if verify_cap and (STATE_CAP_QUEUE_MODE_STATIC not in cap_list):
self.fail("static queue resolution mode is not supported", param, ctx)

click.IntRange(0, UINT8_MAX).convert(value, param, ctx)
if entry[STATE_CAP_QUEUE_NUM_KEY] == "N/A":
click.IntRange(0, UINT8_MAX).convert(value, param, ctx)
else:
click.IntRange(0, int(entry[STATE_CAP_QUEUE_NUM_KEY])-1).convert(value, param, ctx)

return value

Expand Down Expand Up @@ -176,33 +247,41 @@ def SWITCH_TRIMMING():
@click.option(
"-s", "--size", "size",
help="Configures size (in bytes) to trim eligible packet",
type=SizeTypeValidator(),
type=SizeTypeValidator()
)
@click.option(
"-d", "--dscp", "dscp",
help="Configures DSCP value assigned to a packet after trimming",
type=DscpTypeValidator(),
type=DscpTypeValidator()
)
@click.option(
"-t", "--tc", "tc",
help="Configures TC value assigned to a packet after trimming",
type=TcTypeValidator()
)
@click.option(
"-q", "--queue", "queue",
help="Configures queue index to use for transmission of a packet after trimming",
type=QueueTypeValidator(),
type=QueueTypeValidator()
)
@clicommon.pass_db
@click.pass_context
def SWITCH_TRIMMING_GLOBAL(ctx, db, size, dscp, queue):
def SWITCH_TRIMMING_GLOBAL(ctx, db, size, dscp, tc, queue):
""" Configure switch trimming global """

if not (size or dscp or queue):
if not (size or dscp or tc or queue):
raise click.UsageError("Failed to configure switch trimming global: no options are provided", ctx)

generic_validator(ctx, db.db)

table = CFG_SWITCH_TRIMMING
key = CFG_TRIM_KEY

data = {
"size": size,
"dscp_value": dscp,
"queue_index": queue,
"tc_value": tc,
"queue_index": queue
}

try:
Expand Down
24 changes: 13 additions & 11 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -9163,19 +9163,22 @@ This command displays switch trimming global configuration.
```bash
admin@sonic:~$ show switch-trimming global
+-----------------------------+---------+
| Configuration | Value |
| Configuration | Value |
+=============================+=========+
| Packet trimming size | 200 |
| Packet trimming size | 200 |
+-----------------------------+---------+
| Packet trimming DSCP value | 20 |
| Packet trimming DSCP value | 20 |
+-----------------------------+---------+
| Packet trimming queue index | 2 |
| Packet trimming TC value | N/A |
+-----------------------------+---------+
| Packet trimming queue index | 2 |
+-----------------------------+---------+

admin@sonic:~$ show switch-trimming global --json
{
"size": "200",
"dscp_value": "20",
"tc_value": "N/A",
"queue_index": "2"
}
```
Expand All @@ -9196,22 +9199,21 @@ This command is used to manage switch trimming global configuration.
- Options:
- _-s,--size_: size (in bytes) to trim eligible packet
- _-d,--dscp_: dscp value assigned to a packet after trimming
- _-t,--tc_: tc value assigned to a packet after trimming
- _-q,--queue_: queue index to use for transmission of a packet after trimming

- Examples:
```bash
admin@sonic:~$ config switch-trimming global \
--size '128' \
--dscp '48' \
--queue '6'
admin@sonic:~$ config switch-trimming global --size '128' --dscp '48' --queue '6'
admin@sonic:~$ config switch-trimming global --size '128' --dscp '48' --queue 'dynamic'
admin@sonic:~$ config switch-trimming global --size '128' --dscp 'from-tc' --tc '6' --queue '6'
admin@sonic:~$ config switch-trimming global --size '128' --dscp 'from-tc' --tc '6' --queue 'dynamic'
```

- Note:
- At least one option must be provided
- When `--dscp` value is set to `from-tc`, the `--tc` value is used for mapping to DSCP
- When `--queue` value is set to `dynamic`, the `--dscp` value is used for mapping to the queue
```bash
admin@sonic:~$ config switch-trimming global --queue dynamic
```

Go Back To [Beginning of the document](#) or [Beginning of this section](#packet-trimming)

Expand Down
15 changes: 14 additions & 1 deletion show/plugins/sonic-trimming.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

from utilities_common.switch_trimming import (
CFG_SWITCH_TRIMMING,
CFG_TRIM_KEY
CFG_TRIM_KEY,
)


Expand Down Expand Up @@ -81,6 +81,7 @@ def SWITCH_TRIMMING_GLOBAL(ctx, db, json_format):
json_dict = {
"size": entry.get("size", "N/A"),
"dscp_value": entry.get("dscp_value", "N/A"),
"tc_value": entry.get("tc_value", "N/A"),
"queue_index": entry.get("queue_index", "N/A")
}
click.echo(json.dumps(json_dict, indent=4))
Expand Down Expand Up @@ -110,6 +111,18 @@ def SWITCH_TRIMMING_GLOBAL(ctx, db, json_format):
]
body.append(row)

row = [
"Packet trimming TC value",
format_attr_value(
entry,
{
'name': 'tc_value',
'is-leaf-list': False
}
)
]
body.append(row)

row = [
"Packet trimming queue index",
format_attr_value(
Expand Down
23 changes: 16 additions & 7 deletions tests/trimming_input/assert_show_output.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,38 @@
+-----------------------------+---------+
| Packet trimming DSCP value | 20 |
+-----------------------------+---------+
| Packet trimming TC value | N/A |
+-----------------------------+---------+
| Packet trimming queue index | N/A |
+-----------------------------+---------+
"""
show_trim_partial_json = """\
{
"size": "200",
"dscp_value": "20",
"tc_value": "N/A",
"queue_index": "N/A"
}
"""

show_trim_queue_static = """\
show_trim_dscp_asymmetric = """\
+-----------------------------+---------+
| Configuration | Value |
| Configuration | Value |
+=============================+=========+
| Packet trimming size | 200 |
| Packet trimming size | 200 |
+-----------------------------+---------+
| Packet trimming DSCP value | 20 |
| Packet trimming DSCP value | from-tc |
+-----------------------------+---------+
| Packet trimming queue index | 2 |
| Packet trimming TC value | 2 |
+-----------------------------+---------+
| Packet trimming queue index | 2 |
+-----------------------------+---------+
"""
show_trim_queue_static_json = """\
show_trim_dscp_asymmetric_json = """\
{
"size": "200",
"dscp_value": "20",
"dscp_value": "from-tc",
"tc_value": "2",
"queue_index": "2"
}
"""
Expand All @@ -52,13 +58,16 @@
+-----------------------------+---------+
| Packet trimming DSCP value | 20 |
+-----------------------------+---------+
| Packet trimming TC value | N/A |
+-----------------------------+---------+
| Packet trimming queue index | dynamic |
+-----------------------------+---------+
"""
show_trim_queue_dynamic_json = """\
{
"size": "200",
"dscp_value": "20",
"tc_value": "N/A",
"queue_index": "dynamic"
}
"""
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{
"SWITCH_TRIMMING|GLOBAL": {
"size": "200",
"dscp_value": "20",
"dscp_value": "from-tc",
"tc_value": "2",
"queue_index": "2"
}
}
5 changes: 4 additions & 1 deletion tests/trimming_input/mock_state/all.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"SWITCH_CAPABILITY|switch": {
"SWITCH_TRIMMING_CAPABLE": "true",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": "STATIC,DYNAMIC"
"SWITCH|PACKET_TRIMMING_DSCP_RESOLUTION_MODE": "DSCP_VALUE,FROM_TC",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": "STATIC,DYNAMIC",
"SWITCH|NUMBER_OF_TRAFFIC_CLASSES": "16",
"SWITCH|NUMBER_OF_UNICAST_QUEUES": "8"
}
}
9 changes: 9 additions & 0 deletions tests/trimming_input/mock_state/dscp_asymmetric.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"SWITCH_CAPABILITY|switch": {
"SWITCH_TRIMMING_CAPABLE": "true",
"SWITCH|PACKET_TRIMMING_DSCP_RESOLUTION_MODE": "FROM_TC",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": "STATIC,DYNAMIC",
"SWITCH|NUMBER_OF_TRAFFIC_CLASSES": "16",
"SWITCH|NUMBER_OF_UNICAST_QUEUES": "8"
}
}
9 changes: 9 additions & 0 deletions tests/trimming_input/mock_state/dscp_symmetric.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"SWITCH_CAPABILITY|switch": {
"SWITCH_TRIMMING_CAPABLE": "true",
"SWITCH|PACKET_TRIMMING_DSCP_RESOLUTION_MODE": "DSCP_VALUE",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": "STATIC,DYNAMIC",
"SWITCH|NUMBER_OF_TRAFFIC_CLASSES": "16",
"SWITCH|NUMBER_OF_UNICAST_QUEUES": "8"
}
}
5 changes: 4 additions & 1 deletion tests/trimming_input/mock_state/no_capabilities.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"SWITCH_CAPABILITY|switch": {
"SWITCH_TRIMMING_CAPABLE": "true",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": ""
"SWITCH|PACKET_TRIMMING_DSCP_RESOLUTION_MODE": "",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": "",
"SWITCH|NUMBER_OF_TRAFFIC_CLASSES": "N/A",
"SWITCH|NUMBER_OF_UNICAST_QUEUES": "N/A"
}
}
5 changes: 4 additions & 1 deletion tests/trimming_input/mock_state/not_supported.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
{
"SWITCH_CAPABILITY|switch": {
"SWITCH_TRIMMING_CAPABLE": "false",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": ""
"SWITCH|PACKET_TRIMMING_DSCP_RESOLUTION_MODE": "",
"SWITCH|PACKET_TRIMMING_QUEUE_RESOLUTION_MODE": "",
"SWITCH|NUMBER_OF_TRAFFIC_CLASSES": "N/A",
"SWITCH|NUMBER_OF_UNICAST_QUEUES": "N/A"
}
}
Loading
Loading