From d145ffa41ac630d2d834829c09306927752aff83 Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Tue, 10 Dec 2024 23:53:31 +0500 Subject: [PATCH 01/14] Updating YANG model for PVST & MST --- src/sonic-yang-models/setup.py | 2 + .../tests/yang_model_tests/tests/stp.json | 148 +++++++ .../yang_model_tests/tests_config/stp.json | 302 +++++++++++++ .../yang-models/sonic-stp.yang | 406 ++++++++++++++++++ 4 files changed, 858 insertions(+) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests/stp.json create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json create mode 100644 src/sonic-yang-models/yang-models/sonic-stp.yang diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 60dba6c410a..c28d610e498 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -207,6 +207,7 @@ def run(self): './yang-models/sonic-xcvrd-log.yang', './yang-models/sonic-grpcclient.yang', './yang-models/sonic-serial-console.yang', + './yang-models/sonic-stp.yang', './yang-models/sonic-smart-switch.yang',]), ('cvlyang-models', ['./cvlyang-models/sonic-acl.yang', './cvlyang-models/sonic-banner.yang', @@ -287,6 +288,7 @@ def run(self): './cvlyang-models/sonic-macsec.yang', './cvlyang-models/sonic-bmp.yang', './cvlyang-models/sonic-serial-console.yang', + './yang-models/sonic-stp.yang', './cvlyang-models/sonic-bgp-sentinel.yang']), ], zip_safe=False, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json new file mode 100644 index 00000000000..5b2aab731cc --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json @@ -0,0 +1,148 @@ +{ + "STP_GLOBAL_CONFIG_TEST": { + "desc": "Configure STP globally with valid mode (mst or pvst)." + }, + "STP_GLOBAL_INVALID_PRIORITY": { + "desc": "Configure an invalid priority value in the STP global settings.", + "eStrKey": "InvalidValue", + "eStr": ["priority"] + }, + "STP_GLOBAL_INVALID_MODE_TEST": { + "desc": "Configure STP globally with an invalid mode.", + "eStrKey": "InvalidSTPMode", + "eStr": ["Invalid STP mode value. Valid values are 'mst' or 'pvst'."] + }, + "STP_GLOBAL_CONFIG_NO_MODE_NEG_TEST": { + "desc": "Configure STP globally without specifying a mode.", + "eStrKey": "Mandatory", + "eStr": ["STP mode must be specified."] + }, + "STP_GLOBAL_INVALID_ROOTGUARD_TIMEOUT": { + "desc": "Configure an invalid root guard timeout in global STP settings.", + "eStrKey": "InvalidRootguardTimeout", + "eStr": ["Root-guard Timeout must be between 5 and 600 seconds."] + }, + "STP_VLAN_VALID_CONFIG_TEST": { + "desc": "Configure PVST VLAN with valid parameters (priority and VLAN ID)." + }, + "STP_VLAN_INVALID_VLAN_ID_NEG_TEST": { + "desc": "Configure PVST VLAN with an invalid VLAN ID.", + "eStrKey": "InvalidVlanID", + "eStr": ["VLAN ID must be between 1 and 4095."] + }, + "STP_VLAN_INVALID_PRIORITY_NEG_TEST": { + "desc": "Configure PVST VLAN with an invalid bridge priority.", + "eStrKey": "InvalidPriority", + "eStr": ["Bridge priority must be between 0 and 61440."] + }, + "STP_VLAN_MISSING_PRIORITY_NEG_TEST": { + "desc": "Configure PVST VLAN without specifying priority.", + "eStrKey": "Mandatory", + "eStr": ["Bridge priority must be specified for PVST VLAN."] + }, + "STP_VLAN_DUPLICATE_CONFIG_NEG_TEST": { + "desc": "Configure PVST VLAN with a duplicate VLAN ID.", + "eStrKey": "DuplicateVlanID", + "eStr": ["Duplicate VLAN ID detected."] + }, + "STP_INTERFACE_VALID_CONFIG_TEST": { + "desc": "Configure STP parameters on an interface with valid values." + }, + "STP_INTERFACE_INVALID_COST_NEG_TEST": { + "desc": "Configure an invalid path cost for an interface.", + "eStrKey": "InvalidPathCost", + "eStr": ["Path cost must be between 1 and 200000000."] + }, + "STP_INTERFACE_DUPLICATE_NEG_TEST": { + "desc": "Configure duplicate STP parameters for the same interface.", + "eStrKey": "DuplicateInterfaceConfig", + "eStr": ["Duplicate interface configuration detected."] + }, + "STP_INTERFACE_INVALID_PORTFAST_NEG_TEST": { + "desc": "Configure portfast on MST mode interface.", + "eStrKey": "InvalidPortfast", + "eStr": ["Configuration not allowed in MST mode"] + }, + "STP_MST_GLOBAL_CONFIG_TEST": { + "desc": "Configure MSTP globally with valid parameters." + }, + "STP_MST_REGION_NAME_MISSING_NEG_TEST": { + "desc": "Configure MSTP region without specifying a name.", + "eStrKey": "Mandatory", + "eStr": ["MST region name must be provided."] + }, + "STP_MST_REGION_NAME_INVALID_NEG_TEST": { + "desc": "Configure MSTP with an invalid region name.", + "eStrKey": "InvalidValue", + "eStr": ["MST region name must be between 1 and 32 characters."] + }, + "STP_MST_INSTANCE_VALID_CONFIG_TEST": { + "desc": "Configure MSTP instance with valid instance ID and VLAN mapping." + }, + "STP_MST_INSTANCE_DUPLICATE_ID_NEG_TEST": { + "desc": "Configure MSTP instance with a duplicate instance ID.", + "eStrKey": "DuplicateInstanceID", + "eStr": ["Duplicate MSTP instance ID detected."] + }, + "STP_MST_INSTANCE_INVALID_VLAN_NEG_TEST": { + "desc": "Configure MSTP instance with an invalid VLAN list.", + "eStrKey": "InvalidVlanList", + "eStr": ["VLAN list contains invalid or out-of-range VLAN IDs."] + }, + "STP_MST_INSTANCE_MISSING_VLAN_NEG_TEST": { + "desc": "Configure MSTP instance without associating VLANs.", + "eStrKey": "Mandatory", + "eStr": ["At least one VLAN must be associated with the MSTP instance."] + }, + "STP_MST_PORT_CONFIG_TEST": { + "desc": "Configure MSTP parameters on a port with valid settings." + }, + "STP_MST_PORT_INVALID_PRIORITY_NEG_TEST": { + "desc": "Configure MSTP port with an invalid port priority.", + "eStrKey": "InvalidPortPriority", + "eStr": ["Port priority must be between 0 and 240."] + }, + "STP_MST_PORT_INVALID_COST_NEG_TEST": { + "desc": "Configure MSTP port with an invalid path cost.", + "eStrKey": "InvalidPathCost", + "eStr": ["Path cost must be between 1 and 20000000."] + }, + "STP_MST_PORT_DUPLICATE_NEG_TEST": { + "desc": "Configure MSTP parameters with duplicate port settings.", + "eStrKey": "DuplicatePortConfig", + "eStr": ["Duplicate MSTP port configuration detected."] + }, + "STP_MST_PORT_EDGE_PORT_NEG_TEST": { + "desc": "Configure MSTP port with edge-port enabled in non-MST mode.", + "eStrKey": "InvalidEdgePort", + "eStr": ["Edge-port configuration is only allowed in MST mode."] + }, + "STP_MST_PORT_LINK_TYPE_TEST": { + "desc": "Configure MSTP port with valid link type (auto, shared, point-to-point)." + }, + "STP_MST_PORT_INVALID_LINK_TYPE_NEG_TEST": { + "desc": "Configure MSTP port with an invalid link type.", + "eStrKey": "InvalidLinkType", + "eStr": ["Link type must be 'auto', 'shared', or 'point-to-point'."] + }, + "STP_MST_PORT_CONFIG_DUPLICATE_EDGE_PORT_NEG_TEST": { + "desc": "Configure MSTP port with duplicate edge-port configuration.", + "eStrKey": "DuplicateEdgePortConfig", + "eStr": ["Duplicate edge-port configuration detected."] + }, + "STP_PORT_EDGE_PORT_TEST": { + "desc": "Configure edge port settings on an interface." + }, + "STP_PORT_LINK_TYPE_TEST": { + "desc": "Configure link type settings on an interface." + }, + "STP_MST_HOLD_COUNT_TEST": { + "desc": "Configure MST hold count with valid settings." + }, + "STP_MST_HELLO_TIME_TEST": { + "desc": "Configure MST hello time with valid settings." + }, + "STP_MST_MAX_HOPS_TEST": { + "desc": "Configure MST max hops with valid settings." + } +} \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json new file mode 100644 index 00000000000..6f806c6055d --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -0,0 +1,302 @@ +{ + "MSTP_TEST": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "mode": "mst", + "forward_delay": 15, + "hello_time": 2, + "max_age": 20, + "rootguard_timeout": 30, + "priority": 32768 + } + } + }, + "MSTP_TEST_WRONG_MODE": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "mode": "unknown_mode" + } + } + }, + "MSTP_TEST_WRONG_INSTANCE": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST_INST": { + "STP_MST_INST_LIST": [ + { + "instance": 5000, + "vlan": ["10", "20", "30"] + } + ] + } + } + }, + "MSTP_TEST_WRONG_PRIORITY": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "priority": 1000 + } + } + }, + "MSTP_TEST_WITHOUT_NAME": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST": { + "name": "", + "revision": 1, + "max_hops": 20, + "hello_time": 2, + "max_age": 20, + "forward_delay": 15 + } + } + }, + "MSTP_TEST_MISSING_VLAN": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST_INST": { + "STP_MST_INST_LIST": [ + { + "instance": 1, + "vlan": [] + } + ] + } + } + }, + "MSTP_TEST_INVALID_VLAN_LIST": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST_INST": { + "STP_MST_INST_LIST": [ + { + "instance": 1, + "vlan": ["vlan1", "vlan2", "vlan3"] + } + ] + } + } + }, + "MSTP_TEST_MAX_HOPS_EXCEEDED": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST": { + "max_hops": 300 + } + } + }, + "MSTP_TEST_WRONG_HELLO_TIME": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST": { + "hello_time": 15 + } + } + }, + "MSTP_TEST_INVALID_FORWARD_DELAY": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST": { + "forward_delay": 2 + } + } + }, + "MSTP_TEST_DUPLICATE_INSTANCE": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_MST_INST": { + "STP_MST_INST_LIST": [ + { + "instance": 1, + "vlan": ["10", "20"] + }, + { + "instance": 1, + "vlan": ["30", "40"] + } + ] + } + } + }, + "MSTP_TEST_GLOBAL_WITH_INVALID_MODE": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "mode": "invalid_mode" + } + } + }, + "PVST_TEST": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "mode": "pvst", + "forward_delay": 15, + "hello_time": 2, + "max_age": 20, + "rootguard_timeout": 30, + "priority": 32768 + } + } + }, + "PVST_TEST_WRONG_MODE": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "mode": "unknown_mode" + } + } + }, + "PVST_TEST_WRONG_PRIORITY": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_GLOBAL": { + "priority": 1000 + } + } + }, + "PVST_TEST_INVALID_VLAN_ID": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_VLAN": { + "STP_VLAN_LIST": [ + { + "vlanid": 5000, + "vlan": 5000 + } + ] + } + } + }, + "PVST_TEST_MISSING_VLAN": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_VLAN": { + "STP_VLAN_LIST": [ + { + "vlanid": [], + "vlan": [] + } + ] + } + } + }, + "PVST_TEST_DUPLICATE_VLAN": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_VLAN": { + "STP_VLAN_LIST": [ + { + "vlanid": 10 + }, + { + "vlanid": 10, + "vlan": 10 + }, + { + "vlan": 10, + "vlanid": 10 + }, + { + "vlanid": 10 + } + ] + } + } + }, + "PVST_TEST_VLAN_WITHOUT_PRIORITY": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_VLAN": { + "STP_VLAN_LIST": [ + { + "vlanid": 10, + "vlan": 10 + } + ] + } + } + }, + "PVST_TEST_INVALID_PRIORITY": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_VLAN": { + "STP_VLAN_LIST": [ + { + "vlanid": 10, + "vlan": 10, + "priority": 1000 + } + ] + } + } + }, + "PVST_TEST_INVALID_PATH_COST": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "path_cost": -1 + } + ] + } + } + }, + "MSTP_TEST_VALID_INTERFACE_CONFIG": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "enabled": true, + "root_guard": false, + "bpdu_guard": false, + "bpdu_guard_do_disable": false, + "path_cost": 20000, + "priority": 128, + "portfast": false, + "uplink_fast": false, + "edge_port": true, + "link_type": "auto" + } + ] + } + } + }, + "MSTP_TEST_INVALID_INTERFACE_PRIORITY": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "priority": 300 + } + ] + } + } + }, + "MSTP_TEST_DUPLICATE_INTERFACE_CONFIG": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "path_cost": 20000 + }, + { + "ifname": "Ethernet0", + "path_cost": 20000 + } + ] + } + } + }, + "MSTP_TEST_INVALID_EDGE_PORT": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "edge_port": true + } + ] + } + } + }, + "MSTP_TEST_INVALID_LINK_TYPE": { + "sonic-stp:sonic-stp": { + "sonic-stp:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "link_type": "invalid_type" + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-stp.yang b/src/sonic-yang-models/yang-models/sonic-stp.yang new file mode 100644 index 00000000000..aa272880dd1 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-stp.yang @@ -0,0 +1,406 @@ +module sonic-stp { + namespace "http://github.com/sonic-net/sonic-stp"; + prefix stp; + yang-version 1.1; + + import sonic-extension { + prefix sonic-ext; + } + + description "SONiC STP YANG model for PVST and MST configurations"; + + revision 2024-11-24 { + description "Version01 for combined PVST and MST configurations."; + } + + grouping vlanModeAttr { + leaf forward_delay { + type uint8 { + range "4..30" { + error-message "Invalid Forwarding Delay value."; + } + } + units seconds; + default 15; + description + "The delay used by STP bridges to transition root and + designated ports to forwarding"; + } + + leaf hello_time { + type uint8 { + range "1..10" { + error-message "Invalid Hello Time value."; + } + } + units seconds; + default 2; + description + "The interval between periodic transmissions of + configuration messages by designated ports"; + } + + leaf max_age { + type uint8 { + range "6..40" { + error-message "Invalid Maximum Age Time value."; + } + } + units seconds; + default 20; + description + "The maximum age of the information transmitted by the + bridge when it is the root bridge"; + } + + leaf priority { + type uint16 { + range "0..61440" { + error-message "Invalid Bridge Priority value."; + } + } + default 32768; + description + "The manageable component of the Bridge Identifier"; + } + } + + grouping interfaceAttr { + leaf path_cost { + type uint64 { + range "1..200000000" { + error-message "Invalid Port Path Cost value."; + } + } + default 200; + description + "The port's contribution, when it is the Root Port, + to the Root Path Cost for the Bridge"; + } + + leaf priority { + type uint8 { + range "0..240" { + error-message "Invalid Port Priority value."; + } + } + default 128; + description + "The manageable component of the Port Identifier, + also known as the Port Priority"; + } + } + + container sonic-spanning-tree { + + container STP { + list STP_LIST { + max-elements 1; + key "keyleaf"; + leaf keyleaf { + type enumeration { + enum GLOBAL; + } + description + "Key node identifier. It's value is always GLOBAL"; + } + + leaf mode { + type enumeration { + enum pvst; + enum mst; + } + mandatory true; + description + "Spanning tree mode"; + } + + leaf rootguard_timeout { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + + type uint16 { + range "5..600" { + error-message "Invalid Root-guard Timeout value."; + } + } + units seconds; + description + "Once superior BPDUs stop coming on the port, device + will wait for a period until root guard timeout before + moving the port to forwarding state"; + } + + uses vlanModeAttr; + } + } + + container STP_VLAN { + list STP_VLAN_LIST { + key "name"; + leaf name { + type string; + description + "Vlan identifier"; + } + + leaf vlanid { + type uint16 { + range "1..4095" { + error-message "Vlan ID out of range"; + error-app-tag vlanid-invalid; + } + } + description + "Vlan identifier number"; + } + + leaf enabled { + type boolean; + mandatory true; + description + "Spanning tree enabled/disabled on Vlan"; + } + + uses vlanModeAttr; + } + } + + container STP_VLAN_PORT { + list STP_VLAN_PORT_LIST { + key "vlan-name ifname"; + + leaf vlan-name { + type leafref { + path "../../../STP_VLAN/STP_VLAN_LIST/name"; + } + description + "Reference to Vlan"; + } + + leaf ifname { + type leafref { + path "../../../STP_PORT/STP_PORT_LIST/ifname"; + } + description + "Reference to Ethernet interface or PortChannel"; + } + + uses interfaceAttr; + } + } + + container STP_PORT { + list STP_PORT_LIST { + key "ifname"; + sonic-ext:dependent-on "STP_LIST"; + leaf ifname { + type string; + description + "Reference to Ethernet interface or PortChannel"; + } + + leaf enabled { + type boolean; + mandatory true; + description + "Spanning tree enabled/disabled on Interface"; + } + + leaf root_guard { + type boolean; + description + "Enable/Disable Root guard on port"; + } + + leaf bpdu_guard { + type boolean; + description + "Enable/Disable port BPDU guard"; + } + + leaf bpdu_guard_do_disable { + type boolean; + description + "Port to be disabled when it receives a BPDU"; + } + + leaf uplink_fast { + type boolean; + description + "Enable/Disable uplink-fast on port"; + } + + leaf portfast { + must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + type boolean; + description + "Enable/Disable portfast on port"; + } + + uses interfaceAttr; + + // For MST + leaf edge_port { + type boolean; + description + "Enable/Disable Edge-port on interface"; + } + + leaf link_type { + type enumeration { + enum auto; + enum shared; + enum point-to-point; + } + description + "Specifies the interface's link type. Permissible values + are 'shared', 'point-to-point' and 'auto'"; + } + } + } + + container STP_MST { + list STP_MST_LIST { + max-elements 1; + key "keyleaf"; + sonic-ext:dependent-on "STP_LIST"; + + leaf keyleaf { + type enumeration { + enum GLOBAL; + } + description + "Key node identifier. It's value is always GLOBAL"; + } + + leaf name { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type string; + description + "MST Region name"; + } + + leaf revision { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint32; + description + "MST Revision number"; + } + + leaf max_hops { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8; + description + "MST Max hops"; + } + + leaf hello_time { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8; + description + "MST hello time"; + } + + leaf max_age { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8; + description + "MST max age"; + } + + leaf forward_delay { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8; + description + "MST forward delay"; + } + + leaf hold_count { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8; + description + "MST hold count"; + } + } + } + + container STP_MST_INST { + list STP_MST_INST_LIST { + key "instance"; + + leaf instance { + type uint16; + description + "Instance identifier"; + } + + leaf-list vlan { + type string; + description + "Vlan list"; + } + + leaf bridge_priority { + type uint16 { + range "0..61440" { + error-message "Invalid Bridge Priority value."; + } + } + description + "The manageable component of the Bridge Identifier"; + } + } + } + + container STP_MST_PORT { + list STP_MST_PORT_LIST { + key "inst_id ifname"; + + leaf inst_id { + type leafref { + path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; + } + description + "Reference to MST Instance"; + } + + leaf ifname { + type leafref { + path "../../../STP_PORT/STP_PORT_LIST/ifname"; + } + + description + "Reference to Ethernet interface or PortChannel"; + } + uses interfaceAttr; + } + } + } +} \ No newline at end of file From e684942ff877f0791a59c4196feb792811720695 Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Tue, 17 Dec 2024 14:12:25 +0500 Subject: [PATCH 02/14] Creating PR on SONiC buildimage Master --- src/sonic-yang-models/yang-models/sonic-stp.yang | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/sonic-yang-models/yang-models/sonic-stp.yang b/src/sonic-yang-models/yang-models/sonic-stp.yang index aa272880dd1..739b180a3c2 100644 --- a/src/sonic-yang-models/yang-models/sonic-stp.yang +++ b/src/sonic-yang-models/yang-models/sonic-stp.yang @@ -10,20 +10,20 @@ module sonic-stp { description "SONiC STP YANG model for PVST and MST configurations"; revision 2024-11-24 { - description "Version01 for combined PVST and MST configurations."; + description "Version01 for combined PVST configurations."; } grouping vlanModeAttr { leaf forward_delay { type uint8 { range "4..30" { - error-message "Invalid Forwarding Delay value."; + error-message "Invalid Forwarding Delay Value."; } } units seconds; default 15; description - "The delay used by STP bridges to transition root and + "The delay used by STP bridges to transition root, and designated ports to forwarding"; } @@ -49,7 +49,7 @@ module sonic-stp { units seconds; default 20; description - "The maximum age of the information transmitted by the + "The Maximum age of the information transmitted by the bridge when it is the root bridge"; } From 0de9d67563fbbec37112f20d5b3605ec863b41af Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Tue, 17 Dec 2024 14:12:25 +0500 Subject: [PATCH 03/14] Creating PR on SONiC buildimage Master --- src/sonic-yang-models/yang-models/sonic-stp.yang | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/sonic-yang-models/yang-models/sonic-stp.yang b/src/sonic-yang-models/yang-models/sonic-stp.yang index aa272880dd1..d95ca3658aa 100644 --- a/src/sonic-yang-models/yang-models/sonic-stp.yang +++ b/src/sonic-yang-models/yang-models/sonic-stp.yang @@ -10,20 +10,20 @@ module sonic-stp { description "SONiC STP YANG model for PVST and MST configurations"; revision 2024-11-24 { - description "Version01 for combined PVST and MST configurations."; + description "Version01 for combined PVST configurations."; } grouping vlanModeAttr { leaf forward_delay { type uint8 { range "4..30" { - error-message "Invalid Forwarding Delay value."; + error-message "Invalid Forwarding Delay Value."; } } units seconds; default 15; description - "The delay used by STP bridges to transition root and + "The delay used by STP bridges to transition root, and designated ports to forwarding"; } @@ -49,8 +49,8 @@ module sonic-stp { units seconds; default 20; description - "The maximum age of the information transmitted by the - bridge when it is the root bridge"; + "The Maximum age of the information transmitted by the + bridge when it is the root bridge."; } leaf priority { From 2929b0bd3ccc34f64327cf569adb31393935752b Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Wed, 22 Jan 2025 02:02:09 +0500 Subject: [PATCH 04/14] Updated the YANG model --- .../yang-models/sonic-extension.yang | 1 + .../yang-models/sonic-stp.yang | 193 ++++++++++++------ 2 files changed, 127 insertions(+), 67 deletions(-) create mode 120000 src/sonic-yang-models/yang-models/sonic-extension.yang diff --git a/src/sonic-yang-models/yang-models/sonic-extension.yang b/src/sonic-yang-models/yang-models/sonic-extension.yang new file mode 120000 index 00000000000..dc60e0e8871 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-extension.yang @@ -0,0 +1 @@ +/path/to/sonic-extension.yang \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-stp.yang b/src/sonic-yang-models/yang-models/sonic-stp.yang index fe5cac583fe..4d833379020 100644 --- a/src/sonic-yang-models/yang-models/sonic-stp.yang +++ b/src/sonic-yang-models/yang-models/sonic-stp.yang @@ -1,27 +1,27 @@ module sonic-stp { + yang-version 1.1; + namespace "http://github.com/sonic-net/sonic-stp"; + prefix stp; import sonic-extension { prefix sonic-ext; } - - description - "SONiC STP YANG model for PVST and MST configurations"; - revision 2024-12-30 { - description - "Version01 for combined PVST configurations."; - } + description + "This module contains the collection of YANG definitions for the PVST & MSTP"; - extension dependent-on { - argument "dependency"; + revision 2024-12-30 { description - "Indicates module dependencies"; + "Version01 for combined PVST & MSTP configurations."; } grouping vlanModeAttr { + description + "Configuration parameters"; + leaf forward_delay { type uint8 { range "4..30" { @@ -74,6 +74,9 @@ module sonic-stp { } grouping interfaceAttr { + description + "Configuration parameters of interfaces."; + leaf path_cost { type uint64 { range "1..200000000" { @@ -99,15 +102,26 @@ module sonic-stp { } } - container sonic-spanning-tree { + container spanning-tree { + description + "Top level container for SONiC Spanning Tree configurations"; + + container stp-config { + description + "Global configurations"; - container STP { - list STP_LIST { + list stp-list { + description + "STP list containing global attributes"; max-elements 1; key "keyleaf"; + leaf keyleaf { type enumeration { - enum GLOBAL; + enum GLOBAL { + description + "Global configuration identifier"; + } } description "Key node identifier. It's value is always GLOBAL"; @@ -115,8 +129,14 @@ module sonic-stp { leaf mode { type enumeration { - enum pvst; - enum mst; + enum pvst { + description + "Per VLAN Spanning Tree Mode"; + } + enum mst { + description + "Multiple Spanning Tree Mode"; + } } mandatory true; description @@ -124,17 +144,17 @@ module sonic-stp { } leaf rootguard_timeout { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint16 { range "5..600" { error-message "Invalid Root-guard Timeout value."; } } units seconds; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Root guard timeout not allowed in MST mode"; + error-app-tag stp-invalid; + } + description "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before @@ -145,9 +165,15 @@ module sonic-stp { } } - container STP_VLAN { - list STP_VLAN_LIST { + container stp-vlan { + description + "VLAN Specific STP Configurations"; + + list stp-vlan-list { + description + "List of VLAN STP configurations"; key "name"; + leaf name { type string; description @@ -176,13 +202,18 @@ module sonic-stp { } } - container STP_VLAN_PORT { - list STP_VLAN_PORT_LIST { + container stp-vlan-port { + description + "Vlan port configurations"; + + list stp-vlan-port-list { + description + "List of VLAN port configurations"; key "vlan-name ifname"; leaf vlan-name { type leafref { - path "../../../STP_VLAN/STP_VLAN_LIST/name"; + path "../../../stp-vlan/stp-vlan-list/name"; } description "Reference to Vlan"; @@ -190,7 +221,7 @@ module sonic-stp { leaf ifname { type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; + path "../../../stp-port/stp-port-list/ifname"; } description "Reference to Ethernet interface or PortChannel"; @@ -200,13 +231,17 @@ module sonic-stp { } } - container STP_PORT { - list STP_PORT_LIST { + container stp-port { + description + "Port Configurations."; + + list stp-port-list { + description + "List of STP port List attributes."; key "ifname"; - //sonic-ext:dependent-on "STP_LIST"; - must "/sonic-spanning-tree/STP/STP_LIST" { - error-message "STP global configuration must exist"; - } + + sonic-ext:dependent-on "stp-list"; + leaf ifname { type string; description @@ -245,13 +280,13 @@ module sonic-stp { } leaf portfast { - must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" { + type boolean; + must "current()!='true' or ../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='pvst'" { error-message "Configuration not allowed in MST mode"; error-app-tag stp-invalid; } - type boolean; description - "Enable/Disable portfast on port"; + "Enable/Disable portfast on port in PVST only"; } uses interfaceAttr; @@ -265,9 +300,18 @@ module sonic-stp { leaf link_type { type enumeration { - enum auto; - enum shared; - enum point-to-point; + enum auto { + description + "Specifies the interface's link type. Permissible values 'auto'"; + } + enum shared { + description + "Specifies the interface's link type. Permissible values 'shared'"; + } + enum point-to-point { + description + "Specifies the interface's link type. Permissible values 'point-to-point'"; + } } description "Specifies the interface's link type. Permissible values @@ -276,97 +320,108 @@ module sonic-stp { } } - container STP_MST { - list STP_MST_LIST { + container stp-mst { + description + "MST specific configuration container"; + + list stp-mst-list { + description + "List of MST global configurations"; max-elements 1; key "keyleaf"; - //sonic-ext:dependent-on "STP_LIST"; - must "/sonic-spanning-tree/STP/STP_LIST" { - error-message "STP global configuration must exist"; - } + + sonic-ext:dependent-on "stp-list"; leaf keyleaf { type enumeration { - enum GLOBAL; + enum GLOBAL { + description + "Global MST"; + } } description "Key node identifier. It's value is always GLOBAL"; } leaf name { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type string; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type string; description "MST Region name"; } leaf revision { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint32; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint32; description "MST Revision number"; } leaf max_hops { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST Max hops"; } leaf hello_time { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST hello time"; } leaf max_age { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST max age"; } leaf forward_delay { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST forward delay"; } leaf hold_count { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST hold count"; } } } - container STP_MST_INST { - list STP_MST_INST_LIST { + container stp-mst-inst { + description + "STP MST Instance Configuration."; + + list stp-mst-inst-list { + description + "List of STP MST Instance attributes."; key "instance"; leaf instance { @@ -393,13 +448,18 @@ module sonic-stp { } } - container STP_MST_PORT { - list STP_MST_PORT_LIST { + container stp-mst-port { + description + "STP MST Port configurations."; + + list stp-mst-port-list { + description + "STP MST Port List attributes"; key "inst_id ifname"; leaf inst_id { type leafref { - path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; + path "../../../stp-mst-inst/stp-mst-inst-list/instance"; } description "Reference to MST Instance"; @@ -407,9 +467,8 @@ module sonic-stp { leaf ifname { type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; + path "../../../stp-port/stp-port-list/ifname"; } - description "Reference to Ethernet interface or PortChannel"; } From 1d1fc45a7534d755ad47a808473c8bf6a3a16308 Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Wed, 22 Jan 2025 02:02:09 +0500 Subject: [PATCH 05/14] Updated the YANG model --- .../tests/yang_model_tests/tests/stp.json | 4 +- .../yang_model_tests/tests_config/stp.json | 8 +- .../yang-models/sonic-extension.yang | 1 + .../yang-models/sonic-stp.yang | 193 ++++++++++++------ 4 files changed, 133 insertions(+), 73 deletions(-) create mode 120000 src/sonic-yang-models/yang-models/sonic-extension.yang diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json index c8917473183..ab2d565ce0d 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json @@ -1,6 +1,6 @@ { - "STP_GLOBAL_VALID": { - "desc": "Configure valid global STP settings" + "PVST_GLOBAL_VALID": { + "desc": "Configure valid global PVST settings" } } \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index c47e2836df6..bf64a30c81b 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -1,8 +1,8 @@ { - "STP_GLOBAL_VALID": { - "sonic-stp:sonic-spanning-tree": { - "sonic-spanning-tree:STP": { - "STP_LIST": [ + "PVST_GLOBAL_VALID": { + "sonic-stp:spanning-tree": { + "spanning-tree:stp-config": { + "stp-list": [ { "keyleaf": "GLOBAL", "mode": "pvst", diff --git a/src/sonic-yang-models/yang-models/sonic-extension.yang b/src/sonic-yang-models/yang-models/sonic-extension.yang new file mode 120000 index 00000000000..dc60e0e8871 --- /dev/null +++ b/src/sonic-yang-models/yang-models/sonic-extension.yang @@ -0,0 +1 @@ +/path/to/sonic-extension.yang \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-stp.yang b/src/sonic-yang-models/yang-models/sonic-stp.yang index fe5cac583fe..4d833379020 100644 --- a/src/sonic-yang-models/yang-models/sonic-stp.yang +++ b/src/sonic-yang-models/yang-models/sonic-stp.yang @@ -1,27 +1,27 @@ module sonic-stp { + yang-version 1.1; + namespace "http://github.com/sonic-net/sonic-stp"; + prefix stp; import sonic-extension { prefix sonic-ext; } - - description - "SONiC STP YANG model for PVST and MST configurations"; - revision 2024-12-30 { - description - "Version01 for combined PVST configurations."; - } + description + "This module contains the collection of YANG definitions for the PVST & MSTP"; - extension dependent-on { - argument "dependency"; + revision 2024-12-30 { description - "Indicates module dependencies"; + "Version01 for combined PVST & MSTP configurations."; } grouping vlanModeAttr { + description + "Configuration parameters"; + leaf forward_delay { type uint8 { range "4..30" { @@ -74,6 +74,9 @@ module sonic-stp { } grouping interfaceAttr { + description + "Configuration parameters of interfaces."; + leaf path_cost { type uint64 { range "1..200000000" { @@ -99,15 +102,26 @@ module sonic-stp { } } - container sonic-spanning-tree { + container spanning-tree { + description + "Top level container for SONiC Spanning Tree configurations"; + + container stp-config { + description + "Global configurations"; - container STP { - list STP_LIST { + list stp-list { + description + "STP list containing global attributes"; max-elements 1; key "keyleaf"; + leaf keyleaf { type enumeration { - enum GLOBAL; + enum GLOBAL { + description + "Global configuration identifier"; + } } description "Key node identifier. It's value is always GLOBAL"; @@ -115,8 +129,14 @@ module sonic-stp { leaf mode { type enumeration { - enum pvst; - enum mst; + enum pvst { + description + "Per VLAN Spanning Tree Mode"; + } + enum mst { + description + "Multiple Spanning Tree Mode"; + } } mandatory true; description @@ -124,17 +144,17 @@ module sonic-stp { } leaf rootguard_timeout { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint16 { range "5..600" { error-message "Invalid Root-guard Timeout value."; } } units seconds; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Root guard timeout not allowed in MST mode"; + error-app-tag stp-invalid; + } + description "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before @@ -145,9 +165,15 @@ module sonic-stp { } } - container STP_VLAN { - list STP_VLAN_LIST { + container stp-vlan { + description + "VLAN Specific STP Configurations"; + + list stp-vlan-list { + description + "List of VLAN STP configurations"; key "name"; + leaf name { type string; description @@ -176,13 +202,18 @@ module sonic-stp { } } - container STP_VLAN_PORT { - list STP_VLAN_PORT_LIST { + container stp-vlan-port { + description + "Vlan port configurations"; + + list stp-vlan-port-list { + description + "List of VLAN port configurations"; key "vlan-name ifname"; leaf vlan-name { type leafref { - path "../../../STP_VLAN/STP_VLAN_LIST/name"; + path "../../../stp-vlan/stp-vlan-list/name"; } description "Reference to Vlan"; @@ -190,7 +221,7 @@ module sonic-stp { leaf ifname { type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; + path "../../../stp-port/stp-port-list/ifname"; } description "Reference to Ethernet interface or PortChannel"; @@ -200,13 +231,17 @@ module sonic-stp { } } - container STP_PORT { - list STP_PORT_LIST { + container stp-port { + description + "Port Configurations."; + + list stp-port-list { + description + "List of STP port List attributes."; key "ifname"; - //sonic-ext:dependent-on "STP_LIST"; - must "/sonic-spanning-tree/STP/STP_LIST" { - error-message "STP global configuration must exist"; - } + + sonic-ext:dependent-on "stp-list"; + leaf ifname { type string; description @@ -245,13 +280,13 @@ module sonic-stp { } leaf portfast { - must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" { + type boolean; + must "current()!='true' or ../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='pvst'" { error-message "Configuration not allowed in MST mode"; error-app-tag stp-invalid; } - type boolean; description - "Enable/Disable portfast on port"; + "Enable/Disable portfast on port in PVST only"; } uses interfaceAttr; @@ -265,9 +300,18 @@ module sonic-stp { leaf link_type { type enumeration { - enum auto; - enum shared; - enum point-to-point; + enum auto { + description + "Specifies the interface's link type. Permissible values 'auto'"; + } + enum shared { + description + "Specifies the interface's link type. Permissible values 'shared'"; + } + enum point-to-point { + description + "Specifies the interface's link type. Permissible values 'point-to-point'"; + } } description "Specifies the interface's link type. Permissible values @@ -276,97 +320,108 @@ module sonic-stp { } } - container STP_MST { - list STP_MST_LIST { + container stp-mst { + description + "MST specific configuration container"; + + list stp-mst-list { + description + "List of MST global configurations"; max-elements 1; key "keyleaf"; - //sonic-ext:dependent-on "STP_LIST"; - must "/sonic-spanning-tree/STP/STP_LIST" { - error-message "STP global configuration must exist"; - } + + sonic-ext:dependent-on "stp-list"; leaf keyleaf { type enumeration { - enum GLOBAL; + enum GLOBAL { + description + "Global MST"; + } } description "Key node identifier. It's value is always GLOBAL"; } leaf name { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type string; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type string; description "MST Region name"; } leaf revision { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint32; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint32; description "MST Revision number"; } leaf max_hops { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST Max hops"; } leaf hello_time { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST hello time"; } leaf max_age { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST max age"; } leaf forward_delay { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST forward delay"; } leaf hold_count { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + type uint8; + must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } - type uint8; description "MST hold count"; } } } - container STP_MST_INST { - list STP_MST_INST_LIST { + container stp-mst-inst { + description + "STP MST Instance Configuration."; + + list stp-mst-inst-list { + description + "List of STP MST Instance attributes."; key "instance"; leaf instance { @@ -393,13 +448,18 @@ module sonic-stp { } } - container STP_MST_PORT { - list STP_MST_PORT_LIST { + container stp-mst-port { + description + "STP MST Port configurations."; + + list stp-mst-port-list { + description + "STP MST Port List attributes"; key "inst_id ifname"; leaf inst_id { type leafref { - path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; + path "../../../stp-mst-inst/stp-mst-inst-list/instance"; } description "Reference to MST Instance"; @@ -407,9 +467,8 @@ module sonic-stp { leaf ifname { type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; + path "../../../stp-port/stp-port-list/ifname"; } - description "Reference to Ethernet interface or PortChannel"; } From da0137f210e68487cc33dd04e71af3e1e55184eb Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Tue, 11 Feb 2025 15:40:57 +0500 Subject: [PATCH 06/14] Changes in the YANG model --- src/sonic-yang-models/setup.py | 4 ++-- .../tests/yang_model_tests/tests_config/stp.json | 4 ++-- .../yang-models/{sonic-stp.yang => sonic-spanning-tree.yang} | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) rename src/sonic-yang-models/yang-models/{sonic-stp.yang => sonic-spanning-tree.yang} (99%) diff --git a/src/sonic-yang-models/setup.py b/src/sonic-yang-models/setup.py index 9a6b68d0399..872c88fb300 100644 --- a/src/sonic-yang-models/setup.py +++ b/src/sonic-yang-models/setup.py @@ -210,7 +210,7 @@ def run(self): './yang-models/sonic-xcvrd-log.yang', './yang-models/sonic-grpcclient.yang', './yang-models/sonic-serial-console.yang', - './yang-models/sonic-stp.yang', + './yang-models/sonic-spanning-tree.yang', './yang-models/sonic-smart-switch.yang', './yang-models/sonic-srv6.yang']), ('cvlyang-models', ['./cvlyang-models/sonic-acl.yang', @@ -292,7 +292,7 @@ def run(self): './cvlyang-models/sonic-macsec.yang', './cvlyang-models/sonic-bmp.yang', './cvlyang-models/sonic-serial-console.yang', - './cvlyang-models/sonic-stp.yang', + './cvlyang-models/sonic-spanning-tree.yang', './cvlyang-models/sonic-bgp-sentinel.yang']), ], zip_safe=False, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index bf64a30c81b..1fe0e0943a0 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -1,7 +1,7 @@ { "PVST_GLOBAL_VALID": { - "sonic-stp:spanning-tree": { - "spanning-tree:stp-config": { + "sonic-spanning-tree:sonic-spanning-tree": { + "sonic-spanning-tree:stp-config": { "stp-list": [ { "keyleaf": "GLOBAL", diff --git a/src/sonic-yang-models/yang-models/sonic-stp.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang similarity index 99% rename from src/sonic-yang-models/yang-models/sonic-stp.yang rename to src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index b88d1371f52..af550c516cb 100644 --- a/src/sonic-yang-models/yang-models/sonic-stp.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -1,4 +1,4 @@ -module sonic-stp { +module sonic-spanning-tree { yang-version 1.1; namespace "http://github.com/sonic-net/sonic-stp"; prefix stp; @@ -99,7 +99,7 @@ module sonic-stp { } } - container sonic-stp { + container sonic-spanning-tree { description "Top level container for SONiC Spanning Tree configurations"; From c4a339fd319fc90c14d343007c36052bb0b38ae0 Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Wed, 26 Feb 2025 18:27:43 +0500 Subject: [PATCH 07/14] Fixed Errors in STP YANG model --- MSTP.md | 1272 +++++++++++++++++ SONiC_PVST_HLD.md | 746 ++++++++++ SONiC_YANG_Model_Guidelines.md | 1018 +++++++++++++ .../tests/files/sample_config_db.json | 151 ++ .../tests/yang_model_tests/test_yang_model.py | 2 + .../tests/yang_model_tests/tests/stp.json | 8 +- .../yang_model_tests/tests_config/stp.json | 35 +- .../yang-models/sonic-spanning-tree.yang | 208 +-- 8 files changed, 3338 insertions(+), 102 deletions(-) create mode 100644 MSTP.md create mode 100644 SONiC_PVST_HLD.md create mode 100644 SONiC_YANG_Model_Guidelines.md diff --git a/MSTP.md b/MSTP.md new file mode 100644 index 00000000000..7bb8f704efd --- /dev/null +++ b/MSTP.md @@ -0,0 +1,1272 @@ + +[© Broadcom](https://www.broadcom.com/) & [© xFlow Research Inc](https://xflowresearch.com/) + +# Multiple Spanning Tree Protocol + + +## Revision History + +|Revision No.|Description|Author|Date| +| :- | :- | :- | :- | +|0.1|Modified Design| [Divya Kumaran Chandralekha](https://github.com/divyachandralekha) , [Rida Hanif](github.com/ridahanif96) , [Wajahat Razi](https://github.com/wajahatrazi) | July 02, 2024| + +# Table of Contents + +* [Scope](#scope) +* [Background](#background) +* [Abbreviations](#abbreviations) +* [Overview](#overview) +* [Introduction](#introduction) +* [Requirements](#requirements) +* [Architecture Design](#architecture-design) + - [STP Container](#stp-container) + - [SWSS Container](#swss-container) +* [Database Changes](#database-changes) + - [CONFIG DB](#config-db) + - [APP DB](#app-db) +* [SAI](#sai) +* [Additional Features](#additional-features) +* [Sequence Diagrams](#sequence-diagrams) + - [MSTP global enable](#mstp-global-enable) + - [MSTP global disable](#mstp-global-disable) + - [MSTP region name/version change](#mstp-region-nameversion-change) + - [Instance creation](#instance-creation) + - [Instance deletion](#instance-deletion) + - [MSTP Instance creation](#mstp-Instance-Creation) + - [MSTP Instance deletion](#mstp-Instance-Deletion) + - [Add VLAN to Exisiting Instance](#add-vlan-existing) + - [Delete VLAN to Exisiting Instance](#delete-vlan-existing) + - [Add VLAN member](#add-vlan-member) + - [Del VLAN member](#del-vlan-member) +* [Configuration Commands](#configuration-commands) + - [Global Level](#global-level) + - [Region Level](#region-level) + - [Instance, Interface Level](#instance-interface-level) + - [Show Commands](#show-commands) + - [Clear Commands](#clear-commands) + - [Debug Commands](#debug-commands) + - [Disabled Commands](#disabled-commands) +* [YANG Model](#yang-model) +* [Rest API Support](#rest-api-support) +* [Warm Boot](#warm-boot) +* [Testing Requirements](#testing-requirements) + - [Unit test cases](#unit-test-cases) +* [References](#references) + +# Scope +This document describes the High Level Design of Multiple Spanning Tree Protocol. + +# Abbreviations + +|**Term**|**Meaning**| +| :- | :- | +|BPDU|Bridge Protocol Data Unit| +|CIST|Common Internal Spanning Tree| +|CST|Common Spanning Tree| +|IST|Internal Spanning Tree| +|MSTI|Multiple Spanning Tree Instance| +|MSTID|Multiple Spanning Tree Identifier| +|MSTP|Multiple Spanning Tree Protocol| +|STP|Spanning Tree Protocol| +|VLAN|Virtual Local Area Network| +|VID|VLAN identifier| + +# Overview +Multiple Spanning Tree Protocol (MSTP) enhances the Spanning Tree Protocol (STP) by enabling the creation of multiple spanning tree instances within a network. It provides a mechanism to map VLANs to specific spanning tree instances which offers network segmentation and improved control over traffic flow. + +# Introduction + +Spanning Tree Protocol (STP) is a network protocol that operates at the Data Link layer (Layer 2) of the OSI model. Its primary purpose is to prevent loops in a Local Area Network (LAN). Network loops can cause broadcast storms and multiple frame copies, leading to network inefficiencies and failures. STP ensures a loop-free topology by creating a spanning tree that selectively blocks some network paths. + +Multiple Spanning Tree Protocol (MSTP), standardized in IEEE 802.1s, is an extension of STP. MSTP enhances STP by providing better loop prevention, path redundancy, and optimal bandwidth utilization. MSTP allows network engineers to create multiple spanning trees, each associated with a set of VLANs, and assign them to different switch ports. This configuration optimizes bandwidth usage, reduces convergence time, and simplifies network management. + + +MSTP reduces convergence time compared to STP. When a network topology change occurs, only the affected MSTI needs to reconverge, minimizing the impact on the entire network. + + +# Understanding MSTP: IST, CIST, CST, MST Regions, MSTIs, VLAN to MSTI Mapping + +Before diving into the specific terms related to Multiple Spanning Tree Protocol (MSTP), it's important to first define the concept of an MST region. The following definitions outline the key components of MSTP, starting with the MST region. + +1. **MST Regions**: An MST region is a group of interconnected bridges that share the same MST configuration, including the MST configuration name, revision number, and VLAN-to-instance mappings. + +2. **Default Internal Spanning Tree (IST)**: An internal spanning tree (IST) is a spanning tree that runs in an MST region. It is also called MSTI 0, a special MSTI to which all VLANs are mapped by Default. + +3. **Common Spanning Tree (CST)**: The common spanning tree (CST) is a single spanning tree that connects all MST regions in a switched network. + +4. **Common and Internal Spanning Tree (CIST)**: The common and internal spanning tree (CIST) is a single spanning tree that connects all devices in a switched network. It consists of the ISTs in all MST regions and the CST. + +5. **MST Instances (MSTIs)**: MSTP divides the network into multiple regions, each containing several MSTIs. Each MSTI operates independently, allowing for efficient use of network resources and optimized load balancing across different VLANs. + + +# MSTP Advantages + +1. **VLAN-to-MSTI Mapping**: MSTP maps VLANs to specific MSTIs using a VLAN mapping table. This mapping ensures that traffic within a VLAN follows the corresponding MSTI, optimizing the network path and improving performance. + +2. **Traffic Load Sharing and Link Level Redundancy**: By effectively utilizing VLAN-to-MSTI mapping, MSTP can facilitate traffic load sharing across multiple links and provide redundancy at the link level. This helps in balancing the traffic load and enhances overall network resilience. + +3. **Optimized Bandwidth**: MSTP ensures that network paths are used efficiently, reducing link blocking and optimizing bandwidth usage. This results in improved performance for data transmission across the network. + + +# MSTP Operation + +1. **MST BPDUs**: MSTP uses Multiple Spanning Tree Bridge Protocol Data Units (MST BPDUs) to exchange information between switches. These BPDUs contain information about the MSTI and VLAN mappings, ensuring consistent spanning tree calculations across the network. MSTP calculates spanning trees based on MST BPDUs. + +2. **MSTP BPDUs Characteristics**: MSTP BPDUs, which utilize the IEEE Reserved Multicast MAC address, are untagged. This is in contrast to PVST BPDUs. Additionally, MSTP BPDUs are backward compatible with legacy STP, RSTP, and PVST+/RPVST+ BPDUs. + +3. **Config Digest**: A hash of MSTP-VLAN mapping knows as 'config digest' is carried in the BPDUs, coupled with region name and the revision number, determines the same/different MST region of the sending switch. + + +
+MSTP BPDU +

MSTP BPDU Format

+

+
+MSTP Config Message +

MSTI Configuration Messages

+
+ +*Refer to [RFC IEEE 802.1s-2002](https://standards.ieee.org/ieee/802.1s/1042/) for MSTP BPDU details.* + + +### Requirements + + +### Functional Requirements + +1. Support the creation of Multiple Spanning Tree Instances (MSTIs). + +2. Support the assignment of one or more VLANs to a specific MSTI within a region. + +3. Support the option to assign a region name and revision number to MSTP regions to achieve unique identification of VLAN to instance mapping across switches. + +4. Support path selection and forwarding behavior in MSTI to optimize network performance within each instance by configuring a distinct root bridge. + +5. Support the configuration of spanning tree parameters such as forward delay, hello timer, and hop count. + +6. The Destination MAC Address will be `01:80:C2:00:00:00` for MSTP BPDUs. + +7. Support backward compatibility with networks employing different spanning tree protocols, such as STP and RSTP. + +8. Support edge port functionality. + +9. Support BPDU guard functionality. + +10. Support root guard functionality. + +11. Support protocol operation on static breakout ports. + +12. Support protocol operation on Port-channel interfaces. Note: MSTP does not support aggregated path cost calculations. + + +#### Configuration & Management Requirements + + +1. Support CLI configurations as mentioned in Configuration section + +2. Support show commands as mentioned in Configuration section + +3. Support debug commands as mentioned in Configuration section + +4. Support statistics commands as mentioned in Configuration section + +5. Support clear commands as mentioned in Configuration section + + +# Architecture Design +Following diagram explains the architectural design and linkages for MSTP. MSTP uses multiple existing SONiC containers, configuration details of each is mentioned below as well. + +![MSTP Architecture](images/MSTPDesign_Archi.drawio.png) + +## STP Container +STP Container is responsible for actions taken for BPDU rx and BPDU tx. Following are the details for implementation: + +### STPMgr +Subscribes to CONFIG_DB and STATE_DB tables, parsing configurations and passes to STPd. + +### STPd +Responsible for all MST protocol related calculations. BPDUs are sent and received in STPd and states are updated accordingly. + +### STPSync +STPSync is a component integrated within STPd responsible for managing and updating all operational STP data to APP DB. + +Stpd communicates with Linux Kernal for The BPDU reception/transmission, management of port or LAG changes via NetLink events, and synchronization of STP port states with the Linux Kernel. + +## SWSS Container + +SWSS Container is responsible for passing on configurations to SAI as follows: + +### STPOrch +Updates SAI via following APIs: + +1. Creating/deleting instances +2. Assigning VLAN to instance +3. Creation of STP Port and assigning port state with respect to each instance +4. Flushing FDB entries + + +# Database Changes +MSTP design introduces some new tables for configuration along with slight modification in existing STP tables. Following are details of each individual table: + +## CONFIG DB + +### Existing Table +Following existing table of CONFIG_DB will be modified for MSTP implementation: + +#### STP_GLOBAL_TABLE +A new value of `mst` for `mode` column +``` +mode = "pvst" / "mst" ; a new option for mstp +``` +Other fields of this table are not applicable for "mstp" mode. + +### New Tables +Following new tables will be added to CONFIG_DB: + + +#### STP_MST_TABLE +``` +;Stores STP Global configuration +key = STP_MST| GLOBAL ; GLOBAL MSTP table key +name = 1*32CHAR ; MSTP region name(DEF:mac address of switch) +revision = 5*DIGIT ; MSTP revision number (0 o 65535 ,DEF:0) +max_hop = 2*DIGIT ; maximum hops (1 to 40, DEF:20) +max_age = 2*DIGIT ; maximum age time in secs (6 to 40sec, DEF:20sec) +hello_time = 2*DIGIT ; hello time in secs (1 to 10sec, DEF:2sec) +forward_delay = 2*DIGIT ; forward_delay in secs (4 to 30sec, DEF:15 sec) +``` + +#### STP_MST_INST_TABLE +``` +;Stores STP configurations per MSTI +key = STP_MST| "MST_INSTANCE":"Instance" id ; MST with prefix "STP_MST" +bridge_priority = 5*DIGIT ; bridge priority (0 to 61440, DEF: 32768) +vlan_list = "Vlans" ; Lists of VLANs assigned to the MST instance +``` + +#### STP_MST_PORT_TABLE + +``` +;Stores STP interface details per MSTI +key = STP_MST_PORT| "MST_INSTANCE" id|ifname ; MSTI+Intf with prefix "STP_MST_PORT" +path_cost = 9*DIGIT ; port path cost (1 to 20000000) +priority = 3*DIGIT ; port priority (0 to 240, DEF:128) + +``` + +#### STP_PORT_TABLE + +``` +;Stores STP interface details +key = STP_PORT|ifname ; ifname with prefix STP_PORT +edge_port = BIT ; enabled or disabled +link_type = "type" ; type can be of auto, point-to-point or shared +enabled = BIT ; enabled or disabled +bpdu_guard = BIT ; enabled or disabled +bpdu_guard_do = BIT ; enabled or disabled +root_guard = BIT ; enabled or disabled +path_cost = 9*DIGIT ; port path cost (1 to 20000000) +priority = 3*DIGIT ; port priority (0 to 240, DEF:128) + +``` + + +## APP DB + +### New Tables +Following new tables are introduced as part of MSTP Feature: + + +#### STP_MST_INST_TABLE +``` +;Stores the STP per MSTI operational details +key = STP_MST_INST_TABLE:"MST" id +vlan_list = vlan_id-or-range[,vlan_id-or-range] ; list of VLAN IDs assigned to MST instance +bridge_address = 16HEXDIG ; bridge id +regional_root_address = 16HEXDIG ; regional root bridge id +root_address = 16HEXDIG ; root bridge id +root_path_cost = 1*9DIGIT ; root path cost +regional_root_cost = 1*9DIGIT ; regional root path cost +root_max_age = 1*2DIGIT ; Max age of root bridge (6 to 40 sec, DEF:20sec) +root_hello_time = 1*2DIGIT ; Hello time of root bridge (1 to 10 sec, DEF:2sec) +root_forward_delay = 1*2DIGIT ; forward delay of root bridge (4 to 30sec , DEF:15sec) +remining_hops = 1*2DIGIT ; Remaining Max-hops +root_port = ifName ; Root port name +``` + +#### STP_MST_PORT_TABLE +``` +;Stores STP MST instance interface details +key = STP_MST_PORT_TABLE:"MST":id:ifname ; MSTI+Intf with prefix "STP_MST_PORT +port_number = 1*3DIGIT ; port number or bridge port +path_cost = 1*9DIGIT ; port path cost (1 to 200000000) +priority = 3*DIGIT ; port priority (0 to 240, DEF:128) +port_state = "state" ; DISABLED/DISCARDED/LISTENING/LEARNING/FORWARDING +role = "role" ; DESIGNATED/ROOT/ALTERNATIVE/MASTER +desig_cost = 1*9DIGIT ; designated cost +external_cost = 1*9DIGIT ; designated cost +desig_root = 16HEXDIG ; designated root +desig_reg_cost = 16HEXDIG ; designated root +desig_bridge = 16HEXDIG ; designated bridge +desig_port = 1*9DIGIT ; designated port +fwd_transitions = 1*5DIGIT ; number of forward transitions +bpdu_sent = 1*10DIGIT ; bpdu transmitted +bpdu_received = 1*10DIGIT ; bpdu received +``` + +#### STP_PORT_TABLE +``` +;Stores STP interface detail +key = STP_PORT_TABLE:ifname ; ifname with prefix STP_INTF +edge_port = BIT ; edge port enabled or disabled +link_type = "type" ; point-to-point or shared link type +mst_boundary = BIT ; enabled or disabled +mst_boundary_proto = BIT ; enabled or disabled +``` + +#### STP_INST_PORT_FLUSH_TABLE + +``` +;Defines instance and port for which FDB Flush needs to be performed +key = STP_INST_PORT_FLUSH_TABLE:instane:ifname ; FDB Flush instance id and port +name +state = "true" +``` + +### Existing Tables +Following already present APP_DB tables are also used for implementation of MSTP: + +#### STP_PORT_STATE_TABLE +The table holds the state of a port i.e forwarding, learning, blocking with respect to each instance. +#### STP_VLAN_INSTANCE_TABLE +The table holds the VLAN to instance mapping. + +# SAI + +## Existing SAI Attributes +Following table shows the existing SAI Attributes that will be used: + +|**Component**|**SAI Attribute**| +| :- | :- | +|STP Instance|SAI_STP_ATTR_VLAN_LIST +||SAI_STP_ATTR_BRIDGE_ID| +||SAI_STP_ATTR_PORT_LIST| +|STP Port|SAI_STP_PORT_ATTR_STP | +||SAI_STP_PORT_ATTR_BRIDGE_PORT| +||SAI_STP_PORT_ATTR_STATE| +|STP Port States|SAI_STP_PORT_STATE_LEARNING| +||SAI_STP_PORT_STATE_FORWARDING| +||SAI_STP_PORT_STATE_BLOCKING| +|VLAN STP Instance|SAI_VLAN_ATTR_STP_INSTANCE| +|Switch STP Attributes|SAI_SWITCH_ATTR_Default_STP_INST_ID| +||SAI_SWITCH_ATTR_MAX_STP_INSTANCE| + +## New SAI Attributes +MSTP design will not require any new SAI Attributes for Control Packet trap. We will use the existing traps as DMAC and LLC fields are identical for STP and MSTP + +# Additional Features + +## BPDU Guard +BPDU guard feature will also be supported by MSTP. BPDU Guard feature disables the connected device ability to initiate or participate in STP on edge ports. When STP BPDUs are received on the port where BPDU guard is enabled the port will be shutdown. User can re-enable the port administratively after ensuring the BPDUs have stopped coming on the port. + + +## Root Guard +Root guard feature will also be supported by MSTP. The Root Guard feature provides a way to enforce the root bridge placement in the network and allows STP to interoperate with user network bridges while still maintaining the bridged network topology that the administrator requires. When BPDUs are received on a root guard enabled port, the STP state will be moved to "Root inconsistent" state to indicate this condition. Once the port stops receiving superior BPDUs, Root Guard will automatically set the port back to a FORWARDING state. + +## Edge Port +Edge ports immediately transition to the forwarding state upon activation and do not participate in STP topology calculations. + + +## Uplink Fast +MSTP standard does not support uplink fast so uplink fast functionality will be disable for MSTP. + + +# Sequence Diagrams + +## MSTP global enable +![MSTP Global Enable](images/MSTP_GLobal_enable.drawio.png) + +## MSTP global disable +![MSTP Global Disable](images/MSTP_Global_disable.drawio.png) + +## MSTP region name/version change +![MSTP Region Config](images/MSTP_Region_Name.drawio.png) + + +## MSTIs Instance Creation +![Instance Creation ](images/MSTP_Instance_Create.drawio.png) + +## MSTIs Instance Deletion +![Instance Deletion](images/MSTP_Instance_Delete.drawio.png) + + +## Add VLAN to Existing Instance +![MSTP VLAN Add](images/MSTP_Add_ExistingInstance.drawio.png) + +## Del VLAN from Exisiting Instance +![MSTP VLAN Del](images/MSTP_Del_ExistingInstance.drawio.png) + + +# Configuration Commands +Following configuration commands will be provided for configuration of MSTP: +## Global Level + +- **config spanning_tree {enable|disable} {mst}** + - Enables or disables mstp at global level on all ports of the switch. + - Only one mode of STP can be enabled at a time. + - By Default disabled. + +- **config spanning_tree max_hops \** + - Specify the number of maximum hops before the BPDU is discarded inside a region. + - max-hops-value: Default: 20, range: 1-255 + +- **config spanning_tree hello \** + - Specify configuring hello interval in sec for transmission of BPDUs. + - Default: 2, range 1-10 + +- **config spanning_tree max_age \** + - Specify configuring maximum time to listen for root bridge in seconds. + - Default: 2, range 6-40 + + +## Region Level +Below commands allow configuring on region basis: + +- **config spanning_tree mst region-name \** + - Edit the name of region + - region-name: Case sensitive, characters should be less than or equal to 32, Default: mac-address of bridge + +- **config spanning-tree mst revision \** + - Revision number is used to track changes in the configuration and to synchronize the configuration across the switches in the same region. + - revision-number: Default: 0, range: 0-65535 + +## Instance Level + +Below commands allow configuration of an instance: + +- **config spanning_tree mst instance \ priority \** + - Configure priority of bridge for an instance. + - instance-id: id of the instance for which bridge priority is to be defined. If the provided instance id is not created yet, an error message is displayed. + - priority-value: Default: 32768, range: 0-61440 (should be multiple of 4096) + +- **config spanning_tree mst instance \ vlan (add|del) \** + - VLAN to instance mapping. + - instance-id: id of the instance to which VLAN is to be mapped. If the provided instance id is not created yet, an error message is displayed. + - vlan-id: Range: 1-4094. If the provided VLAN is not created yet, an error message is displayed. + - Instance is only active when there is at least one VLAN member port configured for one of the mapped VLANs. + +## Instance, Interface Level +Following commands are used for spanning-tree configurations on per instance, per interface basis: + +- **config spanning_tree mst instance \ interface \ priority \** + - Configure priority of an interface for an instance. + - priority-value: Default: 128, range: 0-240 + - Supported Instances : 64 + +- **config spanning_tree mst instance \ interface \ cost \** + - Configure path cost of an interface for an instance. + - cost-value: Range: 1-200000000 + +## Interface Level +Following new commands will be added: + +- **config spanning_tree interface {enable|disable} \** + - Configure an interface for MSTP. + +- **config spanning_tree interface edgeport {enable|disable} \** + - This command allow enabling or disabling of edge port on an interface. + +- **config spanning_tree interface bpdu_guard {enable|disable} \** + - This command allow enabling or disabling of bpdu_guard on an interface. + +- **config spanning_tree interface root_guard {enable|disable} \** + - This command allow enabling or disabling of root_guard on an interface. + + +- **config spanning_tree interface priority \ \** + - Specify configuring the port level priority for root bridge in seconds. + - Default: 128, range 0-240 + +- **config spanning_tree interface cost \ \** + - Specify configuring the port level priority for root bridge in seconds. + - Default: 0, range 1-200000000 + +- **config spanning_tree interface link-type {P2P|Shared-Lan|Auto} \** + - Specify configuring the interface at different link types. + - Default : Auto + + + **Note : These functionalities need to be explicitly enabled.** + +## Show Commands + +- show spanning_tree mst + + The output of this command will be as follows for `mstp`: +``` +admin@sonic: show spanning_tree detail + +Spanning-tree Mode: MSTP +####### MST0 (CIST) Vlans mapped : 1, 4-8, 202-4094 +Bridge Address 8000.80a2.3526.0c5e +Root Address 8000.80a2.3526.0c5e + Port Root Path cost 0 +Regional Root Address 8000.80a2.3526.0c5e + Internal cost 0 Rem hops 20 +Operational Hello Time 2, Forward Delay 15, Max Age 20, Txholdcount 6 +Configured Hello Time 2, Forward Delay 15, Max Age 20, Max Hops 20 + +Interface Role State Cost Prio.Nbr Type +--------------- -------- ---------- ------- --------- ----------- +Ethernet20 DESIGNATED FORWARDING 2000 128.25 P2P +Ethernet46 DESIGNATED FORWARDING 800 128.86 P2P +PortChannel1001 DESIGNATED FORWARDING 1000 128.45 P2P + + +####### MST1 (CIST) Vlans mapped : 2, 300, 400 +Bridge Address 8000.80a2.3526.0c5e +Root Address 8000.80a2.3526.0c5e + Port Root Path cost 0 Rem Hops 20 + +Interface Role State Cost Prio.Nbr Type +--------------- -------- ---------- ------- --------- ----------- +Ethernet46 DESIGNATED FORWARDING 800 128.86 P2P +PortChannel1001 DESIGNATED FORWARDING 1000 128.45 P2P +``` + +- show spanning_tree mst detail + +``` +admin@sonic: show spanning_tree detail + + +####### MST0 (CIST) Vlans mapped : 1, 4-8, 202-4094 +Bridge Address 8000.80a2.3526.0c5e + Root Address 8000.80a2.3526.0c5e + Port Root Path cost 0 Rem Hops 20 + +Ethernet20 is DESIGNATED FORWARDING +Port info port id 86 priority 128 cost 800 +Designated Address 8000.80a2.3526.0c5e cost 0 +Designated bridge Address 8000.80a2.3526.0c5e port id 25 +Timers: forward transitions 0 +Bpdu send 80, received 0 + +Ethernet46 is DESIGNATED FORWARDING +Port info port id 25 priority 128 cost 1000 +Designated Address 8000.80a2.3526.0c5e cost 0 +Designated bridge Address 8000.80a2.3526.0c5e port id 86 +Timers: forward transitions 0 +Bpdu send 40, received 0 + +PortChannel1001 is DESIGNATED FORWARDING +Port info port id 25 priority 128 cost 2000 +Designated Address 8000.80a2.3526.0c5e cost 0 +Designated bridge Address 8000.80a2.3526.0c5e port id 45 +Timers: forward transitions 0 +Bpdu send 30, received 0 + +####### MST1 (CIST) Vlans mapped : 2, 300, 400 +Bridge Address 8000.80a2.3526.0c5e + Root Address 8000.80a2.3526.0c5e + Port Root Path cost 0 Rem Hops 20 + +Ethernet46 is DESIGNATED FORWARDING +Port info port id 85 priority 128 cost 2000 +Designated Address 8000.80a2.3526.0c5e cost 0 +Designated bridge Address 8000.80a2.3526.0c5e port id 86 +Timers: forward transitions 0 +Bpdu send 80, received 0 + + +PortChannel1001 is DESIGNATED FORWARDING +Port info port id 25 priority 128 cost 2000 +Designated Address 8000.80a2.3526.0c5e cost 0 +Designated bridge Address 8000.80a2.3526.0c5e port id 45 +Timers: forward transitions 0 +Bpdu send 80, received 0 + +``` + + +- show spanning_tree mst instance + +``` +admin@sonic: show spanning_tree mst instance 0 + +####### MST0 (CIST) Vlans mapped : 1, 4-8, 202-4094 +Bridge Address 8000.80a2.3526.0c5e +Root Address 8000.80a2.3526.0c5e + Port Root Path cost 0 +Regional Root Address 8000.80a2.3526.0c5e + Internal cost 0 Rem hops 20 +Operational Hello Time 2, Forward Delay 15, Max Age 20, Txholdcount 6 +Configured Hello Time 2, Forward Delay 15, Max Age 20, Max Hops 20 + +Interface Role State Cost Prio.Nbr Type +--------------- -------- ---------- ------- --------- ----------- +Ethernet20 DESIGNATED FORWARDING 2000 128.25 P2P +Ethernet46 DESIGNATED FORWARDING 800 128.86 P2P +PortChannel1001 DESIGNATED FORWARDING 1000 128.45 P2P +``` + +- show spanning_tree mst interface + +``` +admin@sonic: show spanning_tree mst interface Ethernet46 + +Link Type: P2P Bpdu filter: False +Boundary : internal Bpdu guard: False + +Instance Role State Cost Prio.Nbr Vlans +--------------- -------- ---------- ------- --------- ----------- +0 DESIGNATED FORWARDING 800 128.86 1, 4-8, 202-4094 +1 DESIGNATED FORWARDING 1000 128.45 2, 300, 400 +``` + + +- show spanning_tree bpdu_guard + +``` +admin@sonic: show spanning_tree bpdu_guard + + +PortNum Shutdown Configured Port Shut due to BPDU Guard +--------- -------------------- ----------------------------- +Ethernet46 Yes Yes +PortChannel1001 No NA +``` + + +- show spanning_tree root_guard + +``` +admin@sonic: show spanning_tree root_guard + + +PortNum VLAN/MST Current State +--------- --------------------- --------------------------------------------- +Ethernet46 1, 4-8, 202-4094 Inconsistent state +PortChannel1001 Consistent state + + +``` + +- show spanning_tree mst instance \ interface \ + +``` +admin@sonic: show spanning_tree mst instance 0 interface Ethernet46 + + +Port Prio Path Edge State Role Designated Designated Designated +Num rity Cost Port Cost Root Bridge +Ethernet46 128 800 N FORWARDING Root 0 32768002438eefbc3 32768002438eefbc3 +``` + +### Statistics Commands +- show spanning_tree mst statistics instance \ + +``` + +admin@sonic: show spanning_tree mst statistics instance 0 + + +MSTP instance 0 (CIST) - VLANs 1, 4-8, 202-4094 +-------------------------------------------------------------------- +PortNum BPDU Tx BPDU Rx TCN Tx TCN Rx +Ethernet20 80 4 3 4 +Ethernet46 40 6 3 4 +PortChannel15 30 6 4 1 +``` + + +## Clear Commands +- sonic-clear spanning_tree statistics + +- sonic-clear spanning_tree mst statistics instance \ + + +## Debug Commands +Following debug commands will be supported for enabling additional logging which can be viewed in /var/log/stpd.log, orchagent related logs can be viewed in /var/log/syslog. + +- debug spanning_tree mst instance \ + +- debug spanning_tree bpdu [tx|rx] + +- debug spanning_tree event + +- debug spanning_tree verbose + +- debug spanning_tree interface \ + +Following debug commands will be supported for displaying internal data structures + +- debug spanning_tree dump global + +- debug spanning_tree dump mst instance \ + +# YANG Model + + Model will be extended as follows for MSTP: + +``` +module sonic-stp { + + yang-version 1.1; + + namespace "http://github.com/sonic-net/sonic-stp"; + prefix "stp"; + + import sonic-port { + prefix port; + revision-date 2019-07-01; + } + + import sonic-portchannel { + prefix lag; + revision-date 2021-06-13; + } + + import sonic-vlan { + prefix vlan; + revision-date 2021-04-22; + } + + import sonic-device_metadata { + prefix device_metadata; + revision-date 2021-02-27; + } + + description "STP yang Module for SONiC OS"; + + revision 2023-04-18 { + description "First Revision"; + } + + grouping interfaceAttr { + leaf path_cost { + type uint64 { + range "1..200000000" { + error-message "Invalid Port Path Cost value."; + } + } + Default 200; + description + "The port's contribution, when it is the Root Port, + to the Root Path Cost for the Bridge"; + } + + leaf priority { + type uint8 { + range "0..240" { + error-message "Invalid Port Priority value."; + } + } + Default 128; + description + "The manageable component of the Port Identifier, + also known as the Port Priority"; + } + + leaf link_type { + type enumeration { + enum "P2P" { + description "Point-to-Point link type."; + } + enum "Shared-Lan" { + description "Shared LAN link type."; + } + enum "Auto" { + description "Automatically determine link type."; + } + } + Default "Auto"; + description + "The type of link for the interface. Options include + P2P, Shared-Lan, or Auto."; + } + } + container sonic-stp { + + container STP_GLOBAL { + description "Global STP table"; + + leaf mode { + type enumeration { + enum "pvst"; + enum "mstp"; + } + description "STP mode"; + } + + leaf forward_delay { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "4..30" { + error-message "forward_delay value out of range"; + } + } + Default 15; + description "Forward delay in sec"; + } + + leaf hello_time { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "1..10" { + error-message "hello_time value out of range"; + } + } + Default 2; + description "Hello time in sec"; + } + + leaf max_age { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "6..40" { + error-message "max_age value out of range"; + } + } + Default 20; + description "Max age"; + } + + leaf rootguard_timeout { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint16 { + range "5..600" { + error-message "rootguard_timeout value out of range"; + } + } + Default 30; + description "Root guard timeout in sec"; + } + + leaf priority { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } + must ". mod 4096 = 0" { + error-message "bridge priority must be a multiple of 4096"; + } + + type uint16 { + range "0..61440" { + error-message "priority value out of range"; + } + } + Default 32768; + description "Bridge priority"; + } + } + + container STP_MST { + max-elements 1; + key "keyleaf"; + sonic-ext:dependent-on "STP_LIST"; + + leaf keyleaf { + type enumeration { + enum GLOBAL; + } + description + "Key node identifier. It's value is always GLOBAL"; + } + + leaf name { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type string { + length "1..32"; + } + description + "MST Region name"; + } + + leaf revision { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint16 { + range "0..65535" { + error-message "revision value out of range"; + } + } + description + "MST Revision number"; + } + + leaf max_hops { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "1..255" { + error-message "max-hops value out of range"; + } + } + Default 20; + description + "MST Max hops"; + } + + leaf hello_time { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "1..10" { + error-message "hello_time value out of range"; + } + } + Default 2; + description + "MST hello time"; + } + + leaf max_age { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "6..40" { + error-message "max_age value out of range"; + } + } + Default 20; + description + "MST max age"; + } + + leaf forward_delay { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Configuration allowed in MST mode"; + error-app-tag stp-invalid; + } + type uint8 { + range "4..30" { + error-message "forward_delay value out of range"; + } + } + Default 15; + description + "MST forward delay"; + } + } + container STP_MST_INST { + list STP_MST_INST_LIST { + key "instance"; + + leaf instance { + type uint16; + description + "Instance identifier"; + } + + leaf-list vlan { + type string; + description + "Vlan list"; + } + + leaf bridge_priority { + type uint16 { + range "0..61440" { + error-message "Invalid Bridge Priority value."; + } + } + Default 32768; + description + "The manageable component of the Bridge Identifier"; + } + } + } + + container STP_MST_PORT { + list STP_MST_PORT_LIST { + key "inst_id ifname"; + + leaf inst_id { + type leafref { + path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; + } + description + "Reference to MST Instance"; + } + + leaf ifname { + type leafref { + path "../../../STP_PORT/STP_PORT_LIST/ifname"; + } + description + "Reference to Ethernet interface or PortChannel in the STP database"; + } + uses interfaceAttr; + } + } + + list STP_MST_INST_TABLE_LIST { + sonic-ext:db-name "APPL_DB"; + key "inst_id"; + + leaf inst_id { + type leafref { + path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; + } + description + "Reference to MST Instance"; + } + + leaf-list vlan { + type string; + description + "Vlan list"; + } + + leaf bridge_priority { + type uint16; + description + "The manageable component of the Bridge Identifier"; + } + + leaf root_priority { + type string; + description + "The manageable component of the Port Identifier"; + } + + leaf root_address { + type string; + description + ""; + } + + leaf root_cost { + type string; + description + ""; + } + + leaf root_port { + type string; + description + ""; + } + + leaf bridge_address { + type string; + description + ""; + } + } + } +} +``` + +# Rest API Support + +Rest API is out of scope for this HLD. + +# Warm Boot +Warm boot will not be supported. The IEEE 802.1s standard of MSTP does not define any potential way to support it as this might cause loops in the network. + +User is expected to do a cold reboot when MSTP is running. If a user tries to perform a warm boot while MSTP is enabled, an error message will be displayed. User will first need to disable MSTP so the topology converges and reevaluates the paths. + + +# Testing Requirements + +## Unit Test Cases + +### CLI Test Cases + +1. Verify CLI to enable MSTP globally. + +2. Verify CLI to disable MSTP globally. + +3. Verify CLI to set MSTP region name. + +4. Verify CLI to set MSTP region revision. + +5. Verify CLI to set MSTP port priority. + +6. Verify CLI to set MSTP hello-time. + +7. Verify CLI to set MSTP cost-value. + +8. Verify CLI to set MSTP max-hops. + +9. Verify CLI to set MSTP root guard. + +10. Verify CLI to set MSTP BPDU guard. + +11. Verify CLI to set edge port. + +12. Verify CLI to create an instance. + +13. Verify CLI to delete an instance. + +14. Verify CLI to clear MSTP region name. + +15. Verify CLI to clear MSTP region revision. + +16. Verify CLI to clear MSTP port priority. + +17. Verify CLI to clear MSTP hello-time. + +18. Verify CLI to clear MSTP cost-value. + +19. Verify CLI to clear MSTP max-hops. + +20. Verify CLI to clear MSTP root guard. + +21. Verify CLI to clear MSTP BPDU guard. + +22. Verify CLI to clear bridge priority in an instance. + +23. Verify CLI to map VLAN to an instance. + +24. Verify CLI to delete VLAN from an instance. + +25. Verify CLI to set interface priority on a per-instance basis. + +26. Verify CLI to set interface cost on a per-instance basis. + +27. Verify CLI to display all information related to the region. + +28. Verify CLI to display information related to a specific instance. + +29. Verify CLI to display information about a specific interface in a specific instance. + +30. Verify CLI to display statistics. + +31. Verify CLI to display statistics on a per-instance basis. + +32. Verify CLI to clear statistics. + +33. Verify CLI to clear statistics on a per-instance basis. + +34. Verify CLI to clear statistics on a per-interface per-instance basis. + +35. Verify the commands that are disabled for MSTP mode. + +### Functional Test Cases + +1. Verify CONFIG DB is populated with configured MSTP parameters. + +2. Verify MSTP instances running on multiple VLANs. + +3. Verify multiple VLANs can be mapped to a single instance. + +4. Verify VLAN to STP instance mapping is populated correctly in APP DB, ASIC DB, and Hardware. + +5. Verify instance STP ports are created for its VLAN members. + +6. Verify correct format of MSTP BPDU. + +7. Verify MSTP traps are created. + +8. Verify correct operation of CIST and MSTIs. + +9. Verify two bridges are in the same region only if they have the same region name, revision, and instance to VLAN mapping. + +10. Verify the loop-free topology inside and between regions. + +11. Verify the operational values of forward delay, max age, hello timer, and max hops are of the CIST root. + +12. Verify FDB flush as a result of topology change. + +13. Verify instance is active only when there is at least one VLAN member of any of the VLANs that are mapped to it. + +14. Verify altering bridge priority can alter the selection of CIST root, regional root, and MSTI root. + +15. Verify altering port priority can alter the selection of designated port. + +16. Verify max-hops by changing value. + +17. Verify hello-timer by changing timer values. + +18. Verify max-age by changing intervals. + +19. Verify altering bridge priority will alter Root Bridge selection. + +20. Verify altering port priority will alter Root port selection. + +21. Verify altering port priority will alter Designated port selection. + +22. Verify altering port cost results in the path with the lowest root path cost being selected as the root port. + +23. Verify port states on the same physical interface. + +24. Verify MSTP interoperability with STP and RSTP. + +25. Verify MSTP operational data is synced to APP DB and ASIC DB correctly. + +26. Verify MSTP over LAG. + +27. Verify MSTP over static breakout ports. + +28. Verify BPDU Guard Activation on Ports. + +29. Verify BPDU Guard Port State Transition. + +30. Verify BPDU Guard Recovery Mechanism. + +31. Verify BPDU Guard and MSTP Interaction. + +32. Verify MSTP Topology Changes Detection. + +33. Verify MSTP and VLAN Integration. + +34. Verify MSTP Path Cost Calculation. + +35. Verify MSTP Failover. + +### Logging and Debugging Test Cases + +1. Verify debugging logs for a region. + +2. Verify debugging logs for an instance. + +3. Verify debugging of internal data structure of a region. + +4. Verify debugging of internal data structure of an instance. + +5. Verify debugging of internal data structure of a specific interface in an instance. + +### SAI + +1. Verify creation of STP instance. + +2. Verify adding VLAN to an instance. + +3. Verify deleting VLAN from an instance. + +4. Verify adding a port to an instance. + +5. Verify deleting a port from an instance. + +6. Verify port state for different instances. + +### L3 + +1. Verify normal flow of L3 traffic with the MSTP topology. diff --git a/SONiC_PVST_HLD.md b/SONiC_PVST_HLD.md new file mode 100644 index 00000000000..aaef99aaf15 --- /dev/null +++ b/SONiC_PVST_HLD.md @@ -0,0 +1,746 @@ +# Feature Name +PVST +# High Level Design Document +#### Rev 1.0 + +# Table of Contents + * [List of Tables](#list-of-tables) + * [Revision](#revision) + * [About This Manual](#about-this-manual) + * [Scope](#scope) + * [Definition/Abbreviation](#definitionabbreviation) + * [Requirements Overview](#requirement-overview) + * [Functional Requirements](#functional-requirements) + * [Configuration and Management Requirements](#configuration-and-management-requirements) + * [Scalability Requirements](#scalability-requirements) + * [Warm Boot Requirements](#warm-boot-requirements) + * [Functionality](#-functionality) + * [Functional Description](#functional-description) + * [Design](#design) + * [Overview](#overview) + * [DB Changes](#db-changes) + * [CONFIG DB](#config-db) + * [APP DB](#app-db) + * [STATE DB](#state-db) + * [Switch State Service Design](#switch-state-service-design) + * [Orchestration Agent](#orchestration-agent) + * [STP Container](#stp-container) + * [SAI](#sai) + * [CLI](#cli) + * [Configuration Commands](#configuration-commands) + * [Show Commands](#show-commands) + * [Debug Commands](#debug-commands) + * [Clear Commands](#clear-commands) + * [Flow Diagrams](#flow-diagrams) + * [Serviceability and Debug](#serviceability-and-debug) + * [Warm Boot Support](#warm-boot-support) + * [Scalability](#scalability) + * [Unit Test](#unit-test) + +# List of Tables +[Table 1: Abbreviations](#table-1-abbreviations) + +# Revision +| Rev | Date | Author | Change Description | +|:---:|:-----------:|:-------------------------:|-----------------------------------| +| 0.1 | 05/02/2019 | Sandeep, Praveen | Initial version | +| 0.2 | 05/02/2019 | Sandeep, Praveen | Incorporated Review comments | +| 0.3 | 06/25/2019 | Sandeep, Praveen | Incorporated Review comments | +| 1.0 | 10/15/2019 | Sandeep, Praveen | Minor changes post implementation | + + +# About this Manual +This document provides general information about the PVST (Per VLAN spanning tree) feature implementation in SONiC. +# Scope +This document describes the high level design of PVST feature. + +# Definition/Abbreviation +### Table 1: Abbreviations +| **Term** | **Meaning** | +|--------------------------|-------------------------------------| +| BPDU | Bridge protocol data unit | +| PVST | Per VLAN Spanning tree | +| STP | Spanning tree protocol | + + +# 1 Requirement Overview +## 1.1 Functional Requirements + + + 1. Support PVST+ per VLAN spanning tree + 2. Support Portfast functionality + 3. Support Uplink fast functionality + 4. Support BPDU guard functionality + 5. Support Root guard functionality + 6. Bridge-id should include the VLAN id of the pvst instance along with bridge MAC address to derive a unique value for each instance. + 7. Port channel path cost will be same as the member port cost, it will not be cumulative of member ports cost + 8. DA MAC in case of PVST should be cisco pvst mac - 01:00:0C:CC:CC:CD + 9. Support protocol operation on static breakout ports + 10. Support protocol operation on Port-channel interfaces + + +## 1.2 Configuration and Management Requirements +This feature will support CLI and REST based configurations. + 1. Support CLI configurations as mentioned in section 3.6.2 + 2. Support show commands as mentioned in section 3.6.3 + 3. Support debug commands as mentioned in section 3.6.4 + 4. Support Openconfig yang model - with extensions for supporting PVST + 5. Support REST APIs for config and operational data + +## 1.3 Scalability Requirements +16k port-vlan instances with max 255 STP instances. +The scaling limit might differ depending on the platform and the CPU used, which needs to be determined based on testing. + +## 1.4 Warm Boot Requirements + +Warm boot is not supported in this release. User is expected to do cold reboot when PVST is running so that topology will reconverge and traffic will be redirected via alternate paths. + +If PVST is enabled and user tries to perform warm reboot an error will be displayed indicating PVST doesnt support warm reboot. + + +# 2 Functionality + +## 2.1 Functional Description +The Spanning Tree Protocol (STP) prevents Layer 2 loops in a network and provides redundant links. If a primary link fails, the backup link is activated and network traffic is not affected. STP also ensures that the least cost path is taken when multiple paths exist between the devices. + +When the spanning tree algorithm is run, the network switches transform the real network topology into a spanning tree topology. In an STP topology any LAN in the network can be reached from any other LAN through a unique path. The network switches recalculate a new spanning tree topology whenever there is a change to the network topology. + +For each switch in the topology, a port with lowest path cost to the root bridge is elected as root port. + +For each LAN, the switches that attach to the LAN select a designated switch that is the closest to the root switch. The designated switch forwards all traffic to and from the LAN. The port on the designated switch that connects to the LAN is called the designated port. The switches decide which of their ports is part of the spanning tree. A port is included in the spanning tree if it is a root port or a designated port. + +PVST+ allows for running multiple instances of spanning tree on per VLAN basis. + +One of the advantage with PVST is it allows for load-balancing of the traffic. When a single instance of spanning tree is run and a link is put into blocking state for avoiding the loop, it will result in inefficient bandwidth usage. With per VLAN spanning tree multiple instances can be run such that for some of the instances traffic is blocked over the link and for other instances traffic is forwared allowing for load balancing of traffic. + +PVST+ support allows the device to interoperate with IEEE STP and also tunnel the PVST+ BPDUs transparently across IEEE STP region to potentially connect other PVST+ switches across the IEEE STP region. For interop with IEEE STP, PVST+ will send untagged IEEE BPDUs (MAC - 01:80:C2:00:00:00) with information corresponding to VLAN 1. The STP port must be a member of VLAN 1 for interoperating with IEEE STP. + +# 3 Design +## 3.1 Overview + +![STP](images/STP_Architecture.png "Figure 1: High level architecture") +__Figure 1: High level architecture__ + +High level overview: + +STP container will host STPMgr and STPd process. + +STPMgr will handle all the STP configurations and VLAN configurations via config DB and state DB respectively. + +STPd process will handle all the protocol functionality and has following interactions + + * Linux kernel for packet tx/rx and netlink events + * STPMgr interaction for configuration handling + * STPSync is part of STPd handling all the STP operational data updates to APP DB + +Alternate design consideration: +Linux kernel has support for spanning-tree but is not being considered for following reasons + * Supports only STP, no support for RSTP and MSTP + * Currently SONiC does not create a netdevice for each vlan, port combination as it relies on vlan aware bridge configuration. For supporting per VLAN spanning tree a netdevice needs to be created for each vlan, port combination, this will result in higher memory requirements due to additional netdevices and also a major change from SONiC perspective. + +## 3.2 DB Changes +This section describes the changes made to different DBs for supporting the PVST protocol. +### 3.2.1 CONFIG DB +Following config DB schemas are defined for supporting this feature. +### STP_GLOBAL_TABLE + ;Stores STP Global configuration + ;Status: work in progress + key = STP|GLOBAL ; Global STP table key + mode = "pvst" ; spanning-tree mode pvst + rootguard_timeout = 3*DIGIT ; root-guard timeout value (5 to 600 sec, DEF:30 sec) + forward_delay = 2*DIGIT ; forward delay in secs (4 to 30 sec, DEF:15 sec) + hello_time = 2*DIGIT ; hello time in secs (1 to 10 sec, DEF:2sec) + max_age = 2*DIGIT ; maximum age time in secs (6 to 40 sec, DEF:20sec) + priority = 5*DIGIT ; bridge priority (0 to 61440, DEF:32768) + +### STP_VLAN_TABLE + ;Stores STP configuration per VLAN + ;Status: work in progress + key = STP_VLAN|"Vlan"vlanid ; VLAN with prefix "STP_VLAN" + forward_delay = 2*DIGIT ; forward delay in secs (4 to 30 sec, DEF:15 sec) + hello_time = 2*DIGIT ; hello time in secs (1 to 10 sec, DEF:2sec) + max_age = 2*DIGIT ; maximum age time in secs (6 to 40 sec, DEF:20sec) + priority = 5*DIGIT ; bridge priority (0 to 61440, DEF:32768) + enabled = "true"/"false" ; spanning-tree is enabled or not + +### STP_VLAN_INTF_TABLE + ;Stores STP interface details per VLAN + ;Status: work in progress + key = STP_VLAN_INTF|"Vlan"vlanid|ifname ; VLAN+Intf with prefix "STP_VLAN_INTF" ifname can be physical or port-channel name + path_cost = 9*DIGIT ; port path cost (1 to 200000000) + priority = 3*DIGIT ; port priority (0 to 240, DEF:128) + +### STP_INTF_TABLE + ;Stores STP interface details + ;Status: work in progress + key = STP_INTF|ifname ; ifname with prefix STP_INTF, ifname can be physical or port-channel name + enabled = BIT ; is the STP on port enabled (1) or disabled (0) + root_guard = BIT ; is the root guard on port enabled (1) or disabled (0) + bpdu_guard = BIT ; is the bpdu guard on port enabled (1) or disabled (0) + bpdu_guard_do_disable = BIT ; port to be disabled when it receives a BPDU; enabled (1) or disabled (0) + path_cost = 9*DIGIT ; port path cost (2 to 200000000) + priority = 3*DIGIT ; port priority (0 to 240, DEF:128) + portfast = BIT ; Portfast is enabled or not + uplink_fast = BIT ; Uplink fast is enabled or not + +### 3.2.2 APP DB + +### STP_VLAN_TABLE + ;Stores the STP per VLAN operational details + ;Status: work in progress + key = STP_VLAN:"Vlan"vlanid + bridge_id = 16HEXDIG ; bridge id + max_age = 2*DIGIT ; maximum age time in secs (6 to 40 sec, DEF:20sec) + hello_time = 2*DIGIT ; hello time in secs (1 to 10 sec, DEF:2sec) + forward_delay = 2*DIGIT ; forward delay in secs (4 to 30 sec, DEF:15 sec) + hold_time = 1*DIGIT ; hold time in secs (1 sec) + last_topology_change = 1*10DIGIT ; time in secs since last topology change occured + topology_change_count = 1*10DIGIT ; Number of times topology change occured + root_bridge_id = 16HEXDIG ; root bridge id + root_path_cost = 1*9DIGIT ; port path cost + desig_bridge_id = 16HEXDIG ; designated bridge id + root_port = ifName ; Root port name + root_max_age = 1*2DIGIT ; Max age as per root bridge + root_hello_time = 1*2DIGIT ; hello time as per root bridge + root_forward_delay = 1*2DIGIT ; forward delay as per root bridge + stp_instance = 1*4DIGIT ; STP instance for this VLAN + +### STP_VLAN_INTF_TABLE + ;Stores STP VLAN interface details + ;Status: work in progress + key = STP_VLAN_INTF:"Vlan"vlanid:ifname ; VLAN+Intf with prefix "STP_VLAN_INTF" + port_num = 1*3DIGIT ; port number of bridge port + path_cost = 1*9DIGIT ; port path cost (1 to 200000000) + priority = 3*DIGIT ; port priority (0 to 240, DEF:128) + port_state = "state" ; STP state - disabled, block, listen, learn, forward + desig_cost = 1*9DIGIT ; designated cost + desig_root = 16HEXDIG ; designated root + desig_bridge = 16HEXDIG ; designated bridge + desig_port = 1*3DIGIT ; designated port + fwd_transitions = 1*5DIGIT ; number of forward transitions + bpdu_sent = 1*10DIGIT ; bpdu transmitted + bpdu_received = 1*10DIGIT ; bpdu received + tcn_sent = 1*10DIGIT ; tcn transmitted + tcn_received = 1*10DIGIT ; tcn received + root_guard_timer = 1*3DIGIT ; root guard current timer value + +### STP_INTF_TABLE + ;Stores STP interface details + ;Status: work in progress + key = STP_INTF:ifname ; ifname with prefix STP_INTF, ifname can be physical or port-channel name + bpdu_guard_shutdown = "yes" / "no" ; port disabled due to bpdu-guard + port_fast = "yes" / "no" ; port fast is enabled or not + + +### STP_PORT_STATE_TABLE + ;Stores STP port state per instance + ;Status: work in progress + key = STP_PORT_STATE:ifname:instance ; ifname and the STP instance + state = 1DIGIT ; 0-disabled, 1-block, 2-listen, 3-learn, 4-forward + + +### STP_VLAN_INSTANCE_TABLE + ;Defines VLANs and the STP instance mapping + ;Status: work in progress + key = STP_VLAN_INSTANCE_TABLE:"Vlan"vlanid ; DIGIT 1-4095 with prefix "Vlan" + stp_instance = 1*4DIGIT ; STP instance associated with this VLAN + + +### STP_FASTAGEING_FLUSH_TABLE + ;Defines vlans for which fastageing is enabled + ;Status: work in progress + key = STP_FASTAGEING_FLUSH_TABLE:"Vlan"vlanid ; vlan id for which flush needs to be done + state = "true" ; true perform flush + +### 3.2.3 STATE DB + +### STP_TABLE + ;Defines the global STP state table + ;Status: work in progress + key = STP_TABLE:GLOBAL ; key + max_stp_inst = 1*3DIGIT ; Max STP instances supported by HW + + +## 3.3 Switch State Service Design +### 3.3.1 Orchestration Agent + +All STP operations for programming the HW will be handled as part of OrchAgent. OrchAgent will listen to below updates from APP DB for updating the ASIC DB via SAI REDIS APIs. + + * Port state udpate - STP_PORT_STATE_TABLE + + * VLAN to instance mapping - STP_VLAN_INSTANCE_TABLE + +Orchagent will also listen to updates related to Fast ageing on APP DB. When fast ageing is set for the VLAN due to topology change, Orchagent will perform FDB/MAC flush for the VLAN. + + * FDB/MAC flush - STP_FASTAGEING_FLUSH_TABLE + + + +## 3.4 STP Container + +STP container will have STPMgr and STPd processes. + +STPMgr process will register with the config DB for receiving all the STP configurations and with state DB for VLAN configurations. STPMgr will notify this configuration information to STPd for protocol operation. STPMgr will also handle the STP instance allocation. + +STPd process will handle following interactions. STPd will use libevent for processing the incoming events and timers. +1) Packet processing + + * Socket of PF_PACKET type will be created for packet tx/rx + + * Filters will be attached to the socket to receive the STP BPDUs based on DA MAC + + * PACKET_AUXDATA socket option will be set to get the VLAN id of the packet received from the cmsg headers + +2) Configuration - All STP CLI and VLAN configurations will be received from STPMgr via unix domain socket +3) Timers handling - Timer events are generated every 100ms for handling STP protocol timers +4) Port events - Netlink socket interface for processing create/delete of port, lag interface, lag member add/delete, link state changes and port speed +5) Operational updates - STPsync is part of STPd and handles all the updates to APP DB. All DB interactions are detailed in the Section 4. +6) STP Port state sync to linux kernel - Currently the vlan aware bridge doesnt support programming the STP state into linux bridge. As a workaround, when STP state is not forwarding, corresponding VLAN membership on that port will be removed to filter the packets on blocking port. + +### Interface DB: + +In SONiC, ethernet interface is represented in the format Ethernet where id represents the physical port number and port-channel is represented by PortChannel where id is a 4 digit numerical value. + +STPd implementation makes use of its own internal port id for its protocol operation. These port ids are used for bit representation in port masks and also for indexing the array which holds the pointers to STP port level information. So to continue using these mechanisms it is required to convert the SONiC representation of interface to local STP port ids. So when STPd interacts with other components in the system local port id will be converted to SONiC interface name, similarly all messages received from other components with SONiC interface name will be converted to local STP port id before processing. For this purpose an interface DB (AVL tree) will be maintained to map the SONiC interface names to local STP port ids. + + + +### Local STP Port id allocation: + +For allocating local port ids STPd needs to know the max number of physical ports and Port-channel interfaces supported on the device. Currently there is no mechanism to obtain these values in a direct way (like reading from DBs) so below logic will be used to arrive at max ports - + +Max STP Ports = Max physical ports + Max Port-Channel interfaces + +where, + +Max physical ports will be determined from the higher interface id populated say for example if higher port is Ethernet252 (or 254) - max ports will be 256 to ensure breakout ports are accomodated. + +Max Port-Channel interfaces will be same as max physical ports to accomodate the worst case scenario of each Port-channel having only one port. + + +Post bootup, Portsyncd reads the port_config.ini file which contains the port specific configuration information, and updates the APP DB with this information. Orchagent listens to these APP DB updates and takes care of creating all the interfaces in linux kernel and the hardware. Kernel sends netlink updates for the interfaces being created which Portsyncd listens to, once Portsyncd confirms all the interfaces have been configured it will generate PortInitDone notification. STPd will receive this message via STPMgr and then gets all the interface information via netlink for allocating the local STP port ids. + +Note: The port id for Port-channel interface will be allocated only when the first member port is added, this ensures Port-channel interfaces with no member ports dont burn the port ids. + +Example of port id allocation - +``` +SONiC interface STP Port id +Ethernet0 0 +Ethernet4 4 +Ethernet8 8 +Ethernet252 252 +PortChannel10 256 +PortChannel5 257 +PortChannel20 258 +``` + +Note: As Port-channel port ids are dynamically allocated it might result in same port channel getting different value post reboot. To ensure a predictable convergence where port-channel port id is used as tie breaker, user needs to configure appropriate port priority value. + +### 3.4.1 BPDU trap mechanism +SONiC uses copp configuration file 00-copp.config.json for configuring the trap group, ids, cpu priority queue and a policer. This functionality has been extended for supporting STP and PVST BPDU trap to CPU. + +## 3.5 SAI +STP SAI interface APIs are already defined and is available at below location - + +https://github.com/opencomputeproject/SAI/blob/master/inc/saistp.h + +Control packet traps required for STP (SAI_HOSTIF_TRAP_TYPE_STP) and PVST (SAI_HOSTIF_TRAP_TYPE_PVRST) are defined in below SAI spec - + +https://github.com/opencomputeproject/SAI/blob/master/inc/saihostif.h + +## 3.6 CLI +### 3.6.1 Data Models +Openconfig STP yang model will be extended to support PVST. + +### 3.6.2 Configuration Commands + +### 3.6.2.1 Global level + +### 3.6.2.1.1 Enabling or Disabling of PVST feature - Global spanning-tree mode +This command allows enabling the spanning tree mode for the device. + +**config spanning_tree {enable|disable} {pvst}** + +Note: +1) When global pvst mode is enabled, by default spanning tree will be enabled on the first 255 VLANs, for rest of the VLAN spanning tree will be disabled. +2) When multiple spanning-tree modes are supported, only one mode can be enabled at any given point of time. + +### 3.6.2.1.2 Per VLAN spanning-tree +This command allows enabling or disabling spanning-tree on a VLAN. + +**config spanning_tree vlan {enable|disable} ** + + ### 3.6.2.1.3 Root-guard timeout + +This command allows configuring a root guard timeout value. Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state(default = 30 secs), range 5-600. + +**config spanning_tree root_guard_timeout ** + + ### 3.6.2.1.4 Forward-delay + +This command allows configuring the forward delay time in seconds (default = 15), range 4-30. + +**config spanning_tree forward_delay ** + + ### 3.6.2.1.5 Hello interval +This command allow configuring the hello interval in secs for transmission of bpdus (default = 2), range 1-10. + +**config spanning_tree hello ** + + ### 3.6.2.1.6 Max-age +This command allows configuring the maximum time to listen for root bridge in seconds (default = 20), range 6-40. + +**config spanning_tree max_age ** + + ### 3.6.2.1.7 Bridge priority +This command allows configuring the bridge priority in increments of 4096 (default = 32768), range 0-61440. + +**config spanning_tree priority ** + + ### 3.6.2.2 VLAN level +Below commands are similar to the global level commands but allow configuring on per VLAN basis. + +**config spanning_tree vlan forward_delay ** + +**config spanning_tree vlan hello ** + +**config spanning_tree vlan max_age ** + +**config spanning_tree vlan priority ** + + ### 3.6.2.3 VLAN, interface level +Below configurations allow STP parameters to be configured on per VLAN, interface basis. + + ### 3.6.2.3.1 Port Cost +This command allows to configure the port level cost value for a VLAN, range 1 - 200000000 + +**config spanning_tree vlan interface cost ** + + ### 3.6.2.3.2 Port priority +This command allows to configure the port level priority value for a VLAN, range 0 - 240 (default 128) + +**config spanning_tree vlan interface priority ** + + ### 3.6.2.4 Interface level + + ### 3.6.2.4.1 STP enable/disable on interface + +This command allows enabling or disabling of STP on an interface, by default STP will be enabled on the interface if global STP mode is configured. + +**config spanning_tree interface {enable|disable} ** + + ### 3.6.2.4.2 Root Guard: +The Root Guard feature provides a way to enforce the root bridge placement in the network and allows STP to interoperate with user network bridges while still +maintaining the bridged network topology that the administrator requires. When BPDUs are received on a root guard enabled port, the STP state will be moved to "Root inconsistent" state to indicate this condition. Once the port stops receiving superior BPDUs, Root Guard will automatically set the port back to a FORWARDING state after the timeout period has expired. + +This command allow enabling or disabling of root guard on an interface. + +**config spanning_tree interface root_guard {enable|disable} ** + +Following syslogs will be generated when entering and exiting root guard condition respectively - + +STP: Root Guard interface Ethernet4, VLAN 100 inconsistent (Received superior BPDU) + +STP: Root Guard interface Ethernet4, VLAN 100 consistent (Timeout) + + ### 3.6.2.4.3 BPDU Guard +BPDU Guard feature disables the connected device ability to initiate or participate in STP on edge ports. When STP BPDUs are received on the port where BPDU guard is enabled the port will be shutdown. User can re-enable the port administratively after ensuring the BPDUs have stopped coming on the port. + +Below command allows enabling or disabling of bpdu guard on an interface. + +**config spanning_tree interface bpdu_guard {enable|disable} ** + + +By default, BPDU guard will only generate a syslog indicating the condition, for taking an action like disabling the port below command can be used with shutdown option + +**config spanning_tree interface bpdu_guard {enable|disable} [--shutdown | -s]** + +Following syslog will be generated when BPDU guard condition is entered - + +STP: Tagged BPDU(100) received, interface Ethernet4 disabled due to BPDU guard trigger + +STPd will update the config DB for shutting down the interface, user can enable the interface back once it has stopped receiving the BPDUs. + + ### 3.6.2.4.4 Port fast +Portfast command is enabled by default on all ports, portfast allows edge ports to move to forwarding state quickly when the connected device is not participating in spanning-tree. + +Below command allows enabling or disabling of portfast on an interface. + +**config spanning_tree interface portfast {enable|disable} ** + + ### 3.6.2.4.4 Uplink fast + Uplink fast feature enhances STP performance for switches with redundant uplinks. Using the default value for the standard STP forward delay, convergence following a transition from an active link to a redundant link can take 30 seconds (15 seconds for listening and an additional 15 seconds for learning). + +When uplink fast is configured on the redundant uplinks, it reduces the convergence time to just one second by moving to forwarding state (bypassing listening and learning modes) in just once second when the active link goes down. + +**config spanning_tree interface uplink_fast {enable|disable} ** + + ### 3.6.2.4.5 Port level priority +This command allows to configure the port level priority value, range 0 - 240 (default 128) + +**config spanning_tree interface priority ** + + ### 3.6.2.4.6 Port level path cost +This command allows to configure the port level cost value, range 1 - 200000000 + +**configure spanning_tree interface cost ** + + + +### 3.6.3 Show Commands +- show spanning_tree +- show spanning_tree vlan +- show spanning_tree vlan interface + +``` +Spanning-tree Mode: PVST +VLAN 100 - STP instance 3 +-------------------------------------------------------------------- +STP Bridge Parameters: + +Bridge Bridge Bridge Bridge Hold LastTopology Topology +Identifier MaxAge Hello FwdDly Time Change Change +hex sec sec sec sec sec cnt +8000002438eefbc3 20 2 15 1 0 0 + +RootBridge RootPath DesignatedBridge Root Max Hel Fwd +Identifier Cost Identifier Port Age lo Dly +hex hex sec sec sec +8000002438eefbc3 0 8000002438eefbc3 Root 20 2 15 + +STP Port Parameters: + +Port Prio Path Port Uplink State Designated Designated Designated +Num rity Cost Fast Fast Cost Root Bridge +Ethernet13 128 4 Y N FORWARDING 0 8000002438eefbc3 8000002438eefbc3 +``` + +- show spanning_tree bpdu_guard +This command displays the interfaces which are BPDU guard enabled and also the state if the interface is disabled due to BPDU guard. +``` +show spanning_tree bpdu_guard +PortNum Shutdown Port shut + Configured due to BPDU guard +------------------------------------------------- +Ethernet1 Yes Yes +Ethernet2 Yes No +Port-Channel2 No NA +``` + +-show spanning_tree root_guard +This command displays the interfaces where root guard is active and the pending time for root guard timer expiry +``` +Root guard timeout: 120 secs + +Port VLAN Current State +------------------------------------------------- +Ethernet1 1 Inconsistent state (102 seconds left on timer) +Ethernet8 100 Consistent state +``` + +- show spanning_tree statistics +- show spanning_tree statistics vlan +This command displays the spanning-tree bpdu statistics. Statistics will be synced to APP DB every 10 seconds. +``` +VLAN 100 - STP instance 3 +-------------------------------------------------------------------- +PortNum BPDU Tx BPDU Rx TCN Tx TCN Rx +Ethernet13 10 4 3 4 +PortChannel15 20 6 4 1 +``` + + +### 3.6.4 Debug Commands +Following debug commands will be supported for enabling additional logging which can be viewed in /var/log/stpd.log, orchangent related logs can be viewed in /var/log/syslog. +- debug spanning_tree - This command must be enabled for logs to be written to log file, after enabling any of the below commands. +- debug spanning_tree bpdu [tx|rx] +- debug spanning_tree event +- debug spanning_tree interface +- debug spanning_tree verbose +- debug spanning_tree vlan + +To disable the debugging controls enabled '-d' or '--disable' option can be used, an example of disabling bpdu debugging is shown below - +- debug spanning_tree bpdu -d + +Follow commands can be used to reset and display the debugging controls enabled respectively +- debug spanning_tree reset +- debug spanning_tree show + +Following debug commands will be supported for displaying internal data structures +- debug spanning_tree dump global +- debug spanning_tree dump vlan +- debug spanning_tree dump interface + +### 3.6.5 Clear Commands +Following clear commands will be supported +- sonic-clear spanning_tree statistics +- sonic-clear spanning_tree statistics vlan +- sonic-clear spanning_tree statistics vlan-interface +- sonic-clear spanning_tree statistics interface + +### 3.6.6 REST API Support +REST APIs is not supported in this release + +# 4 Flow Diagrams + +## 4.1 Global spanning-tree mode + +![STP](images/Global_PVST_enable.png "Figure 2: Global PVST mode enable") + +__Figure 2: Global PVST mode enable__ + +![STP](images/Global_PVST_disable.png "Figure 3: Global PVST mode disable") + +__Figure 3: Global PVST mode disable__ + +## 4.2 Per VLAN spanning-tree +![STP](images/STP_VLAN_enable.png "Figure 4: STP VLAN enable") + +__Figure 4: STP VLAN enable__ + +![STP](images/STP_disable_VLAN.png "Figure 5: STP VLAN disable") + +__Figure 5: STP VLAN disable__ + +## 4.3 STP enable/disable on interface +![STP](images/STP_enable_interface.png "Figure 6: STP enable on an interface") + +__Figure 6: STP enable on an interface__ + +![STP](images/STP_disable_on_interface.png "Figure 7: STP disable on an interface") + +__Figure 7: STP disable on an interface__ + +## 4.4 STP port state update +![STP](images/STP_Port_state.png "Figure 8: STP port state update") + +__Figure 8: STP port state update__ + +## 4.5 STP Topology change +![STP](images/Topology_change_update.png "Figure 9: STP Topology change") + +__Figure 9: STP Topology change__ + +## 4.6 STP Port id allocation +![STP](images/STP_Port_id_allocation.png "Figure 10: STP Port id allocation") + +__Figure 10: STP Port id allocation__ + +# 5 Serviceability and Debug +Debug command and statistics commands as mentioned in Section 3.6.3 and 3.6.4 will be supported. Debug command output will be captured as part of techsupport. + +# 6 Warm Boot Support +Warm boot is not supported + +# 7 Scalability +16k port-vlan instances with max 255 STP instances. +The scaling limit might differ depending on the platform and the CPU used, which needs to be determined based on testing. + +# 8 Unit Test + +CLI: +1) Verify CLI to enable spanning-tree globally +2) Verify CLI to enable spanning-tree per VLAN +3) Verify CLI to enable spanning-tree on interface +4) Verify CLI to set Bridge priority +5) Verify CLI to set Bridge forward-delay +6) Verify CLI to set Bridge hello-time +7) Verify CLI to set Bridge max-age +8) Verify CLI to set Bridge Port path cost +9) Verify CLI to set Bridge Port priority +10) Verify CLI to set Bridge root guard +11) Verify CLI to set Bridge root guard timeout +12) Verify CLI to set Bridge bpdu guard +13) Verify CLI to set Bridge bpdu guard with do-disable action +14) Verify CLI to set portfast +15) Verify CLI to set uplink fast +16) Verify CLI to clear uplink fast +17) Verify CLI to clear portfast +18) Verify CLI to clear Bridge bpdu guard with do-disable action +19) Verify CLI to clear Bridge bpdu guard +20) Verify CLI to clear Bridge root guard timeout +21) Verify CLI to clear Bridge root guard +22) Verify CLI to clear Bridge Port priority +23) Verify CLI to clear Bridge Port path cost +24) Verify CLI to clear Bridge max-age +25) Verify CLI to clear Bridge hello-time +26) Verify CLI to clear Bridge forward-delay +27) Verify CLI to clear Bridge priority +28) Verify CLI to disabling spanning-tree on interface +29) Verify CLI to disabling spanning-tree per VLAN +30) Verify CLI to disabling spanning-tree globally +31) Verify CLI to display spanning-tree running config +32) Verify CLI to display spanning-tree state information +33) Verify CLI to display spanning-tree statistics +34) Verify CLI to display bpdu-guard port information +35) Verify CLI for clear spanning tree statistics + +Functionality +1) Verify Config DB is populated with configured STP values +2) Verify PVST instances running on multiple VLANs +3) Verify VLAN to STP instance mapping is populated correctly in APP DB, ASIC DB, Hardware +4) Verify spanning-tree port state updates for the VLANs are populated correctly in APP DB, ASIC DB, Hardware +5) Verify during topology change fast ageing updates in APP DB and also MAC flush is performed +6) Verify BPDU format of the packets are correct +7) Verify traffic with stp convergence and loops are prevented where there are redundant paths in topology +8) Verify load balancing functionality with multiple spanning tree instances +9) Verify adding port to VLAN after spanning-tree is enabled on the VLAN and verify port state updates +10) Verify deleting port from VLAN running PVST and verify re-convergence is fine +11) Verify BUM traffic forwarding with spanning-tree running +12) Verify forward-delay by changing intervals +13) Verify hello-time timers +14) Verify max-age by changing intervals +15) Verify altering bridge priority will alter Root Bridge selection +16) Verify altering port priority will alter Designated port selection +17) Verify altering port cost results in path with lowest root path cost is seleced as root port +18) Verify port states on same physical interface for multiple STP instances configured +19) Verify Topology change functionality and spanning-tree reconvergence by disabling/enabling links +20) Verify spanning-tree behavior after adding few more VLANs +21) Verify spanning-tree behavior after removing some of the VLANs +22) Verify rebooting one of the nodes in the topology and verify re-convergence and traffic takes alternate path +23) Verify port cost values chosen are correct as per the interface speed +24) Verify Root guard functionality +25) Verify BPDU guard functionality, verify BPDU guard with do-disable functionality +26) Verify Portfast functionality +27) Verify Uplink fast functionality +28) Verify PVST and STP traps are created after switch reboot +29) Verify PVST behavior when spanning-tree disabled on VLAN, verify APP DB, ASIC DB, hardware are populated correctly +30) Verify global spanning-tree disable, verify APP DB, ASIC DB, hardware are populated correctly +31) Verify spanning tree config save and reload, verify topology converges is same as before reboot +32) Verify PVST convergence over untagged ports +33) Verify PVST interop with IEEE STP +35) Verify bridge id encoding includes the VLAN id of the respective PVST instance +36) Verify PVST operational data is sync to APP DB +37) Verify PVST over static breakout ports + +Scaling +1) Verify running 255 PVST instances +2) Verify 16k vlan,port scaling + +Logging and debugging +1) Verify debug messages are logged in /var/log/syslog +2) Verify changing log level +3) Verify Pkt Tx/Rx Debug +4) Verify STP debug commands +5) Verify debug commands output is captured in techsupport + +REST +1) Verify all REST commands + +PVST over LAG +1) Verify PVST behavior over LAG +2) Verify adding port to LAG will not flap the protocol +3) Verify deleting a port from LAG will not flap the protocol +4) Verify BPDU is sent only from one of the LAG member port +5) Verify adding LAG to VLAN running PVST +6) Verify deleting LAG from VLAN running PVST + +SAI +1) Verify creating STP instance and ports in SAI +2) Verify adding VLAN to STP instance in SAI +3) Verify updating PortState in SAI +4) Verify deleting VLAN from STP instance in SAI +5) Verify deleting STP instance and ports in SAI + +L3 +1) Verify L3 traffic with PVST in topology diff --git a/SONiC_YANG_Model_Guidelines.md b/SONiC_YANG_Model_Guidelines.md new file mode 100644 index 00000000000..9d03f1296d4 --- /dev/null +++ b/SONiC_YANG_Model_Guidelines.md @@ -0,0 +1,1018 @@ + +# SONiC YANG MODEL GUIDELINES + + +## Revision + + | Rev | Date | Author | Change Description | + |:---:|:-----------:|:------------------:|-----------------------------------| + | 1.0 | 22 Aug 2019 | Praveen Chaudhary | Initial version | + | 1.0 | 11 Sep 2019 | Partha Dutta | Adding additional steps for SONiC YANG | + | 1.1 | 15 Dec 2023 | Jingwen Xie | Added rules for List Keys | + +## References +| References | Date/Version | Link | +|:-------------------------:|:-------------------:|:-----------------------------------:| +| RFC 7950 | August 2016 | https://tools.ietf.org/html/rfc7950 | +| Management Framework | 0.9 | https://github.com/sonic-net/SONiC/pull/436 | + +## Terminology and Acronyms +| Acronyms | Description/Expansion | +|:-------------------------:|:-------------------:| +| ABNF | Augmented Backus-Naur Form | +| XPath | XML Path Language | +| CVL | Configuration Validation Library | + + +## Overview + This document lists the guidelines, which will be used to write YANG Modules for SONiC. These YANG Modules (called SONiC YANG models) will be primarily based on or represent the ABNF.json of SONiC, and the syntax of YANG models must follow RFC 7950 ([https://tools.ietf.org/html/rfc7950](https://tools.ietf.org/html/rfc7950)). Details of config in format of ABNF.json can be found at https://github.com/sonic-net/SONiC/wiki/Configuration. + +These YANG models will be used to verify the configuration for SONiC switches, so a library which supports validation of configuration on SONiC Switch must use these YANG Models. List of such Libraries are: 1.) Configuration Validation Library. (CVL). YANG models, which are written using these guidelines can also be used as User End YANG Models, i.e North Bound configuration tools or CLI can provide config data in sync with these YANG models. For example [SONiC Management Framework](https://github.com/sonic-net/SONiC/pull/436) uses SONiC YANG models as Northbound Management YANG and for configuration validation purpose also. + +## Guidelines + + +### 1. All schema definitions related to a feature should be written in a single YANG model file. YANG model file is named as 'sonic-{feature}.yang', e.g. for ACL feature sonic-acl.yang is the file name. It is best to categorize YANG Modules based on a networking components. For example, it is good to have separate modules for VLAN, ACL, PORT and IP-ADDRESSES etc. + +``` +sonic-acl.yang +sonic-interface.yang +sonic-port.yang +sonic-vlan.yang +``` + +### 2. It is mandatory to define a top level YANG container named as 'sonic-{feature}' i.e. same as YANG model name. For example, sonic-acl.yang should have 'sonic-acl' as top level container. All other definition should be written inside the top level container. + +Example : +#### YANG +```yang +module sonic-acl { + container sonic-acl { + ..... + ..... + } +} +``` + +### 3. Define namespace as "http://github.com/sonic-net/{model-name}". + +Example : +#### YANG +```yang +module sonic-acl { + namespace "http://github.com/sonic-net/sonic-acl"; + ..... + ..... +} +``` + +### 4. Use 'revision' to record revision history whenever YANG model is changed. Updating revision with appropriate details helps tracking the changes in the model. + +Example : + +#### YANG +```yang +module sonic-acl { + revision 2019-09-02 { + description + "Added must expression for ACL_RULE_LIST."; // Updated with new change details + } + + revision 2019-09-01 { + description + "Initial revision."; + } + ..... + ..... +} +``` + +### 5. Each primary section of ABNF.json (i.e a dictionary in ABNF.json) for example, VLAN, VLAN_MEMBER, INTERFACE in ABNF.json will be mapped to a container in YANG model. + +Example: Table VLAN will translate to container VLAN. + +#### ABNF + +```yang +"VLAN": { + "Vlan100": { + "vlanid": "100" + } + } +``` +will translate to: + +#### YANG +-- +```yang +container VLAN { //"VLAN" mapped to a container + list VLAN_LIST { + key name; + leaf vlanid { + type uint16; + } + } +} +``` + + +### 6. Each leaf in YANG module should have same name (including their case) as corresponding key-fields in ABNF.json. + +Example: +Leaf names are same PACKET_ACTION, IP_TYPE and PRIORITY, which are defined in ABNF. + +#### ABNF +``` + "NO-NSW-.....|.....": { + "PACKET_ACTION": "FORWARD", + "IP_TYPE": "IPv6ANY", + "PRIORITY": "955520", + ..... + ..... + }, +``` + +#### YANG +```yang + leaf PACKET_ACTION { + ..... + } + leaf IP_TYPE { + ..... + } + leaf PRIORITY { + ..... + } +``` + +### 7. Use IETF data types for leaf type first if applicable (RFC 6021) . Declare new type (say SONiC types) only if IETF type is not applicable. All SONiC types must be part of same header type or common YANG model. +Example: + +#### YANG +```yang + leaf SRC_IP { + type inet:ipv4-prefix; <<<< + } + + leaf DST_IP { + type inet:ipv4-prefix; + } +``` + +### 8. Data Node/Object Hierarchy of the an objects in YANG models will be same as for all the fields at same hierarchy in Config DB. If any exception is created then it must be recorded properly with comment under object level in YANG models. To see an example of a comment, please refer to the step with heading as "Comment all must, when and patterns conditions." below. + +For Example: + +"Family" of VLAN_INTERFACE and "IP_TYPE" of ACL_RULE should be at same level in YANG model too. + +#### ABNF +``` +"VLAN_INTERFACE": { + "Vlan100|2a04:f547:45:6709::1/64": { + "scope": "global", + "family": "IPv6" + } +} +"ACL_RULE": { + "NO-NSW-PACL-V4|DEFAULT_DENY": { + "PACKET_ACTION": "DROP", + "IP_TYPE": "IPv4ANY", + "PRIORITY": "0" + } +} +``` +#### YANG +In YANG, "Family" of VLAN_INTERFACE and "IP_TYPE" of ACL_RULE is at same level. +```yang +container VLAN_INTERFACE { + description "VLAN_INTERFACE part of config_db.json"; + list VLAN_INTERFACE_LIST { + ...... + ...... + leaf family { + type sonic-head:ip-family; + } + } +} + +container ACL_RULE { + description "ACL_RULE part of config_db.json"; + list ACL_RULE_LIST { + ...... + ...... + leaf IP_TYPE { + type sonic-head:ip_type; + } + } +} +``` + +### 9. If an object is part of primary-key in ABNF.json, then it should be a key in YANG model. In YANG models, a primary-key from ABNF.json can be represented either as name of a Container object or as a key field in List object. Exception must be recorded in YANG Model with a comment in object field. To see an example of a comment, please refer to the step with heading as "Comment all must, when and patterns conditions." below. Though, key names are not stored in Redis DB, use the same key name as defined in ABNF schema. + +Example: VLAN_MEMBER dictionary in ABNF.json has both vlan-id and ifname part of the key. So YANG model should have the same keys. + +#### ABNF +``` + "VLAN_MEMBER": { + "Vlan100|Ethernet0": { //<<<< KEYS + "tagging_mode": "untagged" + } + } +``` +;Defines interfaces which are members of a vlan +key = VLAN_MEMBER_TABLE:"Vlan"vlanid:ifname ; + +#### YANG +```yang +container VLAN_MEMBER { + description "VLAN_MEMBER part of config_db.json"; + list ..... { + key "vlan-name ifname";//<<<< KEYS + } +} +``` + +### 10. If any key used in current table refers to other table, use leafref type for the key leaf definition. + +Example : +#### ABNF + +``` +key: ACL_RULE_TABLE:table_name:rule_name +..... +..... +``` +#### YANG +```yang +..... +container ACL_TABLE { + list ACL_TABLE_LIST { + key table_name; + + leaf table_name { + type string; + } + ..... + ..... + } +} +container ACL_RULE { + list ACL_RULE_LIST { + key "table_name rule_name"; + + leaf table_name { + type leafref { + path "../../../ACL_TABLE/ACL_TABLE_LIST/aclname"; //Refers to other table 'ACL_TABLE' + } + } + + leaf rule_name { + type string; + } + ..... + ..... + } +} +``` + +### 11. Mapping tables in Redis are defined using nested 'list'. Use 'sonic-ext:map-list "true";' to indicate that the 'list' is used for mapping table. The outer 'list' is used for multiple instances of mapping. The inner 'list' is used for mapping entries for each outer list instance. + +Example : + +#### ABNF +``` +; TC to queue map +;SAI mapping - qos_map with SAI_QOS_MAP_ATTR_TYPE == SAI_QOS_MAP_TC_TO_QUEUE. See saiqosmaps.h +key = "TC_TO_QUEUE_MAP_TABLE:"name ;field +tc_num = 1*DIGIT ;values +queue = 1*DIGIT; queue index + +``` + +#### YANG +```yang + container TC_TO_QUEUE_MAP { + list TC_TO_QUEUE_MAP_LIST { + key "name"; + sonic-ext:map-list "true"; //special annotation for map table + + leaf name { + type string; + } + + list TC_TO_QUEUE_MAP_LIST { //this is list inside list for storing mapping between two fields + key "tc_num qindex"; + leaf tc_num { + type string { + pattern "[0-9]?"; + } + } + leaf qindex { + type string { + pattern "[0-9]?"; + } + } + } + } + } +``` + + +### 12. 'ref_hash_key_reference' in ABNF schema is defined using 'leafref' to the referred table. + +Example : + +#### ABNF +``` +; QUEUE table. Defines port queue. +; SAI mapping - port queue. + +key = "QUEUE_TABLE:"port_name":queue_index +queue_index = 1*DIGIT +port_name = ifName +queue_reference = ref_hash_key_reference ;field value +scheduler = ref_hash_key_reference; reference to scheduler key +wred_profile = ref_hash_key_reference; reference to wred profile key + +``` + +#### YANG +```yang +container sonic-queue { + container QUEUE { + list QUEUE_LIST { + ..... + leaf scheduler { + type leafref { + path "/sch:sonic-scheduler/sch:SCHEDULER/sch:name"; //Reference to SCHEDULER table + } + } + + leaf wred_profile { + type leafref { + path "/wrd:sonic-wred-profile/wrd:WRED_PROFILE/wrd:name"; // Reference to WRED_PROFILE table + } + } + } + } +} +``` + +### 13. To establish complex relationship and constraints among multiple tables use 'must' expression. Define appropriate error message for reporting to Northbound when condition is not met. For existing feature, code logic could be reference point for deriving 'must' expression. +Example: + +#### YANG +```yang + must "(/sonic-ext:operation/sonic-ext:operation != 'DELETE') or " + + "count(../../ACL_TABLE[aclname=current()]/ports) = 0" { + error-message "Ports are already bound to this rule."; + } +``` + +### 14. Define appropriate 'error-app-tag' and 'error' messages for in 'length', 'pattern', 'range' and 'must' statement so that management application can use it for error reporting. + +Example: + +#### YANG +```yang +module sonic-vlan { + .... + .... + leaf vlanid { + mandatory true; + type uint16 { + range "1..4095" { + error-message "Vlan ID out of range"; + error-app-tag vlanid-invalid; + } + } + } + .... + .... +} + +``` + +### 15. All must, when, pattern and enumeration constraints can be derived from .h files or from code. If code has the possibility to have unknown behavior with some config, then we should put a constraint in YANG models objects. Also, Developer can put any additional constraint to stop invalid configuration. For new features, constraints may be derived based on low-level design document. + +For Example: Enumeration of IP_TYPE comes for aclorch.h +``` +#define IP_TYPE_ANY "ANY" +#define IP_TYPE_IP "IP" +#define IP_TYPE_NON_IP "NON_IP" +#define IP_TYPE_IPv4ANY "IPV4ANY" +#define IP_TYPE_NON_IPv4 "NON_IPv4" +#define IP_TYPE_IPv6ANY "IPV6ANY" +#define IP_TYPE_NON_IPv6 "NON_IPv6" +#define IP_TYPE_ARP "ARP" +#define IP_TYPE_ARP_REQUEST "ARP_REQUEST" +#define IP_TYPE_ARP_REPLY "ARP_REPLY" +``` +Example of When Statement: Orchagent of SONiC will have unknown behavior if below config is entered, So YANG must have a constraint. Here SRC_IP is IPv4, where as IP_TYPE is IPv6. + +#### ABNF: +``` + "ACL_RULE": { + "NO-NSW-PACL-V4|Rule_20": { + "PACKET_ACTION": "FORWARD", + "DST_IP": "10.186.72.0/26", + "SRC_IP": "10.176.0.0/15", + "PRIORITY": "999980", + "IP_TYPE": "IPv6" + }, + +``` +#### YANG: +```yang +choice ip_prefix { + case ip4_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; + leaf SRC_IP { + type inet:ipv4-prefix; + } + leaf DST_IP { + type inet:ipv4-prefix; + } + } + case ip6_prefix { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf SRC_IPV6 { + type inet:ipv6-prefix; + } + leaf DST_IPV6 { + type inet:ipv6-prefix; + } + } + } +``` +Example of Pattern: If PORT Range should be "<0-65365> - <0-65365>" +``` +leaf L4_DST_PORT_RANGE { + type string { + pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; + } +} +``` +### 16. Comment all must, when and patterns conditions. See example of comment below. +Example: + +#### YANG +```yang +leaf family { + /* family leaf needed for backward compatibility + Both ip4 and ip6 address are string in IETF RFC 6020, + so must statement can check based on : or ., family + should be IPv4 or IPv6 according. + */ + must "(contains(../ip-prefix, ':') and current()='IPv6') or + (contains(../ip-prefix, '.') and current()='IPv4')"; + type sonic-head:ip-family; + } +``` + + +### 17. If a List object is needed in YANG model to bundle multiple entries from a Table in ABNF.json, but this LIST is not a valid entry in config data, then we must define such list as _LIST . + +For Example: Below entries in PORTCHANNEL_INTERFACE Table must be part of List Object in YANG model, because variable number of entries may be present in config data. But there is no explicit list in config data. To support this, a list object with name PORTCHANNEL_INTERFACE_LIST should be added in YANG model. +#### ABNF: +``` +"PORTCHANNEL_INTERFACE": { + "PortChannel01|10.0.0.56/31": {}, + "PortChannel01|FC00::71/126": {}, + "PortChannel02|10.0.0.58/31": {}, + "PortChannel02|FC00::75/126": {} + ... + } +``` + +#### YANG +```yang +container PORTCHANNEL_INTERFACE { + + description "PORTCHANNEL_INTERFACE part of config_db.json"; + + list PORTCHANNEL_INTERFACE_LIST {<<<<< + ..... + ..... + } +} +``` + +### 18. In some cases it may be required to split an ABNF table into multiple YANG lists based on the data stored in the ABNF table. In this case it is crucial to ensure that the List keys are non-overlapping, unique, and unambiguous. + +**Strategies for Ensuring Unique and Unambiguous Keys**: Utilize composite keys that have a different number of key elements to distinguish lists. Need to mention that different key names do not count as unambiguous model. + +#### ABNF +``` +"INTERFACE" : { + "Ethernet1" : { + "vrf-name": "vrf1" + } + "Ethernet1|10.184.230.211/31": { + } +} +``` +#### Example 1: Key with different number of elements(composite keys - Allowed case) + +`INTERFACE` table stores VRF names to which an interface belongs, also it stores IP address of each interface. Hence it is needed to split them into two different YANG lists. + +```yang +...... +container INTERFACE { + list INTERFACE_LIST { // 1st list + key ifname; + + leaf ifname { + type leafref { + ...... + } + } + leaf vrf-name { + type leafref { + ...... + } + } + ...... + } + + list INTERFACE_IPADDR_LIST { //2nd list + key "ifname ip_addr" + + leaf ifname { + type leafref { + ...... + } + } + leaf ip_addr { + type inet:ipv4-prefix; + } + ...... + } +} +...... +``` +In the example above if the config DB contains an INTERFACE table with single key element then it will be associted with the INTERFACE_LIST and if contains 2 key elements then it will be associated with INTERFACE_IPADDR_LIST + +#### Example 2: Keys with same number of elements of same type (NOT Allowed case 1) + +```yang +...... +container NOT_SUPPORTED_INTERFACE { + list NOT_SUPPORTED_INTERFACE_LIST { // 1st list + key ifname; + leaf ifname { + type string; + } + // ... + } + + list NOT_SUPPORTED_INTERFACE_ANOTHER_LIST { // Negative case + key ifname; + leaf ifname { + type string; + } + // ... + } +} +...... +``` + +In the example above if the config DB contains an NOT_SUPPORTED_INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario + +#### Example 3: Keys with same number of elements of same type (NOT Allowed case 2) + +```yang +...... +container NOT_SUPPORTED_TELEMETRY_CLIENT { + list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { // 1st list + key "prefix name"; + + leaf prefix { + type string { + pattern "DestinationGroup_" + ".*"; + } + } + + leaf name { + type string; + } + + leaf dst_addr { + type ipv4-port; + } + } + + list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { // Negative case + key "prefix name"; + + leaf prefix { + type string { + pattern "Subscription_" + ".*"; + } + } + + leaf name { + type string; + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type string; + } + } +} +...... +``` +In the example above if the config DB contains an NOT_SUPPORTED_TELEMETRY_CLIENT table with key "DestinationGroup|HS", then it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario + +#### Example 4: keys with same number of elements and different type(NOT Allowed case 3) + +In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "1234", it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario + +```yang +...... +container NOT_SUPPORTED_TELEMETRY_CLIENT { + list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { // 1st list + key "prefix"; + + leaf prefix { + type string { + pattern ".*"; + } + } + + leaf dst_addr { + type ipv4-port; + } + } + + list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { // Negative case + key "id"; + + leaf id { + type int32; + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type int32; + } + } +} +...... +``` + +#### Example 5: keys with same number of elements and different type(NOT Allowed case 4) + +In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "1234|1234", it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario + +```yang +...... +container NOT_SUPPORTED_TELEMETRY_CLIENT { + list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { // 1st list + key "prefix name"; + + leaf prefix { + type string; + } + + leaf name { + type string; + } + + leaf dst_addr { + type ipv4-port; + } + } + + list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { // Negative case + key "id name"; + + leaf id { + type int32; + } + + leaf name { + type int32; + } + + leaf dst_group { + must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; + type int32; + } + } +} +...... +``` + + +### 19. Add read-only nodes for state data using 'config false' statement. Define a separate top level container for state data. If state data is defined in other DB than CONFIG_DB, use extension 'sonic-ext:db-name' for defining the table present in other Redis DB. The default separator used in table key is "|", if it is different, use 'sonic-ext:key-delim {separator};' YANG extension. This step applies when SONiC YANG is used as Northbound YANG. + +Example: + +#### YANG +```yang +container ACL_RULE { + list ACL_RULE_LIST { + .... + .... + container state { + sonic-ext:db-name "APPL_DB"; //For example only + sonic-ext:key-delim ":"; //For example only + + config false; + description "State data"; + + leaf MATCHED_PACKETS { + type yang:counter64; + } + + leaf MATCHED_OCTETS { + type yang:counter64; + } + } + } +} +``` + +### 20. Define custom RPC for executing command like clear, reset etc. No configuration should change through such RPCs. Define 'input' and 'output' as needed, however they are optional. This step applies when SONiC YANG is used as Northbound YANG. + +Example: + +#### YANG +```yang +container sonic-acl { + .... + .... + rpc clear-stats { + input { + leaf aclname { + type string; + } + + leaf rulename { + type string; + } + } + } +} +``` + +### 21. Define Notification for sending out events generated in the system, e.g. link up/down or link failure event. This step applies when SONiC YANG is used as Northbound YANG. + +Example: + +#### YANG +```yang +module sonic-port { + .... + .... + notification link_event { + leaf port { + type leafref { + path "../../PORT/PORT_LIST/ifname"; + } + } + } +} +``` + +## APPENDIX + +### Sample SONiC ACL YANG + +```yang +module sonic-acl { + namespace "http://github.com/sonic-net/sonic-acl"; + prefix sacl; + yang-version 1.1; + + import ietf-yang-types { + prefix yang; + } + + import ietf-inet-types { + prefix inet; + } + + import sonic-common { + prefix scommon; + } + + import sonic-port { + prefix prt; + } + + import sonic-portchannel { + prefix spc; + } + + import sonic-mirror-session { + prefix sms; + } + + import sonic-pf-limits { + prefix spf; + } + + organization + "SONiC"; + + contact + "SONiC"; + + description + "SONiC YANG ACL"; + + revision 2019-09-11 { + description + "Initial revision."; + } + + container sonic-acl { + container ACL_TABLE { + list ACL_TABLE_LIST { + key "table_name"; + + leaf table_name { + type string; + } + + leaf policy_desc { + type string { + length 1..255 { + error-app-tag policy-desc-invalid-length; + } + } + } + + leaf stage { + type enumeration { + enum INGRESS; + enum EGRESS; + } + } + + leaf type { + type enumeration { + enum MIRROR; + enum L2; + enum L3; + enum L3V6; + } + } + + leaf-list ports { + type union { + type leafref { + path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; + } + type leafref { + path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:PORTCHANNEL_LIST/spc:name"; + } + } + } + } + } + + container ACL_RULE { + list ACL_RULE_LIST { + key "table_name rule_name"; + leaf table_name { + type leafref { + path "../../../ACL_TABLE/ACL_TABLE_LIST/table_name"; + } + must "(/scommon:operation/scommon:operation != 'DELETE') or " + + "(current()/../../../ACL_TABLE/ACL_TABLE_LIST[table_name=current()]/type = 'L3')" { + error-message "Type not staisfied."; + } + } + + leaf rule_name { + type string; + } + + leaf PRIORITY { + type uint16 { + range "1..65535"{ + error-message "Invalid ACL rule priority."; + } + } + } + + leaf RULE_DESCRIPTION { + type string; + } + + leaf PACKET_ACTION { + type enumeration { + enum FORWARD; + enum DROP; + enum REDIRECT; + } + } + + leaf MIRROR_ACTION { + type leafref { + path "/sms:sonic-mirror-session/sms:MIRROR_SESSION/sms:MIRROR_SESSION_LIST/sms:name"; + } + } + + leaf IP_TYPE { + type enumeration { + enum ANY; + enum IP; + enum IPV4; + enum IPV4ANY; + enum NON_IPV4; + enum IPV6ANY; + enum NON_IPV6; + } + } + + leaf IP_PROTOCOL { + type uint8 { + range "1|2|6|17|46|47|51|103|115"; + } + } + + leaf ETHER_TYPE { + type string { + pattern "(0x88CC)|(0x8100)|(0x8915)|(0x0806)|(0x0800)|(0x86DD)|(0x8847)" { + error-message "Invalid ACL Rule Ether Type"; + error-app-tag ether-type-invalid; + } + } + } + + choice ip_src_dst { + case ipv4_src_dst { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY'])"; + leaf SRC_IP { + mandatory true; + type inet:ipv4-prefix; + } + leaf DST_IP { + mandatory true; + type inet:ipv4-prefix; + } + } + case ipv6_src_dst { + when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; + leaf SRC_IPV6 { + mandatory true; + type inet:ipv6-prefix; + } + leaf DST_IPV6 { + mandatory true; + type inet:ipv6-prefix; + } + } + } + + choice src_port { + case l4_src_port { + leaf L4_SRC_PORT { + type uint16; + } + } + case l4_src_port_range { + leaf L4_SRC_PORT_RANGE { + type string { + pattern "[0-9]{1,5}(-)[0-9]{1,5}"; + } + } + } + } + + choice dst_port { + case l4_dst_port { + leaf L4_DST_PORT { + type uint16; + } + } + case l4_dst_port_range { + leaf L4_DST_PORT_RANGE { + type string { + pattern "[0-9]{1,5}(-)[0-9]{1,5}"; + } + } + } + } + + leaf TCP_FLAGS { + type string { + pattern "0[xX][0-9a-fA-F]{2}[/]0[xX][0-9a-fA-F]{2}"; + } + } + + leaf DSCP { + type uint8; + } + } + } + } +} + +``` + diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 710151ef666..f8fe25e5705 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2363,6 +2363,157 @@ } }, + "STP": { + "GLOBAL": { + "mode": "pvst", + "rootguard_timeout": "30", + "forward_delay": "15", + "hello_time": "2", + "max_age": "20", + "priority": "32768" + } + }, + "STP_VLAN": { + "Vlan100": { + "forward_delay": "15", + "hello_time": "2", + "max_age": "20", + "priority": "32768", + "enabled": "true" + }, + "Vlan200": { + "forward_delay": "16", + "hello_time": "3", + "max_age": "22", + "priority": "16384", + "enabled": "true" + } + }, + "STP_VLAN_INTF": { + "Vlan100|Ethernet0": { + "path_cost": "200000", + "priority": "128" + }, + "Vlan100|PortChannel2": { + "path_cost": "20000", + "priority": "64" + }, + "Vlan200|Ethernet4": { + "path_cost": "200000", + "priority": "128" + } + }, + "STP_INTF": { + "Ethernet0": { + "enabled": "1", + "root_guard": "0", + "bpdu_guard": "0", + "bpdu_guard_do_disable": "0", + "path_cost": "200000", + "priority": "128", + "portfast": "1", + "uplink_fast": "0" + }, + "Ethernet4": { + "enabled": "1", + "root_guard": "0", + "bpdu_guard": "1", + "bpdu_guard_do_disable": "1", + "path_cost": "200000", + "priority": "128", + "portfast": "0", + "uplink_fast": "0" + }, + "PortChannel2": { + "enabled": "1", + "root_guard": "1", + "bpdu_guard": "0", + "bpdu_guard_do_disable": "0", + "path_cost": "20000", + "priority": "64", + "portfast": "0", + "uplink_fast": "1" + } + }, + + "STP_MST": { + "GLOBAL": { + "name": "region1", + "revision": "0", + "max_hops": "20", + "max_age": "20", + "hello_time": "2", + "forward_delay": "15" + } + }, + "STP_MST_INST": { + "0": { + "bridge_priority": "32768", + "vlan_list": "1-99,4000-4094" + }, + "1": { + "bridge_priority": "16384", + "vlan_list": "100-199" + }, + "2": { + "bridge_priority": "20480", + "vlan_list": "200-299" + }, + "3": { + "bridge_priority": "24576", + "vlan_list": "300-399" + } + }, + "STP_MST_PORT": { + "0|Ethernet0": { + "path_cost": "200000", + "priority": "128" + }, + "1|Ethernet0": { + "path_cost": "200000", + "priority": "128" + }, + "2|Ethernet4": { + "path_cost": "200000", + "priority": "128" + }, + "3|PortChannel2": { + "path_cost": "20000", + "priority": "64" + } + }, + "STP_PORT": { + "Ethernet0": { + "edge_port": "1", + "link_type": "point-to-point", + "enabled": "1", + "bpdu_guard": "0", + "bpdu_guard_do": "0", + "root_guard": "0", + "path_cost": "200000", + "priority": "128" + }, + "Ethernet4": { + "edge_port": "0", + "link_type": "shared", + "enabled": "1", + "bpdu_guard": "1", + "bpdu_guard_do": "1", + "root_guard": "0", + "path_cost": "200000", + "priority": "128" + }, + "PortChannel2": { + "edge_port": "0", + "link_type": "point-to-point", + "enabled": "1", + "bpdu_guard": "0", + "bpdu_guard_do": "0", + "root_guard": "1", + "path_cost": "20000", + "priority": "64" + } + }, "MCLAG_DOMAIN": { "123": { diff --git a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py index 22cad816b11..7ca4f0d7830 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py +++ b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py @@ -267,6 +267,8 @@ def test_run_tests(self): elif test in self.SpecialTests: ret = ret + self.runSpecialTest(test); else: + #log.error("Unexpected Test: {}".format(test)) + #ret = ret + 1 raise Exception("Unexpected Test") except Exception as e: ret = FAIL * len(self.tests) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json index ab2d565ce0d..cc1f43e7bb3 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json @@ -1,6 +1,10 @@ { "PVST_GLOBAL_VALID": { - "desc": "Configure valid global PVST settings" - + "desc": "Configure valid global PVST settings", + "eStr": [] + }, + "MSTP_GLOBAL_VALID": { + "desc": "Configure valid global MSTP settings", + "eStr": [] } } \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index 1fe0e0943a0..eb7dfdc97a0 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -1,10 +1,10 @@ { "PVST_GLOBAL_VALID": { "sonic-spanning-tree:sonic-spanning-tree": { - "sonic-spanning-tree:stp-config": { - "stp-list": [ + "sonic-spanning-tree:STP": { + "GLOBAL": [ { - "keyleaf": "GLOBAL", + "global-stp-mode": "GLOBAL", "mode": "pvst", "rootguard_timeout": 30, "forward_delay": 15, @@ -15,5 +15,34 @@ ] } } + }, + "MSTP_GLOBAL_VALID": { + "sonic-spanning-tree:sonic-spanning-tree": { + "sonic-spanning-tree:STP": { + "GLOBAL": [ + { + "global-stp-mode": "GLOBAL", + "mode": "mst", + "forward_delay": 15, + "hello_time": 2, + "max_age": 20, + "priority": 32768 + } + ] + }, + "sonic-spanning-tree:STP_MST": { + "MST_GLOBAL": [ + { + "global-stp-mode": "GLOBAL", + "name": "region1", + "revision": 0, + "max_hops": 20, + "hello_time": 2, + "max_age": 20, + "forward_delay": 15 + } + ] + } + } } } \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index af550c516cb..7e1ef9cc44b 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -3,21 +3,31 @@ module sonic-spanning-tree { namespace "http://github.com/sonic-net/sonic-stp"; prefix stp; + import ietf-yang-types { + prefix yang; + } + import sonic-extension { prefix sonic-ext; } + + organization + "SONiC"; + + contact + "SONiC"; description - "This module contains the collection of YANG definitions for the PVST & MSTP"; + "YANG model for Spanning Tree Protocol (STP) in SONiC, supporting PVST and MSTP."; - revision 2025-01-22 { + revision 2025-02-25 { description "Initial YANG model written for PVST & MSTP configurations xFlow & BRCM"; } grouping vlanModeAttr { description - "Configuration parameters"; + "Configuration parameters for VLAN-based STP settings."; leaf forward_delay { type uint8 { @@ -28,8 +38,7 @@ module sonic-spanning-tree { units seconds; default 15; description - "The delay used by STP bridges to transition root, and - designated ports to forwarding"; + "Delay before transitioning to the forwarding state."; } leaf hello_time { @@ -41,8 +50,7 @@ module sonic-spanning-tree { units seconds; default 2; description - "The interval between periodic transmissions of - configuration messages by designated ports"; + "Interval between configuration BPDUs."; } leaf max_age { @@ -54,8 +62,7 @@ module sonic-spanning-tree { units seconds; default 20; description - "The Maximum age of the information transmitted by the - bridge when it is the root bridge."; + "Maximum time bridge stores BPDU information."; } leaf priority { @@ -66,13 +73,13 @@ module sonic-spanning-tree { } default 32768; description - "The manageable component of the Bridge Identifier"; + "Bridge Identifier priority component."; } } grouping interfaceAttr { description - "Configuration parameters of interfaces."; + "Configuration parameters for STP interfaces."; leaf path_cost { type uint64 { @@ -82,8 +89,7 @@ module sonic-spanning-tree { } default 200; description - "The port's contribution, when it is the Root Port, - to the Root Path Cost for the Bridge"; + "Root path cost contribution."; } leaf priority { @@ -94,87 +100,83 @@ module sonic-spanning-tree { } default 128; description - "The manageable component of the Port Identifier, - also known as the Port Priority"; + "Port priority in STP calculations."; } } container sonic-spanning-tree { description - "Top level container for SONiC Spanning Tree configurations"; + "SONiC Spanning Tree Protocol (STP) configuration."; - container stp-config { + container STP { description - "Global configurations"; + "Global STP configurations, maps to STP_GLOBAL_TABLE."; - list stp-list { - description - "STP list containing global attributes"; + list GLOBAL { + key "global-stp-mode"; max-elements 1; - key "keyleaf"; + description + "Global STP configuration settings."; - leaf keyleaf { + leaf global-stp-mode { type enumeration { enum GLOBAL { description - "Global configuration identifier"; + "Global STP identifier."; } } description - "Key node identifier. It's value is always GLOBAL"; + "Key node identifier, always GLOBAL."; } leaf mode { type enumeration { enum pvst { description - "Per VLAN Spanning Tree Mode"; + "Per VLAN Spanning Tree Mode."; } enum mst { description - "Multiple Spanning Tree Mode"; + "Multiple Spanning Tree Mode."; } } mandatory true; description - "Spanning tree mode"; + "STP operating mode."; } leaf rootguard_timeout { type uint16 { - range "5..600" { - error-message "Invalid Root-guard Timeout value."; - } + range "5..600"; } - units seconds; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Root guard timeout not allowed in MST mode"; + units "seconds"; + default 30; + must "../mode != 'mst'" { + error-message "Root guard timeout is not allowed in MST mode."; error-app-tag stp-invalid; } - description - "Once superior BPDUs stop coming on the port, device - will wait for a period until root guard timeout before - moving the port to forwarding state"; + "Time before re-enabling a port in root-guard mode."; } - uses vlanModeAttr; } } - container stp-vlan { + container STP_VLAN { description - "VLAN Specific STP Configurations"; + "VLAN Specific STP Configurations, maps to STP_VLAN_TABLE"; - list stp-vlan-list { + list VLAN { + key "name"; description "List of VLAN STP configurations"; - key "name"; - + leaf name { - type string; + type string { + pattern 'Vlan[0-9]{1,4}'; + } description - "Vlan identifier"; + "Vlan identifier in format 'Vlan'"; } leaf vlanid { @@ -199,18 +201,18 @@ module sonic-spanning-tree { } } - container stp-vlan-port { + container STP_VLAN_INTF { description - "Vlan port configurations"; + "Vlan port configurations, maps to STP_VLAN_INTF_TABLE"; - list stp-vlan-port-list { + list VLAN_INTF { description "List of VLAN port configurations"; key "vlan-name ifname"; leaf vlan-name { type leafref { - path "../../../stp-vlan/stp-vlan-list/name"; + path "../../../STP_VLAN/VLAN/name"; } description "Reference to Vlan"; @@ -218,7 +220,7 @@ module sonic-spanning-tree { leaf ifname { type leafref { - path "../../../stp-port/stp-port-list/ifname"; + path "../../../STP_PORT/PORT/ifname"; } description "Reference to Ethernet interface or PortChannel"; @@ -228,17 +230,15 @@ module sonic-spanning-tree { } } - container stp-port { + container STP_PORT { description - "Port Configurations."; + "Port Configurations, maps to STP_PORT_TABLE"; - list stp-port-list { + list PORT { description "List of STP port List attributes."; key "ifname"; - //sonic-ext:dependent-on "stp-list"; - leaf ifname { type string; description @@ -278,7 +278,7 @@ module sonic-spanning-tree { leaf portfast { type boolean; - must "current()!='true' or ../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='pvst'" { + must "current()!='true' or ../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='pvst'" { error-message "Configuration not allowed in MST mode"; error-app-tag stp-invalid; } @@ -299,38 +299,34 @@ module sonic-spanning-tree { type enumeration { enum auto { description - "Specifies the interface's link type. Permissible values 'auto'"; + "Specifies the interface's link type as auto"; } enum shared { description - "Specifies the interface's link type. Permissible values 'shared'"; + "Specifies the interface's link type as shared"; } enum point-to-point { description - "Specifies the interface's link type. Permissible values 'point-to-point'"; + "Specifies the interface's link type as point-to-point"; } } description - "Specifies the interface's link type. Permissible values - are 'shared', 'point-to-point' and 'auto'"; + "Specifies the interface's link type: shared, point-to-point or auto"; } } } - container stp-mst { + container STP_MST { description - "MST specific configuration container"; + "MST specific configuration container, maps to STP_MST_TABLE"; - list stp-mst-list { + list MST_GLOBAL { description "List of MST global configurations"; max-elements 1; - key "keyleaf"; - + key "global-stp-mode"; - //sonic-ext:dependent-on "stp-list"; - - leaf keyleaf { + leaf global-stp-mode { type enumeration { enum GLOBAL { description @@ -342,8 +338,10 @@ module sonic-spanning-tree { } leaf name { - type string; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + type string { + length "1..32"; + } + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -352,8 +350,11 @@ module sonic-spanning-tree { } leaf revision { - type uint32; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + type uint16 { + range "0..65535"; + } + default 0; + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -362,8 +363,11 @@ module sonic-spanning-tree { } leaf max_hops { - type uint8; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + type uint8 { + range "1..40"; + } + default 20; + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -372,38 +376,47 @@ module sonic-spanning-tree { } leaf hello_time { - type uint8; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + type uint8 { + range "1..10"; + } + default 2; + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } description - "MST hello time"; + "MST hello time in seconds"; } leaf max_age { - type uint8; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + type uint8 { + range "6..40"; + } + default 20; + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } description - "MST max age"; + "MST max age in seconds"; } leaf forward_delay { - type uint8; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + type uint8 { + range "4..30"; + } + default 15; + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } description - "MST forward delay"; + "MST forward delay in seconds"; } leaf hold_count { type uint8; - must "../../../stp-config/stp-list[keyleaf='GLOBAL']/mode='mst'" { + must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -413,13 +426,13 @@ module sonic-spanning-tree { } } - container stp-mst-inst { + container STP_MST_INST { description - "STP MST Instance Configuration."; + "STP MST Instance Configuration, maps to STP_MST_INST_TABLE"; - list stp-mst-inst-list { + list MST_INSTANCE { description - "List of STP MST Instance attributes."; + "List of STP MST Instance attributes"; key "instance"; leaf instance { @@ -428,10 +441,10 @@ module sonic-spanning-tree { "Instance identifier"; } - leaf-list vlan { + leaf-list vlan_list { type string; description - "Vlan list"; + "Vlan list assigned to MST instance"; } leaf bridge_priority { @@ -440,24 +453,25 @@ module sonic-spanning-tree { error-message "Invalid Bridge Priority value."; } } + default 32768; description "The manageable component of the Bridge Identifier"; } } } - container stp-mst-port { + container STP_MST_PORT { description - "STP MST Port configurations."; + "STP MST Port configurations, maps to STP_MST_PORT_TABLE"; - list stp-mst-port-list { + list MST_PORT { description "STP MST Port List attributes"; key "inst_id ifname"; leaf inst_id { type leafref { - path "../../../stp-mst-inst/stp-mst-inst-list/instance"; + path "../../../STP_MST_INST/MST_INSTANCE/instance"; } description "Reference to MST Instance"; @@ -465,7 +479,7 @@ module sonic-spanning-tree { leaf ifname { type leafref { - path "../../../stp-port/stp-port-list/ifname"; + path "../../../STP_PORT/PORT/ifname"; } description "Reference to Ethernet interface or PortChannel"; From 873c72102045d8bd48760b2301f5ec7dec215d2a Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Sat, 8 Mar 2025 22:31:38 +0500 Subject: [PATCH 08/14] Fixing rootguard timeout issue for mst --- MSTP.md | 1272 ----------------- SONiC_PVST_HLD.md | 746 ---------- src/sonic-yang-mgmt/sonic_yang_ext.py | 2 +- .../tests/files/sample_config_db.json | 2 + .../tests/yang_model_tests/test_yang_model.py | 6 +- .../yang_model_tests/tests_config/stp.json | 10 +- .../yang-models/sonic-spanning-tree.yang | 23 +- 7 files changed, 18 insertions(+), 2043 deletions(-) delete mode 100644 MSTP.md delete mode 100644 SONiC_PVST_HLD.md diff --git a/MSTP.md b/MSTP.md deleted file mode 100644 index 7bb8f704efd..00000000000 --- a/MSTP.md +++ /dev/null @@ -1,1272 +0,0 @@ - -[© Broadcom](https://www.broadcom.com/) & [© xFlow Research Inc](https://xflowresearch.com/) - -# Multiple Spanning Tree Protocol - - -## Revision History - -|Revision No.|Description|Author|Date| -| :- | :- | :- | :- | -|0.1|Modified Design| [Divya Kumaran Chandralekha](https://github.com/divyachandralekha) , [Rida Hanif](github.com/ridahanif96) , [Wajahat Razi](https://github.com/wajahatrazi) | July 02, 2024| - -# Table of Contents - -* [Scope](#scope) -* [Background](#background) -* [Abbreviations](#abbreviations) -* [Overview](#overview) -* [Introduction](#introduction) -* [Requirements](#requirements) -* [Architecture Design](#architecture-design) - - [STP Container](#stp-container) - - [SWSS Container](#swss-container) -* [Database Changes](#database-changes) - - [CONFIG DB](#config-db) - - [APP DB](#app-db) -* [SAI](#sai) -* [Additional Features](#additional-features) -* [Sequence Diagrams](#sequence-diagrams) - - [MSTP global enable](#mstp-global-enable) - - [MSTP global disable](#mstp-global-disable) - - [MSTP region name/version change](#mstp-region-nameversion-change) - - [Instance creation](#instance-creation) - - [Instance deletion](#instance-deletion) - - [MSTP Instance creation](#mstp-Instance-Creation) - - [MSTP Instance deletion](#mstp-Instance-Deletion) - - [Add VLAN to Exisiting Instance](#add-vlan-existing) - - [Delete VLAN to Exisiting Instance](#delete-vlan-existing) - - [Add VLAN member](#add-vlan-member) - - [Del VLAN member](#del-vlan-member) -* [Configuration Commands](#configuration-commands) - - [Global Level](#global-level) - - [Region Level](#region-level) - - [Instance, Interface Level](#instance-interface-level) - - [Show Commands](#show-commands) - - [Clear Commands](#clear-commands) - - [Debug Commands](#debug-commands) - - [Disabled Commands](#disabled-commands) -* [YANG Model](#yang-model) -* [Rest API Support](#rest-api-support) -* [Warm Boot](#warm-boot) -* [Testing Requirements](#testing-requirements) - - [Unit test cases](#unit-test-cases) -* [References](#references) - -# Scope -This document describes the High Level Design of Multiple Spanning Tree Protocol. - -# Abbreviations - -|**Term**|**Meaning**| -| :- | :- | -|BPDU|Bridge Protocol Data Unit| -|CIST|Common Internal Spanning Tree| -|CST|Common Spanning Tree| -|IST|Internal Spanning Tree| -|MSTI|Multiple Spanning Tree Instance| -|MSTID|Multiple Spanning Tree Identifier| -|MSTP|Multiple Spanning Tree Protocol| -|STP|Spanning Tree Protocol| -|VLAN|Virtual Local Area Network| -|VID|VLAN identifier| - -# Overview -Multiple Spanning Tree Protocol (MSTP) enhances the Spanning Tree Protocol (STP) by enabling the creation of multiple spanning tree instances within a network. It provides a mechanism to map VLANs to specific spanning tree instances which offers network segmentation and improved control over traffic flow. - -# Introduction - -Spanning Tree Protocol (STP) is a network protocol that operates at the Data Link layer (Layer 2) of the OSI model. Its primary purpose is to prevent loops in a Local Area Network (LAN). Network loops can cause broadcast storms and multiple frame copies, leading to network inefficiencies and failures. STP ensures a loop-free topology by creating a spanning tree that selectively blocks some network paths. - -Multiple Spanning Tree Protocol (MSTP), standardized in IEEE 802.1s, is an extension of STP. MSTP enhances STP by providing better loop prevention, path redundancy, and optimal bandwidth utilization. MSTP allows network engineers to create multiple spanning trees, each associated with a set of VLANs, and assign them to different switch ports. This configuration optimizes bandwidth usage, reduces convergence time, and simplifies network management. - - -MSTP reduces convergence time compared to STP. When a network topology change occurs, only the affected MSTI needs to reconverge, minimizing the impact on the entire network. - - -# Understanding MSTP: IST, CIST, CST, MST Regions, MSTIs, VLAN to MSTI Mapping - -Before diving into the specific terms related to Multiple Spanning Tree Protocol (MSTP), it's important to first define the concept of an MST region. The following definitions outline the key components of MSTP, starting with the MST region. - -1. **MST Regions**: An MST region is a group of interconnected bridges that share the same MST configuration, including the MST configuration name, revision number, and VLAN-to-instance mappings. - -2. **Default Internal Spanning Tree (IST)**: An internal spanning tree (IST) is a spanning tree that runs in an MST region. It is also called MSTI 0, a special MSTI to which all VLANs are mapped by Default. - -3. **Common Spanning Tree (CST)**: The common spanning tree (CST) is a single spanning tree that connects all MST regions in a switched network. - -4. **Common and Internal Spanning Tree (CIST)**: The common and internal spanning tree (CIST) is a single spanning tree that connects all devices in a switched network. It consists of the ISTs in all MST regions and the CST. - -5. **MST Instances (MSTIs)**: MSTP divides the network into multiple regions, each containing several MSTIs. Each MSTI operates independently, allowing for efficient use of network resources and optimized load balancing across different VLANs. - - -# MSTP Advantages - -1. **VLAN-to-MSTI Mapping**: MSTP maps VLANs to specific MSTIs using a VLAN mapping table. This mapping ensures that traffic within a VLAN follows the corresponding MSTI, optimizing the network path and improving performance. - -2. **Traffic Load Sharing and Link Level Redundancy**: By effectively utilizing VLAN-to-MSTI mapping, MSTP can facilitate traffic load sharing across multiple links and provide redundancy at the link level. This helps in balancing the traffic load and enhances overall network resilience. - -3. **Optimized Bandwidth**: MSTP ensures that network paths are used efficiently, reducing link blocking and optimizing bandwidth usage. This results in improved performance for data transmission across the network. - - -# MSTP Operation - -1. **MST BPDUs**: MSTP uses Multiple Spanning Tree Bridge Protocol Data Units (MST BPDUs) to exchange information between switches. These BPDUs contain information about the MSTI and VLAN mappings, ensuring consistent spanning tree calculations across the network. MSTP calculates spanning trees based on MST BPDUs. - -2. **MSTP BPDUs Characteristics**: MSTP BPDUs, which utilize the IEEE Reserved Multicast MAC address, are untagged. This is in contrast to PVST BPDUs. Additionally, MSTP BPDUs are backward compatible with legacy STP, RSTP, and PVST+/RPVST+ BPDUs. - -3. **Config Digest**: A hash of MSTP-VLAN mapping knows as 'config digest' is carried in the BPDUs, coupled with region name and the revision number, determines the same/different MST region of the sending switch. - - -
-MSTP BPDU -

MSTP BPDU Format

-

-
-MSTP Config Message -

MSTI Configuration Messages

-
- -*Refer to [RFC IEEE 802.1s-2002](https://standards.ieee.org/ieee/802.1s/1042/) for MSTP BPDU details.* - - -### Requirements - - -### Functional Requirements - -1. Support the creation of Multiple Spanning Tree Instances (MSTIs). - -2. Support the assignment of one or more VLANs to a specific MSTI within a region. - -3. Support the option to assign a region name and revision number to MSTP regions to achieve unique identification of VLAN to instance mapping across switches. - -4. Support path selection and forwarding behavior in MSTI to optimize network performance within each instance by configuring a distinct root bridge. - -5. Support the configuration of spanning tree parameters such as forward delay, hello timer, and hop count. - -6. The Destination MAC Address will be `01:80:C2:00:00:00` for MSTP BPDUs. - -7. Support backward compatibility with networks employing different spanning tree protocols, such as STP and RSTP. - -8. Support edge port functionality. - -9. Support BPDU guard functionality. - -10. Support root guard functionality. - -11. Support protocol operation on static breakout ports. - -12. Support protocol operation on Port-channel interfaces. Note: MSTP does not support aggregated path cost calculations. - - -#### Configuration & Management Requirements - - -1. Support CLI configurations as mentioned in Configuration section - -2. Support show commands as mentioned in Configuration section - -3. Support debug commands as mentioned in Configuration section - -4. Support statistics commands as mentioned in Configuration section - -5. Support clear commands as mentioned in Configuration section - - -# Architecture Design -Following diagram explains the architectural design and linkages for MSTP. MSTP uses multiple existing SONiC containers, configuration details of each is mentioned below as well. - -![MSTP Architecture](images/MSTPDesign_Archi.drawio.png) - -## STP Container -STP Container is responsible for actions taken for BPDU rx and BPDU tx. Following are the details for implementation: - -### STPMgr -Subscribes to CONFIG_DB and STATE_DB tables, parsing configurations and passes to STPd. - -### STPd -Responsible for all MST protocol related calculations. BPDUs are sent and received in STPd and states are updated accordingly. - -### STPSync -STPSync is a component integrated within STPd responsible for managing and updating all operational STP data to APP DB. - -Stpd communicates with Linux Kernal for The BPDU reception/transmission, management of port or LAG changes via NetLink events, and synchronization of STP port states with the Linux Kernel. - -## SWSS Container - -SWSS Container is responsible for passing on configurations to SAI as follows: - -### STPOrch -Updates SAI via following APIs: - -1. Creating/deleting instances -2. Assigning VLAN to instance -3. Creation of STP Port and assigning port state with respect to each instance -4. Flushing FDB entries - - -# Database Changes -MSTP design introduces some new tables for configuration along with slight modification in existing STP tables. Following are details of each individual table: - -## CONFIG DB - -### Existing Table -Following existing table of CONFIG_DB will be modified for MSTP implementation: - -#### STP_GLOBAL_TABLE -A new value of `mst` for `mode` column -``` -mode = "pvst" / "mst" ; a new option for mstp -``` -Other fields of this table are not applicable for "mstp" mode. - -### New Tables -Following new tables will be added to CONFIG_DB: - - -#### STP_MST_TABLE -``` -;Stores STP Global configuration -key = STP_MST| GLOBAL ; GLOBAL MSTP table key -name = 1*32CHAR ; MSTP region name(DEF:mac address of switch) -revision = 5*DIGIT ; MSTP revision number (0 o 65535 ,DEF:0) -max_hop = 2*DIGIT ; maximum hops (1 to 40, DEF:20) -max_age = 2*DIGIT ; maximum age time in secs (6 to 40sec, DEF:20sec) -hello_time = 2*DIGIT ; hello time in secs (1 to 10sec, DEF:2sec) -forward_delay = 2*DIGIT ; forward_delay in secs (4 to 30sec, DEF:15 sec) -``` - -#### STP_MST_INST_TABLE -``` -;Stores STP configurations per MSTI -key = STP_MST| "MST_INSTANCE":"Instance" id ; MST with prefix "STP_MST" -bridge_priority = 5*DIGIT ; bridge priority (0 to 61440, DEF: 32768) -vlan_list = "Vlans" ; Lists of VLANs assigned to the MST instance -``` - -#### STP_MST_PORT_TABLE - -``` -;Stores STP interface details per MSTI -key = STP_MST_PORT| "MST_INSTANCE" id|ifname ; MSTI+Intf with prefix "STP_MST_PORT" -path_cost = 9*DIGIT ; port path cost (1 to 20000000) -priority = 3*DIGIT ; port priority (0 to 240, DEF:128) - -``` - -#### STP_PORT_TABLE - -``` -;Stores STP interface details -key = STP_PORT|ifname ; ifname with prefix STP_PORT -edge_port = BIT ; enabled or disabled -link_type = "type" ; type can be of auto, point-to-point or shared -enabled = BIT ; enabled or disabled -bpdu_guard = BIT ; enabled or disabled -bpdu_guard_do = BIT ; enabled or disabled -root_guard = BIT ; enabled or disabled -path_cost = 9*DIGIT ; port path cost (1 to 20000000) -priority = 3*DIGIT ; port priority (0 to 240, DEF:128) - -``` - - -## APP DB - -### New Tables -Following new tables are introduced as part of MSTP Feature: - - -#### STP_MST_INST_TABLE -``` -;Stores the STP per MSTI operational details -key = STP_MST_INST_TABLE:"MST" id -vlan_list = vlan_id-or-range[,vlan_id-or-range] ; list of VLAN IDs assigned to MST instance -bridge_address = 16HEXDIG ; bridge id -regional_root_address = 16HEXDIG ; regional root bridge id -root_address = 16HEXDIG ; root bridge id -root_path_cost = 1*9DIGIT ; root path cost -regional_root_cost = 1*9DIGIT ; regional root path cost -root_max_age = 1*2DIGIT ; Max age of root bridge (6 to 40 sec, DEF:20sec) -root_hello_time = 1*2DIGIT ; Hello time of root bridge (1 to 10 sec, DEF:2sec) -root_forward_delay = 1*2DIGIT ; forward delay of root bridge (4 to 30sec , DEF:15sec) -remining_hops = 1*2DIGIT ; Remaining Max-hops -root_port = ifName ; Root port name -``` - -#### STP_MST_PORT_TABLE -``` -;Stores STP MST instance interface details -key = STP_MST_PORT_TABLE:"MST":id:ifname ; MSTI+Intf with prefix "STP_MST_PORT -port_number = 1*3DIGIT ; port number or bridge port -path_cost = 1*9DIGIT ; port path cost (1 to 200000000) -priority = 3*DIGIT ; port priority (0 to 240, DEF:128) -port_state = "state" ; DISABLED/DISCARDED/LISTENING/LEARNING/FORWARDING -role = "role" ; DESIGNATED/ROOT/ALTERNATIVE/MASTER -desig_cost = 1*9DIGIT ; designated cost -external_cost = 1*9DIGIT ; designated cost -desig_root = 16HEXDIG ; designated root -desig_reg_cost = 16HEXDIG ; designated root -desig_bridge = 16HEXDIG ; designated bridge -desig_port = 1*9DIGIT ; designated port -fwd_transitions = 1*5DIGIT ; number of forward transitions -bpdu_sent = 1*10DIGIT ; bpdu transmitted -bpdu_received = 1*10DIGIT ; bpdu received -``` - -#### STP_PORT_TABLE -``` -;Stores STP interface detail -key = STP_PORT_TABLE:ifname ; ifname with prefix STP_INTF -edge_port = BIT ; edge port enabled or disabled -link_type = "type" ; point-to-point or shared link type -mst_boundary = BIT ; enabled or disabled -mst_boundary_proto = BIT ; enabled or disabled -``` - -#### STP_INST_PORT_FLUSH_TABLE - -``` -;Defines instance and port for which FDB Flush needs to be performed -key = STP_INST_PORT_FLUSH_TABLE:instane:ifname ; FDB Flush instance id and port -name -state = "true" -``` - -### Existing Tables -Following already present APP_DB tables are also used for implementation of MSTP: - -#### STP_PORT_STATE_TABLE -The table holds the state of a port i.e forwarding, learning, blocking with respect to each instance. -#### STP_VLAN_INSTANCE_TABLE -The table holds the VLAN to instance mapping. - -# SAI - -## Existing SAI Attributes -Following table shows the existing SAI Attributes that will be used: - -|**Component**|**SAI Attribute**| -| :- | :- | -|STP Instance|SAI_STP_ATTR_VLAN_LIST -||SAI_STP_ATTR_BRIDGE_ID| -||SAI_STP_ATTR_PORT_LIST| -|STP Port|SAI_STP_PORT_ATTR_STP | -||SAI_STP_PORT_ATTR_BRIDGE_PORT| -||SAI_STP_PORT_ATTR_STATE| -|STP Port States|SAI_STP_PORT_STATE_LEARNING| -||SAI_STP_PORT_STATE_FORWARDING| -||SAI_STP_PORT_STATE_BLOCKING| -|VLAN STP Instance|SAI_VLAN_ATTR_STP_INSTANCE| -|Switch STP Attributes|SAI_SWITCH_ATTR_Default_STP_INST_ID| -||SAI_SWITCH_ATTR_MAX_STP_INSTANCE| - -## New SAI Attributes -MSTP design will not require any new SAI Attributes for Control Packet trap. We will use the existing traps as DMAC and LLC fields are identical for STP and MSTP - -# Additional Features - -## BPDU Guard -BPDU guard feature will also be supported by MSTP. BPDU Guard feature disables the connected device ability to initiate or participate in STP on edge ports. When STP BPDUs are received on the port where BPDU guard is enabled the port will be shutdown. User can re-enable the port administratively after ensuring the BPDUs have stopped coming on the port. - - -## Root Guard -Root guard feature will also be supported by MSTP. The Root Guard feature provides a way to enforce the root bridge placement in the network and allows STP to interoperate with user network bridges while still maintaining the bridged network topology that the administrator requires. When BPDUs are received on a root guard enabled port, the STP state will be moved to "Root inconsistent" state to indicate this condition. Once the port stops receiving superior BPDUs, Root Guard will automatically set the port back to a FORWARDING state. - -## Edge Port -Edge ports immediately transition to the forwarding state upon activation and do not participate in STP topology calculations. - - -## Uplink Fast -MSTP standard does not support uplink fast so uplink fast functionality will be disable for MSTP. - - -# Sequence Diagrams - -## MSTP global enable -![MSTP Global Enable](images/MSTP_GLobal_enable.drawio.png) - -## MSTP global disable -![MSTP Global Disable](images/MSTP_Global_disable.drawio.png) - -## MSTP region name/version change -![MSTP Region Config](images/MSTP_Region_Name.drawio.png) - - -## MSTIs Instance Creation -![Instance Creation ](images/MSTP_Instance_Create.drawio.png) - -## MSTIs Instance Deletion -![Instance Deletion](images/MSTP_Instance_Delete.drawio.png) - - -## Add VLAN to Existing Instance -![MSTP VLAN Add](images/MSTP_Add_ExistingInstance.drawio.png) - -## Del VLAN from Exisiting Instance -![MSTP VLAN Del](images/MSTP_Del_ExistingInstance.drawio.png) - - -# Configuration Commands -Following configuration commands will be provided for configuration of MSTP: -## Global Level - -- **config spanning_tree {enable|disable} {mst}** - - Enables or disables mstp at global level on all ports of the switch. - - Only one mode of STP can be enabled at a time. - - By Default disabled. - -- **config spanning_tree max_hops \** - - Specify the number of maximum hops before the BPDU is discarded inside a region. - - max-hops-value: Default: 20, range: 1-255 - -- **config spanning_tree hello \** - - Specify configuring hello interval in sec for transmission of BPDUs. - - Default: 2, range 1-10 - -- **config spanning_tree max_age \** - - Specify configuring maximum time to listen for root bridge in seconds. - - Default: 2, range 6-40 - - -## Region Level -Below commands allow configuring on region basis: - -- **config spanning_tree mst region-name \** - - Edit the name of region - - region-name: Case sensitive, characters should be less than or equal to 32, Default: mac-address of bridge - -- **config spanning-tree mst revision \** - - Revision number is used to track changes in the configuration and to synchronize the configuration across the switches in the same region. - - revision-number: Default: 0, range: 0-65535 - -## Instance Level - -Below commands allow configuration of an instance: - -- **config spanning_tree mst instance \ priority \** - - Configure priority of bridge for an instance. - - instance-id: id of the instance for which bridge priority is to be defined. If the provided instance id is not created yet, an error message is displayed. - - priority-value: Default: 32768, range: 0-61440 (should be multiple of 4096) - -- **config spanning_tree mst instance \ vlan (add|del) \** - - VLAN to instance mapping. - - instance-id: id of the instance to which VLAN is to be mapped. If the provided instance id is not created yet, an error message is displayed. - - vlan-id: Range: 1-4094. If the provided VLAN is not created yet, an error message is displayed. - - Instance is only active when there is at least one VLAN member port configured for one of the mapped VLANs. - -## Instance, Interface Level -Following commands are used for spanning-tree configurations on per instance, per interface basis: - -- **config spanning_tree mst instance \ interface \ priority \** - - Configure priority of an interface for an instance. - - priority-value: Default: 128, range: 0-240 - - Supported Instances : 64 - -- **config spanning_tree mst instance \ interface \ cost \** - - Configure path cost of an interface for an instance. - - cost-value: Range: 1-200000000 - -## Interface Level -Following new commands will be added: - -- **config spanning_tree interface {enable|disable} \** - - Configure an interface for MSTP. - -- **config spanning_tree interface edgeport {enable|disable} \** - - This command allow enabling or disabling of edge port on an interface. - -- **config spanning_tree interface bpdu_guard {enable|disable} \** - - This command allow enabling or disabling of bpdu_guard on an interface. - -- **config spanning_tree interface root_guard {enable|disable} \** - - This command allow enabling or disabling of root_guard on an interface. - - -- **config spanning_tree interface priority \ \** - - Specify configuring the port level priority for root bridge in seconds. - - Default: 128, range 0-240 - -- **config spanning_tree interface cost \ \** - - Specify configuring the port level priority for root bridge in seconds. - - Default: 0, range 1-200000000 - -- **config spanning_tree interface link-type {P2P|Shared-Lan|Auto} \** - - Specify configuring the interface at different link types. - - Default : Auto - - - **Note : These functionalities need to be explicitly enabled.** - -## Show Commands - -- show spanning_tree mst - - The output of this command will be as follows for `mstp`: -``` -admin@sonic: show spanning_tree detail - -Spanning-tree Mode: MSTP -####### MST0 (CIST) Vlans mapped : 1, 4-8, 202-4094 -Bridge Address 8000.80a2.3526.0c5e -Root Address 8000.80a2.3526.0c5e - Port Root Path cost 0 -Regional Root Address 8000.80a2.3526.0c5e - Internal cost 0 Rem hops 20 -Operational Hello Time 2, Forward Delay 15, Max Age 20, Txholdcount 6 -Configured Hello Time 2, Forward Delay 15, Max Age 20, Max Hops 20 - -Interface Role State Cost Prio.Nbr Type ---------------- -------- ---------- ------- --------- ----------- -Ethernet20 DESIGNATED FORWARDING 2000 128.25 P2P -Ethernet46 DESIGNATED FORWARDING 800 128.86 P2P -PortChannel1001 DESIGNATED FORWARDING 1000 128.45 P2P - - -####### MST1 (CIST) Vlans mapped : 2, 300, 400 -Bridge Address 8000.80a2.3526.0c5e -Root Address 8000.80a2.3526.0c5e - Port Root Path cost 0 Rem Hops 20 - -Interface Role State Cost Prio.Nbr Type ---------------- -------- ---------- ------- --------- ----------- -Ethernet46 DESIGNATED FORWARDING 800 128.86 P2P -PortChannel1001 DESIGNATED FORWARDING 1000 128.45 P2P -``` - -- show spanning_tree mst detail - -``` -admin@sonic: show spanning_tree detail - - -####### MST0 (CIST) Vlans mapped : 1, 4-8, 202-4094 -Bridge Address 8000.80a2.3526.0c5e - Root Address 8000.80a2.3526.0c5e - Port Root Path cost 0 Rem Hops 20 - -Ethernet20 is DESIGNATED FORWARDING -Port info port id 86 priority 128 cost 800 -Designated Address 8000.80a2.3526.0c5e cost 0 -Designated bridge Address 8000.80a2.3526.0c5e port id 25 -Timers: forward transitions 0 -Bpdu send 80, received 0 - -Ethernet46 is DESIGNATED FORWARDING -Port info port id 25 priority 128 cost 1000 -Designated Address 8000.80a2.3526.0c5e cost 0 -Designated bridge Address 8000.80a2.3526.0c5e port id 86 -Timers: forward transitions 0 -Bpdu send 40, received 0 - -PortChannel1001 is DESIGNATED FORWARDING -Port info port id 25 priority 128 cost 2000 -Designated Address 8000.80a2.3526.0c5e cost 0 -Designated bridge Address 8000.80a2.3526.0c5e port id 45 -Timers: forward transitions 0 -Bpdu send 30, received 0 - -####### MST1 (CIST) Vlans mapped : 2, 300, 400 -Bridge Address 8000.80a2.3526.0c5e - Root Address 8000.80a2.3526.0c5e - Port Root Path cost 0 Rem Hops 20 - -Ethernet46 is DESIGNATED FORWARDING -Port info port id 85 priority 128 cost 2000 -Designated Address 8000.80a2.3526.0c5e cost 0 -Designated bridge Address 8000.80a2.3526.0c5e port id 86 -Timers: forward transitions 0 -Bpdu send 80, received 0 - - -PortChannel1001 is DESIGNATED FORWARDING -Port info port id 25 priority 128 cost 2000 -Designated Address 8000.80a2.3526.0c5e cost 0 -Designated bridge Address 8000.80a2.3526.0c5e port id 45 -Timers: forward transitions 0 -Bpdu send 80, received 0 - -``` - - -- show spanning_tree mst instance - -``` -admin@sonic: show spanning_tree mst instance 0 - -####### MST0 (CIST) Vlans mapped : 1, 4-8, 202-4094 -Bridge Address 8000.80a2.3526.0c5e -Root Address 8000.80a2.3526.0c5e - Port Root Path cost 0 -Regional Root Address 8000.80a2.3526.0c5e - Internal cost 0 Rem hops 20 -Operational Hello Time 2, Forward Delay 15, Max Age 20, Txholdcount 6 -Configured Hello Time 2, Forward Delay 15, Max Age 20, Max Hops 20 - -Interface Role State Cost Prio.Nbr Type ---------------- -------- ---------- ------- --------- ----------- -Ethernet20 DESIGNATED FORWARDING 2000 128.25 P2P -Ethernet46 DESIGNATED FORWARDING 800 128.86 P2P -PortChannel1001 DESIGNATED FORWARDING 1000 128.45 P2P -``` - -- show spanning_tree mst interface - -``` -admin@sonic: show spanning_tree mst interface Ethernet46 - -Link Type: P2P Bpdu filter: False -Boundary : internal Bpdu guard: False - -Instance Role State Cost Prio.Nbr Vlans ---------------- -------- ---------- ------- --------- ----------- -0 DESIGNATED FORWARDING 800 128.86 1, 4-8, 202-4094 -1 DESIGNATED FORWARDING 1000 128.45 2, 300, 400 -``` - - -- show spanning_tree bpdu_guard - -``` -admin@sonic: show spanning_tree bpdu_guard - - -PortNum Shutdown Configured Port Shut due to BPDU Guard ---------- -------------------- ----------------------------- -Ethernet46 Yes Yes -PortChannel1001 No NA -``` - - -- show spanning_tree root_guard - -``` -admin@sonic: show spanning_tree root_guard - - -PortNum VLAN/MST Current State ---------- --------------------- --------------------------------------------- -Ethernet46 1, 4-8, 202-4094 Inconsistent state -PortChannel1001 Consistent state - - -``` - -- show spanning_tree mst instance \ interface \ - -``` -admin@sonic: show spanning_tree mst instance 0 interface Ethernet46 - - -Port Prio Path Edge State Role Designated Designated Designated -Num rity Cost Port Cost Root Bridge -Ethernet46 128 800 N FORWARDING Root 0 32768002438eefbc3 32768002438eefbc3 -``` - -### Statistics Commands -- show spanning_tree mst statistics instance \ - -``` - -admin@sonic: show spanning_tree mst statistics instance 0 - - -MSTP instance 0 (CIST) - VLANs 1, 4-8, 202-4094 --------------------------------------------------------------------- -PortNum BPDU Tx BPDU Rx TCN Tx TCN Rx -Ethernet20 80 4 3 4 -Ethernet46 40 6 3 4 -PortChannel15 30 6 4 1 -``` - - -## Clear Commands -- sonic-clear spanning_tree statistics - -- sonic-clear spanning_tree mst statistics instance \ - - -## Debug Commands -Following debug commands will be supported for enabling additional logging which can be viewed in /var/log/stpd.log, orchagent related logs can be viewed in /var/log/syslog. - -- debug spanning_tree mst instance \ - -- debug spanning_tree bpdu [tx|rx] - -- debug spanning_tree event - -- debug spanning_tree verbose - -- debug spanning_tree interface \ - -Following debug commands will be supported for displaying internal data structures - -- debug spanning_tree dump global - -- debug spanning_tree dump mst instance \ - -# YANG Model - - Model will be extended as follows for MSTP: - -``` -module sonic-stp { - - yang-version 1.1; - - namespace "http://github.com/sonic-net/sonic-stp"; - prefix "stp"; - - import sonic-port { - prefix port; - revision-date 2019-07-01; - } - - import sonic-portchannel { - prefix lag; - revision-date 2021-06-13; - } - - import sonic-vlan { - prefix vlan; - revision-date 2021-04-22; - } - - import sonic-device_metadata { - prefix device_metadata; - revision-date 2021-02-27; - } - - description "STP yang Module for SONiC OS"; - - revision 2023-04-18 { - description "First Revision"; - } - - grouping interfaceAttr { - leaf path_cost { - type uint64 { - range "1..200000000" { - error-message "Invalid Port Path Cost value."; - } - } - Default 200; - description - "The port's contribution, when it is the Root Port, - to the Root Path Cost for the Bridge"; - } - - leaf priority { - type uint8 { - range "0..240" { - error-message "Invalid Port Priority value."; - } - } - Default 128; - description - "The manageable component of the Port Identifier, - also known as the Port Priority"; - } - - leaf link_type { - type enumeration { - enum "P2P" { - description "Point-to-Point link type."; - } - enum "Shared-Lan" { - description "Shared LAN link type."; - } - enum "Auto" { - description "Automatically determine link type."; - } - } - Default "Auto"; - description - "The type of link for the interface. Options include - P2P, Shared-Lan, or Auto."; - } - } - container sonic-stp { - - container STP_GLOBAL { - description "Global STP table"; - - leaf mode { - type enumeration { - enum "pvst"; - enum "mstp"; - } - description "STP mode"; - } - - leaf forward_delay { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "4..30" { - error-message "forward_delay value out of range"; - } - } - Default 15; - description "Forward delay in sec"; - } - - leaf hello_time { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "1..10" { - error-message "hello_time value out of range"; - } - } - Default 2; - description "Hello time in sec"; - } - - leaf max_age { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "6..40" { - error-message "max_age value out of range"; - } - } - Default 20; - description "Max age"; - } - - leaf rootguard_timeout { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint16 { - range "5..600" { - error-message "rootguard_timeout value out of range"; - } - } - Default 30; - description "Root guard timeout in sec"; - } - - leaf priority { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; - } - must ". mod 4096 = 0" { - error-message "bridge priority must be a multiple of 4096"; - } - - type uint16 { - range "0..61440" { - error-message "priority value out of range"; - } - } - Default 32768; - description "Bridge priority"; - } - } - - container STP_MST { - max-elements 1; - key "keyleaf"; - sonic-ext:dependent-on "STP_LIST"; - - leaf keyleaf { - type enumeration { - enum GLOBAL; - } - description - "Key node identifier. It's value is always GLOBAL"; - } - - leaf name { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { - error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; - } - type string { - length "1..32"; - } - description - "MST Region name"; - } - - leaf revision { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { - error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint16 { - range "0..65535" { - error-message "revision value out of range"; - } - } - description - "MST Revision number"; - } - - leaf max_hops { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { - error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "1..255" { - error-message "max-hops value out of range"; - } - } - Default 20; - description - "MST Max hops"; - } - - leaf hello_time { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { - error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "1..10" { - error-message "hello_time value out of range"; - } - } - Default 2; - description - "MST hello time"; - } - - leaf max_age { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { - error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "6..40" { - error-message "max_age value out of range"; - } - } - Default 20; - description - "MST max age"; - } - - leaf forward_delay { - must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { - error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; - } - type uint8 { - range "4..30" { - error-message "forward_delay value out of range"; - } - } - Default 15; - description - "MST forward delay"; - } - } - container STP_MST_INST { - list STP_MST_INST_LIST { - key "instance"; - - leaf instance { - type uint16; - description - "Instance identifier"; - } - - leaf-list vlan { - type string; - description - "Vlan list"; - } - - leaf bridge_priority { - type uint16 { - range "0..61440" { - error-message "Invalid Bridge Priority value."; - } - } - Default 32768; - description - "The manageable component of the Bridge Identifier"; - } - } - } - - container STP_MST_PORT { - list STP_MST_PORT_LIST { - key "inst_id ifname"; - - leaf inst_id { - type leafref { - path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; - } - description - "Reference to MST Instance"; - } - - leaf ifname { - type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; - } - description - "Reference to Ethernet interface or PortChannel in the STP database"; - } - uses interfaceAttr; - } - } - - list STP_MST_INST_TABLE_LIST { - sonic-ext:db-name "APPL_DB"; - key "inst_id"; - - leaf inst_id { - type leafref { - path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; - } - description - "Reference to MST Instance"; - } - - leaf-list vlan { - type string; - description - "Vlan list"; - } - - leaf bridge_priority { - type uint16; - description - "The manageable component of the Bridge Identifier"; - } - - leaf root_priority { - type string; - description - "The manageable component of the Port Identifier"; - } - - leaf root_address { - type string; - description - ""; - } - - leaf root_cost { - type string; - description - ""; - } - - leaf root_port { - type string; - description - ""; - } - - leaf bridge_address { - type string; - description - ""; - } - } - } -} -``` - -# Rest API Support - -Rest API is out of scope for this HLD. - -# Warm Boot -Warm boot will not be supported. The IEEE 802.1s standard of MSTP does not define any potential way to support it as this might cause loops in the network. - -User is expected to do a cold reboot when MSTP is running. If a user tries to perform a warm boot while MSTP is enabled, an error message will be displayed. User will first need to disable MSTP so the topology converges and reevaluates the paths. - - -# Testing Requirements - -## Unit Test Cases - -### CLI Test Cases - -1. Verify CLI to enable MSTP globally. - -2. Verify CLI to disable MSTP globally. - -3. Verify CLI to set MSTP region name. - -4. Verify CLI to set MSTP region revision. - -5. Verify CLI to set MSTP port priority. - -6. Verify CLI to set MSTP hello-time. - -7. Verify CLI to set MSTP cost-value. - -8. Verify CLI to set MSTP max-hops. - -9. Verify CLI to set MSTP root guard. - -10. Verify CLI to set MSTP BPDU guard. - -11. Verify CLI to set edge port. - -12. Verify CLI to create an instance. - -13. Verify CLI to delete an instance. - -14. Verify CLI to clear MSTP region name. - -15. Verify CLI to clear MSTP region revision. - -16. Verify CLI to clear MSTP port priority. - -17. Verify CLI to clear MSTP hello-time. - -18. Verify CLI to clear MSTP cost-value. - -19. Verify CLI to clear MSTP max-hops. - -20. Verify CLI to clear MSTP root guard. - -21. Verify CLI to clear MSTP BPDU guard. - -22. Verify CLI to clear bridge priority in an instance. - -23. Verify CLI to map VLAN to an instance. - -24. Verify CLI to delete VLAN from an instance. - -25. Verify CLI to set interface priority on a per-instance basis. - -26. Verify CLI to set interface cost on a per-instance basis. - -27. Verify CLI to display all information related to the region. - -28. Verify CLI to display information related to a specific instance. - -29. Verify CLI to display information about a specific interface in a specific instance. - -30. Verify CLI to display statistics. - -31. Verify CLI to display statistics on a per-instance basis. - -32. Verify CLI to clear statistics. - -33. Verify CLI to clear statistics on a per-instance basis. - -34. Verify CLI to clear statistics on a per-interface per-instance basis. - -35. Verify the commands that are disabled for MSTP mode. - -### Functional Test Cases - -1. Verify CONFIG DB is populated with configured MSTP parameters. - -2. Verify MSTP instances running on multiple VLANs. - -3. Verify multiple VLANs can be mapped to a single instance. - -4. Verify VLAN to STP instance mapping is populated correctly in APP DB, ASIC DB, and Hardware. - -5. Verify instance STP ports are created for its VLAN members. - -6. Verify correct format of MSTP BPDU. - -7. Verify MSTP traps are created. - -8. Verify correct operation of CIST and MSTIs. - -9. Verify two bridges are in the same region only if they have the same region name, revision, and instance to VLAN mapping. - -10. Verify the loop-free topology inside and between regions. - -11. Verify the operational values of forward delay, max age, hello timer, and max hops are of the CIST root. - -12. Verify FDB flush as a result of topology change. - -13. Verify instance is active only when there is at least one VLAN member of any of the VLANs that are mapped to it. - -14. Verify altering bridge priority can alter the selection of CIST root, regional root, and MSTI root. - -15. Verify altering port priority can alter the selection of designated port. - -16. Verify max-hops by changing value. - -17. Verify hello-timer by changing timer values. - -18. Verify max-age by changing intervals. - -19. Verify altering bridge priority will alter Root Bridge selection. - -20. Verify altering port priority will alter Root port selection. - -21. Verify altering port priority will alter Designated port selection. - -22. Verify altering port cost results in the path with the lowest root path cost being selected as the root port. - -23. Verify port states on the same physical interface. - -24. Verify MSTP interoperability with STP and RSTP. - -25. Verify MSTP operational data is synced to APP DB and ASIC DB correctly. - -26. Verify MSTP over LAG. - -27. Verify MSTP over static breakout ports. - -28. Verify BPDU Guard Activation on Ports. - -29. Verify BPDU Guard Port State Transition. - -30. Verify BPDU Guard Recovery Mechanism. - -31. Verify BPDU Guard and MSTP Interaction. - -32. Verify MSTP Topology Changes Detection. - -33. Verify MSTP and VLAN Integration. - -34. Verify MSTP Path Cost Calculation. - -35. Verify MSTP Failover. - -### Logging and Debugging Test Cases - -1. Verify debugging logs for a region. - -2. Verify debugging logs for an instance. - -3. Verify debugging of internal data structure of a region. - -4. Verify debugging of internal data structure of an instance. - -5. Verify debugging of internal data structure of a specific interface in an instance. - -### SAI - -1. Verify creation of STP instance. - -2. Verify adding VLAN to an instance. - -3. Verify deleting VLAN from an instance. - -4. Verify adding a port to an instance. - -5. Verify deleting a port from an instance. - -6. Verify port state for different instances. - -### L3 - -1. Verify normal flow of L3 traffic with the MSTP topology. diff --git a/SONiC_PVST_HLD.md b/SONiC_PVST_HLD.md deleted file mode 100644 index aaef99aaf15..00000000000 --- a/SONiC_PVST_HLD.md +++ /dev/null @@ -1,746 +0,0 @@ -# Feature Name -PVST -# High Level Design Document -#### Rev 1.0 - -# Table of Contents - * [List of Tables](#list-of-tables) - * [Revision](#revision) - * [About This Manual](#about-this-manual) - * [Scope](#scope) - * [Definition/Abbreviation](#definitionabbreviation) - * [Requirements Overview](#requirement-overview) - * [Functional Requirements](#functional-requirements) - * [Configuration and Management Requirements](#configuration-and-management-requirements) - * [Scalability Requirements](#scalability-requirements) - * [Warm Boot Requirements](#warm-boot-requirements) - * [Functionality](#-functionality) - * [Functional Description](#functional-description) - * [Design](#design) - * [Overview](#overview) - * [DB Changes](#db-changes) - * [CONFIG DB](#config-db) - * [APP DB](#app-db) - * [STATE DB](#state-db) - * [Switch State Service Design](#switch-state-service-design) - * [Orchestration Agent](#orchestration-agent) - * [STP Container](#stp-container) - * [SAI](#sai) - * [CLI](#cli) - * [Configuration Commands](#configuration-commands) - * [Show Commands](#show-commands) - * [Debug Commands](#debug-commands) - * [Clear Commands](#clear-commands) - * [Flow Diagrams](#flow-diagrams) - * [Serviceability and Debug](#serviceability-and-debug) - * [Warm Boot Support](#warm-boot-support) - * [Scalability](#scalability) - * [Unit Test](#unit-test) - -# List of Tables -[Table 1: Abbreviations](#table-1-abbreviations) - -# Revision -| Rev | Date | Author | Change Description | -|:---:|:-----------:|:-------------------------:|-----------------------------------| -| 0.1 | 05/02/2019 | Sandeep, Praveen | Initial version | -| 0.2 | 05/02/2019 | Sandeep, Praveen | Incorporated Review comments | -| 0.3 | 06/25/2019 | Sandeep, Praveen | Incorporated Review comments | -| 1.0 | 10/15/2019 | Sandeep, Praveen | Minor changes post implementation | - - -# About this Manual -This document provides general information about the PVST (Per VLAN spanning tree) feature implementation in SONiC. -# Scope -This document describes the high level design of PVST feature. - -# Definition/Abbreviation -### Table 1: Abbreviations -| **Term** | **Meaning** | -|--------------------------|-------------------------------------| -| BPDU | Bridge protocol data unit | -| PVST | Per VLAN Spanning tree | -| STP | Spanning tree protocol | - - -# 1 Requirement Overview -## 1.1 Functional Requirements - - - 1. Support PVST+ per VLAN spanning tree - 2. Support Portfast functionality - 3. Support Uplink fast functionality - 4. Support BPDU guard functionality - 5. Support Root guard functionality - 6. Bridge-id should include the VLAN id of the pvst instance along with bridge MAC address to derive a unique value for each instance. - 7. Port channel path cost will be same as the member port cost, it will not be cumulative of member ports cost - 8. DA MAC in case of PVST should be cisco pvst mac - 01:00:0C:CC:CC:CD - 9. Support protocol operation on static breakout ports - 10. Support protocol operation on Port-channel interfaces - - -## 1.2 Configuration and Management Requirements -This feature will support CLI and REST based configurations. - 1. Support CLI configurations as mentioned in section 3.6.2 - 2. Support show commands as mentioned in section 3.6.3 - 3. Support debug commands as mentioned in section 3.6.4 - 4. Support Openconfig yang model - with extensions for supporting PVST - 5. Support REST APIs for config and operational data - -## 1.3 Scalability Requirements -16k port-vlan instances with max 255 STP instances. -The scaling limit might differ depending on the platform and the CPU used, which needs to be determined based on testing. - -## 1.4 Warm Boot Requirements - -Warm boot is not supported in this release. User is expected to do cold reboot when PVST is running so that topology will reconverge and traffic will be redirected via alternate paths. - -If PVST is enabled and user tries to perform warm reboot an error will be displayed indicating PVST doesnt support warm reboot. - - -# 2 Functionality - -## 2.1 Functional Description -The Spanning Tree Protocol (STP) prevents Layer 2 loops in a network and provides redundant links. If a primary link fails, the backup link is activated and network traffic is not affected. STP also ensures that the least cost path is taken when multiple paths exist between the devices. - -When the spanning tree algorithm is run, the network switches transform the real network topology into a spanning tree topology. In an STP topology any LAN in the network can be reached from any other LAN through a unique path. The network switches recalculate a new spanning tree topology whenever there is a change to the network topology. - -For each switch in the topology, a port with lowest path cost to the root bridge is elected as root port. - -For each LAN, the switches that attach to the LAN select a designated switch that is the closest to the root switch. The designated switch forwards all traffic to and from the LAN. The port on the designated switch that connects to the LAN is called the designated port. The switches decide which of their ports is part of the spanning tree. A port is included in the spanning tree if it is a root port or a designated port. - -PVST+ allows for running multiple instances of spanning tree on per VLAN basis. - -One of the advantage with PVST is it allows for load-balancing of the traffic. When a single instance of spanning tree is run and a link is put into blocking state for avoiding the loop, it will result in inefficient bandwidth usage. With per VLAN spanning tree multiple instances can be run such that for some of the instances traffic is blocked over the link and for other instances traffic is forwared allowing for load balancing of traffic. - -PVST+ support allows the device to interoperate with IEEE STP and also tunnel the PVST+ BPDUs transparently across IEEE STP region to potentially connect other PVST+ switches across the IEEE STP region. For interop with IEEE STP, PVST+ will send untagged IEEE BPDUs (MAC - 01:80:C2:00:00:00) with information corresponding to VLAN 1. The STP port must be a member of VLAN 1 for interoperating with IEEE STP. - -# 3 Design -## 3.1 Overview - -![STP](images/STP_Architecture.png "Figure 1: High level architecture") -__Figure 1: High level architecture__ - -High level overview: - -STP container will host STPMgr and STPd process. - -STPMgr will handle all the STP configurations and VLAN configurations via config DB and state DB respectively. - -STPd process will handle all the protocol functionality and has following interactions - - * Linux kernel for packet tx/rx and netlink events - * STPMgr interaction for configuration handling - * STPSync is part of STPd handling all the STP operational data updates to APP DB - -Alternate design consideration: -Linux kernel has support for spanning-tree but is not being considered for following reasons - * Supports only STP, no support for RSTP and MSTP - * Currently SONiC does not create a netdevice for each vlan, port combination as it relies on vlan aware bridge configuration. For supporting per VLAN spanning tree a netdevice needs to be created for each vlan, port combination, this will result in higher memory requirements due to additional netdevices and also a major change from SONiC perspective. - -## 3.2 DB Changes -This section describes the changes made to different DBs for supporting the PVST protocol. -### 3.2.1 CONFIG DB -Following config DB schemas are defined for supporting this feature. -### STP_GLOBAL_TABLE - ;Stores STP Global configuration - ;Status: work in progress - key = STP|GLOBAL ; Global STP table key - mode = "pvst" ; spanning-tree mode pvst - rootguard_timeout = 3*DIGIT ; root-guard timeout value (5 to 600 sec, DEF:30 sec) - forward_delay = 2*DIGIT ; forward delay in secs (4 to 30 sec, DEF:15 sec) - hello_time = 2*DIGIT ; hello time in secs (1 to 10 sec, DEF:2sec) - max_age = 2*DIGIT ; maximum age time in secs (6 to 40 sec, DEF:20sec) - priority = 5*DIGIT ; bridge priority (0 to 61440, DEF:32768) - -### STP_VLAN_TABLE - ;Stores STP configuration per VLAN - ;Status: work in progress - key = STP_VLAN|"Vlan"vlanid ; VLAN with prefix "STP_VLAN" - forward_delay = 2*DIGIT ; forward delay in secs (4 to 30 sec, DEF:15 sec) - hello_time = 2*DIGIT ; hello time in secs (1 to 10 sec, DEF:2sec) - max_age = 2*DIGIT ; maximum age time in secs (6 to 40 sec, DEF:20sec) - priority = 5*DIGIT ; bridge priority (0 to 61440, DEF:32768) - enabled = "true"/"false" ; spanning-tree is enabled or not - -### STP_VLAN_INTF_TABLE - ;Stores STP interface details per VLAN - ;Status: work in progress - key = STP_VLAN_INTF|"Vlan"vlanid|ifname ; VLAN+Intf with prefix "STP_VLAN_INTF" ifname can be physical or port-channel name - path_cost = 9*DIGIT ; port path cost (1 to 200000000) - priority = 3*DIGIT ; port priority (0 to 240, DEF:128) - -### STP_INTF_TABLE - ;Stores STP interface details - ;Status: work in progress - key = STP_INTF|ifname ; ifname with prefix STP_INTF, ifname can be physical or port-channel name - enabled = BIT ; is the STP on port enabled (1) or disabled (0) - root_guard = BIT ; is the root guard on port enabled (1) or disabled (0) - bpdu_guard = BIT ; is the bpdu guard on port enabled (1) or disabled (0) - bpdu_guard_do_disable = BIT ; port to be disabled when it receives a BPDU; enabled (1) or disabled (0) - path_cost = 9*DIGIT ; port path cost (2 to 200000000) - priority = 3*DIGIT ; port priority (0 to 240, DEF:128) - portfast = BIT ; Portfast is enabled or not - uplink_fast = BIT ; Uplink fast is enabled or not - -### 3.2.2 APP DB - -### STP_VLAN_TABLE - ;Stores the STP per VLAN operational details - ;Status: work in progress - key = STP_VLAN:"Vlan"vlanid - bridge_id = 16HEXDIG ; bridge id - max_age = 2*DIGIT ; maximum age time in secs (6 to 40 sec, DEF:20sec) - hello_time = 2*DIGIT ; hello time in secs (1 to 10 sec, DEF:2sec) - forward_delay = 2*DIGIT ; forward delay in secs (4 to 30 sec, DEF:15 sec) - hold_time = 1*DIGIT ; hold time in secs (1 sec) - last_topology_change = 1*10DIGIT ; time in secs since last topology change occured - topology_change_count = 1*10DIGIT ; Number of times topology change occured - root_bridge_id = 16HEXDIG ; root bridge id - root_path_cost = 1*9DIGIT ; port path cost - desig_bridge_id = 16HEXDIG ; designated bridge id - root_port = ifName ; Root port name - root_max_age = 1*2DIGIT ; Max age as per root bridge - root_hello_time = 1*2DIGIT ; hello time as per root bridge - root_forward_delay = 1*2DIGIT ; forward delay as per root bridge - stp_instance = 1*4DIGIT ; STP instance for this VLAN - -### STP_VLAN_INTF_TABLE - ;Stores STP VLAN interface details - ;Status: work in progress - key = STP_VLAN_INTF:"Vlan"vlanid:ifname ; VLAN+Intf with prefix "STP_VLAN_INTF" - port_num = 1*3DIGIT ; port number of bridge port - path_cost = 1*9DIGIT ; port path cost (1 to 200000000) - priority = 3*DIGIT ; port priority (0 to 240, DEF:128) - port_state = "state" ; STP state - disabled, block, listen, learn, forward - desig_cost = 1*9DIGIT ; designated cost - desig_root = 16HEXDIG ; designated root - desig_bridge = 16HEXDIG ; designated bridge - desig_port = 1*3DIGIT ; designated port - fwd_transitions = 1*5DIGIT ; number of forward transitions - bpdu_sent = 1*10DIGIT ; bpdu transmitted - bpdu_received = 1*10DIGIT ; bpdu received - tcn_sent = 1*10DIGIT ; tcn transmitted - tcn_received = 1*10DIGIT ; tcn received - root_guard_timer = 1*3DIGIT ; root guard current timer value - -### STP_INTF_TABLE - ;Stores STP interface details - ;Status: work in progress - key = STP_INTF:ifname ; ifname with prefix STP_INTF, ifname can be physical or port-channel name - bpdu_guard_shutdown = "yes" / "no" ; port disabled due to bpdu-guard - port_fast = "yes" / "no" ; port fast is enabled or not - - -### STP_PORT_STATE_TABLE - ;Stores STP port state per instance - ;Status: work in progress - key = STP_PORT_STATE:ifname:instance ; ifname and the STP instance - state = 1DIGIT ; 0-disabled, 1-block, 2-listen, 3-learn, 4-forward - - -### STP_VLAN_INSTANCE_TABLE - ;Defines VLANs and the STP instance mapping - ;Status: work in progress - key = STP_VLAN_INSTANCE_TABLE:"Vlan"vlanid ; DIGIT 1-4095 with prefix "Vlan" - stp_instance = 1*4DIGIT ; STP instance associated with this VLAN - - -### STP_FASTAGEING_FLUSH_TABLE - ;Defines vlans for which fastageing is enabled - ;Status: work in progress - key = STP_FASTAGEING_FLUSH_TABLE:"Vlan"vlanid ; vlan id for which flush needs to be done - state = "true" ; true perform flush - -### 3.2.3 STATE DB - -### STP_TABLE - ;Defines the global STP state table - ;Status: work in progress - key = STP_TABLE:GLOBAL ; key - max_stp_inst = 1*3DIGIT ; Max STP instances supported by HW - - -## 3.3 Switch State Service Design -### 3.3.1 Orchestration Agent - -All STP operations for programming the HW will be handled as part of OrchAgent. OrchAgent will listen to below updates from APP DB for updating the ASIC DB via SAI REDIS APIs. - - * Port state udpate - STP_PORT_STATE_TABLE - - * VLAN to instance mapping - STP_VLAN_INSTANCE_TABLE - -Orchagent will also listen to updates related to Fast ageing on APP DB. When fast ageing is set for the VLAN due to topology change, Orchagent will perform FDB/MAC flush for the VLAN. - - * FDB/MAC flush - STP_FASTAGEING_FLUSH_TABLE - - - -## 3.4 STP Container - -STP container will have STPMgr and STPd processes. - -STPMgr process will register with the config DB for receiving all the STP configurations and with state DB for VLAN configurations. STPMgr will notify this configuration information to STPd for protocol operation. STPMgr will also handle the STP instance allocation. - -STPd process will handle following interactions. STPd will use libevent for processing the incoming events and timers. -1) Packet processing - - * Socket of PF_PACKET type will be created for packet tx/rx - - * Filters will be attached to the socket to receive the STP BPDUs based on DA MAC - - * PACKET_AUXDATA socket option will be set to get the VLAN id of the packet received from the cmsg headers - -2) Configuration - All STP CLI and VLAN configurations will be received from STPMgr via unix domain socket -3) Timers handling - Timer events are generated every 100ms for handling STP protocol timers -4) Port events - Netlink socket interface for processing create/delete of port, lag interface, lag member add/delete, link state changes and port speed -5) Operational updates - STPsync is part of STPd and handles all the updates to APP DB. All DB interactions are detailed in the Section 4. -6) STP Port state sync to linux kernel - Currently the vlan aware bridge doesnt support programming the STP state into linux bridge. As a workaround, when STP state is not forwarding, corresponding VLAN membership on that port will be removed to filter the packets on blocking port. - -### Interface DB: - -In SONiC, ethernet interface is represented in the format Ethernet where id represents the physical port number and port-channel is represented by PortChannel where id is a 4 digit numerical value. - -STPd implementation makes use of its own internal port id for its protocol operation. These port ids are used for bit representation in port masks and also for indexing the array which holds the pointers to STP port level information. So to continue using these mechanisms it is required to convert the SONiC representation of interface to local STP port ids. So when STPd interacts with other components in the system local port id will be converted to SONiC interface name, similarly all messages received from other components with SONiC interface name will be converted to local STP port id before processing. For this purpose an interface DB (AVL tree) will be maintained to map the SONiC interface names to local STP port ids. - - - -### Local STP Port id allocation: - -For allocating local port ids STPd needs to know the max number of physical ports and Port-channel interfaces supported on the device. Currently there is no mechanism to obtain these values in a direct way (like reading from DBs) so below logic will be used to arrive at max ports - - -Max STP Ports = Max physical ports + Max Port-Channel interfaces - -where, - -Max physical ports will be determined from the higher interface id populated say for example if higher port is Ethernet252 (or 254) - max ports will be 256 to ensure breakout ports are accomodated. - -Max Port-Channel interfaces will be same as max physical ports to accomodate the worst case scenario of each Port-channel having only one port. - - -Post bootup, Portsyncd reads the port_config.ini file which contains the port specific configuration information, and updates the APP DB with this information. Orchagent listens to these APP DB updates and takes care of creating all the interfaces in linux kernel and the hardware. Kernel sends netlink updates for the interfaces being created which Portsyncd listens to, once Portsyncd confirms all the interfaces have been configured it will generate PortInitDone notification. STPd will receive this message via STPMgr and then gets all the interface information via netlink for allocating the local STP port ids. - -Note: The port id for Port-channel interface will be allocated only when the first member port is added, this ensures Port-channel interfaces with no member ports dont burn the port ids. - -Example of port id allocation - -``` -SONiC interface STP Port id -Ethernet0 0 -Ethernet4 4 -Ethernet8 8 -Ethernet252 252 -PortChannel10 256 -PortChannel5 257 -PortChannel20 258 -``` - -Note: As Port-channel port ids are dynamically allocated it might result in same port channel getting different value post reboot. To ensure a predictable convergence where port-channel port id is used as tie breaker, user needs to configure appropriate port priority value. - -### 3.4.1 BPDU trap mechanism -SONiC uses copp configuration file 00-copp.config.json for configuring the trap group, ids, cpu priority queue and a policer. This functionality has been extended for supporting STP and PVST BPDU trap to CPU. - -## 3.5 SAI -STP SAI interface APIs are already defined and is available at below location - - -https://github.com/opencomputeproject/SAI/blob/master/inc/saistp.h - -Control packet traps required for STP (SAI_HOSTIF_TRAP_TYPE_STP) and PVST (SAI_HOSTIF_TRAP_TYPE_PVRST) are defined in below SAI spec - - -https://github.com/opencomputeproject/SAI/blob/master/inc/saihostif.h - -## 3.6 CLI -### 3.6.1 Data Models -Openconfig STP yang model will be extended to support PVST. - -### 3.6.2 Configuration Commands - -### 3.6.2.1 Global level - -### 3.6.2.1.1 Enabling or Disabling of PVST feature - Global spanning-tree mode -This command allows enabling the spanning tree mode for the device. - -**config spanning_tree {enable|disable} {pvst}** - -Note: -1) When global pvst mode is enabled, by default spanning tree will be enabled on the first 255 VLANs, for rest of the VLAN spanning tree will be disabled. -2) When multiple spanning-tree modes are supported, only one mode can be enabled at any given point of time. - -### 3.6.2.1.2 Per VLAN spanning-tree -This command allows enabling or disabling spanning-tree on a VLAN. - -**config spanning_tree vlan {enable|disable} ** - - ### 3.6.2.1.3 Root-guard timeout - -This command allows configuring a root guard timeout value. Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state(default = 30 secs), range 5-600. - -**config spanning_tree root_guard_timeout ** - - ### 3.6.2.1.4 Forward-delay - -This command allows configuring the forward delay time in seconds (default = 15), range 4-30. - -**config spanning_tree forward_delay ** - - ### 3.6.2.1.5 Hello interval -This command allow configuring the hello interval in secs for transmission of bpdus (default = 2), range 1-10. - -**config spanning_tree hello ** - - ### 3.6.2.1.6 Max-age -This command allows configuring the maximum time to listen for root bridge in seconds (default = 20), range 6-40. - -**config spanning_tree max_age ** - - ### 3.6.2.1.7 Bridge priority -This command allows configuring the bridge priority in increments of 4096 (default = 32768), range 0-61440. - -**config spanning_tree priority ** - - ### 3.6.2.2 VLAN level -Below commands are similar to the global level commands but allow configuring on per VLAN basis. - -**config spanning_tree vlan forward_delay ** - -**config spanning_tree vlan hello ** - -**config spanning_tree vlan max_age ** - -**config spanning_tree vlan priority ** - - ### 3.6.2.3 VLAN, interface level -Below configurations allow STP parameters to be configured on per VLAN, interface basis. - - ### 3.6.2.3.1 Port Cost -This command allows to configure the port level cost value for a VLAN, range 1 - 200000000 - -**config spanning_tree vlan interface cost ** - - ### 3.6.2.3.2 Port priority -This command allows to configure the port level priority value for a VLAN, range 0 - 240 (default 128) - -**config spanning_tree vlan interface priority ** - - ### 3.6.2.4 Interface level - - ### 3.6.2.4.1 STP enable/disable on interface - -This command allows enabling or disabling of STP on an interface, by default STP will be enabled on the interface if global STP mode is configured. - -**config spanning_tree interface {enable|disable} ** - - ### 3.6.2.4.2 Root Guard: -The Root Guard feature provides a way to enforce the root bridge placement in the network and allows STP to interoperate with user network bridges while still -maintaining the bridged network topology that the administrator requires. When BPDUs are received on a root guard enabled port, the STP state will be moved to "Root inconsistent" state to indicate this condition. Once the port stops receiving superior BPDUs, Root Guard will automatically set the port back to a FORWARDING state after the timeout period has expired. - -This command allow enabling or disabling of root guard on an interface. - -**config spanning_tree interface root_guard {enable|disable} ** - -Following syslogs will be generated when entering and exiting root guard condition respectively - - -STP: Root Guard interface Ethernet4, VLAN 100 inconsistent (Received superior BPDU) - -STP: Root Guard interface Ethernet4, VLAN 100 consistent (Timeout) - - ### 3.6.2.4.3 BPDU Guard -BPDU Guard feature disables the connected device ability to initiate or participate in STP on edge ports. When STP BPDUs are received on the port where BPDU guard is enabled the port will be shutdown. User can re-enable the port administratively after ensuring the BPDUs have stopped coming on the port. - -Below command allows enabling or disabling of bpdu guard on an interface. - -**config spanning_tree interface bpdu_guard {enable|disable} ** - - -By default, BPDU guard will only generate a syslog indicating the condition, for taking an action like disabling the port below command can be used with shutdown option - -**config spanning_tree interface bpdu_guard {enable|disable} [--shutdown | -s]** - -Following syslog will be generated when BPDU guard condition is entered - - -STP: Tagged BPDU(100) received, interface Ethernet4 disabled due to BPDU guard trigger - -STPd will update the config DB for shutting down the interface, user can enable the interface back once it has stopped receiving the BPDUs. - - ### 3.6.2.4.4 Port fast -Portfast command is enabled by default on all ports, portfast allows edge ports to move to forwarding state quickly when the connected device is not participating in spanning-tree. - -Below command allows enabling or disabling of portfast on an interface. - -**config spanning_tree interface portfast {enable|disable} ** - - ### 3.6.2.4.4 Uplink fast - Uplink fast feature enhances STP performance for switches with redundant uplinks. Using the default value for the standard STP forward delay, convergence following a transition from an active link to a redundant link can take 30 seconds (15 seconds for listening and an additional 15 seconds for learning). - -When uplink fast is configured on the redundant uplinks, it reduces the convergence time to just one second by moving to forwarding state (bypassing listening and learning modes) in just once second when the active link goes down. - -**config spanning_tree interface uplink_fast {enable|disable} ** - - ### 3.6.2.4.5 Port level priority -This command allows to configure the port level priority value, range 0 - 240 (default 128) - -**config spanning_tree interface priority ** - - ### 3.6.2.4.6 Port level path cost -This command allows to configure the port level cost value, range 1 - 200000000 - -**configure spanning_tree interface cost ** - - - -### 3.6.3 Show Commands -- show spanning_tree -- show spanning_tree vlan -- show spanning_tree vlan interface - -``` -Spanning-tree Mode: PVST -VLAN 100 - STP instance 3 --------------------------------------------------------------------- -STP Bridge Parameters: - -Bridge Bridge Bridge Bridge Hold LastTopology Topology -Identifier MaxAge Hello FwdDly Time Change Change -hex sec sec sec sec sec cnt -8000002438eefbc3 20 2 15 1 0 0 - -RootBridge RootPath DesignatedBridge Root Max Hel Fwd -Identifier Cost Identifier Port Age lo Dly -hex hex sec sec sec -8000002438eefbc3 0 8000002438eefbc3 Root 20 2 15 - -STP Port Parameters: - -Port Prio Path Port Uplink State Designated Designated Designated -Num rity Cost Fast Fast Cost Root Bridge -Ethernet13 128 4 Y N FORWARDING 0 8000002438eefbc3 8000002438eefbc3 -``` - -- show spanning_tree bpdu_guard -This command displays the interfaces which are BPDU guard enabled and also the state if the interface is disabled due to BPDU guard. -``` -show spanning_tree bpdu_guard -PortNum Shutdown Port shut - Configured due to BPDU guard -------------------------------------------------- -Ethernet1 Yes Yes -Ethernet2 Yes No -Port-Channel2 No NA -``` - --show spanning_tree root_guard -This command displays the interfaces where root guard is active and the pending time for root guard timer expiry -``` -Root guard timeout: 120 secs - -Port VLAN Current State -------------------------------------------------- -Ethernet1 1 Inconsistent state (102 seconds left on timer) -Ethernet8 100 Consistent state -``` - -- show spanning_tree statistics -- show spanning_tree statistics vlan -This command displays the spanning-tree bpdu statistics. Statistics will be synced to APP DB every 10 seconds. -``` -VLAN 100 - STP instance 3 --------------------------------------------------------------------- -PortNum BPDU Tx BPDU Rx TCN Tx TCN Rx -Ethernet13 10 4 3 4 -PortChannel15 20 6 4 1 -``` - - -### 3.6.4 Debug Commands -Following debug commands will be supported for enabling additional logging which can be viewed in /var/log/stpd.log, orchangent related logs can be viewed in /var/log/syslog. -- debug spanning_tree - This command must be enabled for logs to be written to log file, after enabling any of the below commands. -- debug spanning_tree bpdu [tx|rx] -- debug spanning_tree event -- debug spanning_tree interface -- debug spanning_tree verbose -- debug spanning_tree vlan - -To disable the debugging controls enabled '-d' or '--disable' option can be used, an example of disabling bpdu debugging is shown below - -- debug spanning_tree bpdu -d - -Follow commands can be used to reset and display the debugging controls enabled respectively -- debug spanning_tree reset -- debug spanning_tree show - -Following debug commands will be supported for displaying internal data structures -- debug spanning_tree dump global -- debug spanning_tree dump vlan -- debug spanning_tree dump interface - -### 3.6.5 Clear Commands -Following clear commands will be supported -- sonic-clear spanning_tree statistics -- sonic-clear spanning_tree statistics vlan -- sonic-clear spanning_tree statistics vlan-interface -- sonic-clear spanning_tree statistics interface - -### 3.6.6 REST API Support -REST APIs is not supported in this release - -# 4 Flow Diagrams - -## 4.1 Global spanning-tree mode - -![STP](images/Global_PVST_enable.png "Figure 2: Global PVST mode enable") - -__Figure 2: Global PVST mode enable__ - -![STP](images/Global_PVST_disable.png "Figure 3: Global PVST mode disable") - -__Figure 3: Global PVST mode disable__ - -## 4.2 Per VLAN spanning-tree -![STP](images/STP_VLAN_enable.png "Figure 4: STP VLAN enable") - -__Figure 4: STP VLAN enable__ - -![STP](images/STP_disable_VLAN.png "Figure 5: STP VLAN disable") - -__Figure 5: STP VLAN disable__ - -## 4.3 STP enable/disable on interface -![STP](images/STP_enable_interface.png "Figure 6: STP enable on an interface") - -__Figure 6: STP enable on an interface__ - -![STP](images/STP_disable_on_interface.png "Figure 7: STP disable on an interface") - -__Figure 7: STP disable on an interface__ - -## 4.4 STP port state update -![STP](images/STP_Port_state.png "Figure 8: STP port state update") - -__Figure 8: STP port state update__ - -## 4.5 STP Topology change -![STP](images/Topology_change_update.png "Figure 9: STP Topology change") - -__Figure 9: STP Topology change__ - -## 4.6 STP Port id allocation -![STP](images/STP_Port_id_allocation.png "Figure 10: STP Port id allocation") - -__Figure 10: STP Port id allocation__ - -# 5 Serviceability and Debug -Debug command and statistics commands as mentioned in Section 3.6.3 and 3.6.4 will be supported. Debug command output will be captured as part of techsupport. - -# 6 Warm Boot Support -Warm boot is not supported - -# 7 Scalability -16k port-vlan instances with max 255 STP instances. -The scaling limit might differ depending on the platform and the CPU used, which needs to be determined based on testing. - -# 8 Unit Test - -CLI: -1) Verify CLI to enable spanning-tree globally -2) Verify CLI to enable spanning-tree per VLAN -3) Verify CLI to enable spanning-tree on interface -4) Verify CLI to set Bridge priority -5) Verify CLI to set Bridge forward-delay -6) Verify CLI to set Bridge hello-time -7) Verify CLI to set Bridge max-age -8) Verify CLI to set Bridge Port path cost -9) Verify CLI to set Bridge Port priority -10) Verify CLI to set Bridge root guard -11) Verify CLI to set Bridge root guard timeout -12) Verify CLI to set Bridge bpdu guard -13) Verify CLI to set Bridge bpdu guard with do-disable action -14) Verify CLI to set portfast -15) Verify CLI to set uplink fast -16) Verify CLI to clear uplink fast -17) Verify CLI to clear portfast -18) Verify CLI to clear Bridge bpdu guard with do-disable action -19) Verify CLI to clear Bridge bpdu guard -20) Verify CLI to clear Bridge root guard timeout -21) Verify CLI to clear Bridge root guard -22) Verify CLI to clear Bridge Port priority -23) Verify CLI to clear Bridge Port path cost -24) Verify CLI to clear Bridge max-age -25) Verify CLI to clear Bridge hello-time -26) Verify CLI to clear Bridge forward-delay -27) Verify CLI to clear Bridge priority -28) Verify CLI to disabling spanning-tree on interface -29) Verify CLI to disabling spanning-tree per VLAN -30) Verify CLI to disabling spanning-tree globally -31) Verify CLI to display spanning-tree running config -32) Verify CLI to display spanning-tree state information -33) Verify CLI to display spanning-tree statistics -34) Verify CLI to display bpdu-guard port information -35) Verify CLI for clear spanning tree statistics - -Functionality -1) Verify Config DB is populated with configured STP values -2) Verify PVST instances running on multiple VLANs -3) Verify VLAN to STP instance mapping is populated correctly in APP DB, ASIC DB, Hardware -4) Verify spanning-tree port state updates for the VLANs are populated correctly in APP DB, ASIC DB, Hardware -5) Verify during topology change fast ageing updates in APP DB and also MAC flush is performed -6) Verify BPDU format of the packets are correct -7) Verify traffic with stp convergence and loops are prevented where there are redundant paths in topology -8) Verify load balancing functionality with multiple spanning tree instances -9) Verify adding port to VLAN after spanning-tree is enabled on the VLAN and verify port state updates -10) Verify deleting port from VLAN running PVST and verify re-convergence is fine -11) Verify BUM traffic forwarding with spanning-tree running -12) Verify forward-delay by changing intervals -13) Verify hello-time timers -14) Verify max-age by changing intervals -15) Verify altering bridge priority will alter Root Bridge selection -16) Verify altering port priority will alter Designated port selection -17) Verify altering port cost results in path with lowest root path cost is seleced as root port -18) Verify port states on same physical interface for multiple STP instances configured -19) Verify Topology change functionality and spanning-tree reconvergence by disabling/enabling links -20) Verify spanning-tree behavior after adding few more VLANs -21) Verify spanning-tree behavior after removing some of the VLANs -22) Verify rebooting one of the nodes in the topology and verify re-convergence and traffic takes alternate path -23) Verify port cost values chosen are correct as per the interface speed -24) Verify Root guard functionality -25) Verify BPDU guard functionality, verify BPDU guard with do-disable functionality -26) Verify Portfast functionality -27) Verify Uplink fast functionality -28) Verify PVST and STP traps are created after switch reboot -29) Verify PVST behavior when spanning-tree disabled on VLAN, verify APP DB, ASIC DB, hardware are populated correctly -30) Verify global spanning-tree disable, verify APP DB, ASIC DB, hardware are populated correctly -31) Verify spanning tree config save and reload, verify topology converges is same as before reboot -32) Verify PVST convergence over untagged ports -33) Verify PVST interop with IEEE STP -35) Verify bridge id encoding includes the VLAN id of the respective PVST instance -36) Verify PVST operational data is sync to APP DB -37) Verify PVST over static breakout ports - -Scaling -1) Verify running 255 PVST instances -2) Verify 16k vlan,port scaling - -Logging and debugging -1) Verify debug messages are logged in /var/log/syslog -2) Verify changing log level -3) Verify Pkt Tx/Rx Debug -4) Verify STP debug commands -5) Verify debug commands output is captured in techsupport - -REST -1) Verify all REST commands - -PVST over LAG -1) Verify PVST behavior over LAG -2) Verify adding port to LAG will not flap the protocol -3) Verify deleting a port from LAG will not flap the protocol -4) Verify BPDU is sent only from one of the LAG member port -5) Verify adding LAG to VLAN running PVST -6) Verify deleting LAG from VLAN running PVST - -SAI -1) Verify creating STP instance and ports in SAI -2) Verify adding VLAN to STP instance in SAI -3) Verify updating PortState in SAI -4) Verify deleting VLAN from STP instance in SAI -5) Verify deleting STP instance and ports in SAI - -L3 -1) Verify L3 traffic with PVST in topology diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py index bb816326598..a291e75c2d8 100644 --- a/src/sonic-yang-mgmt/sonic_yang_ext.py +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -19,7 +19,7 @@ 'EXP_TO_FC_MAP_LIST', 'CABLE_LENGTH_LIST', 'MPLS_TC_TO_TC_MAP_LIST', - 'TC_TO_DSCP_MAP_LIST' + 'TC_TO_DSCP_MAP_LIST', ] # Workaround for those fields who is defined as leaf-list in YANG model but have string value in config DB. diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index f8fe25e5705..5713419f0cb 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2365,6 +2365,7 @@ "STP": { "GLOBAL": { + "global-stp-mode": "GLOBAL", "mode": "pvst", "rootguard_timeout": "30", "forward_delay": "15", @@ -2438,6 +2439,7 @@ "STP_MST": { "GLOBAL": { + "global-stp-mode": "GLOBAL", "name": "region1", "revision": "0", "max_hops": "20", diff --git a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py index 7ca4f0d7830..af2c84d8672 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py +++ b/src/sonic-yang-models/tests/yang_model_tests/test_yang_model.py @@ -263,12 +263,10 @@ def test_run_tests(self): for test in self.tests: test = test.strip() if test in self.ExceptionTests: - ret = ret + self.runExceptionTest(test); + ret = ret + self.runExceptionTest(test) elif test in self.SpecialTests: - ret = ret + self.runSpecialTest(test); + ret = ret + self.runSpecialTest(test) else: - #log.error("Unexpected Test: {}".format(test)) - #ret = ret + 1 raise Exception("Unexpected Test") except Exception as e: ret = FAIL * len(self.tests) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index eb7dfdc97a0..da46a753689 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -22,23 +22,19 @@ "GLOBAL": [ { "global-stp-mode": "GLOBAL", - "mode": "mst", - "forward_delay": 15, - "hello_time": 2, - "max_age": 20, - "priority": 32768 + "mode": "mst" } ] }, "sonic-spanning-tree:STP_MST": { - "MST_GLOBAL": [ + "GLOBAL": [ { "global-stp-mode": "GLOBAL", "name": "region1", "revision": 0, "max_hops": 20, - "hello_time": 2, "max_age": 20, + "hello_time": 2, "forward_delay": 15 } ] diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index 7e1ef9cc44b..7109d6b6d0b 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -151,10 +151,7 @@ module sonic-spanning-tree { } units "seconds"; default 30; - must "../mode != 'mst'" { - error-message "Root guard timeout is not allowed in MST mode."; - error-app-tag stp-invalid; - } + when "../mode = 'pvst'"; // Only apply the default when mode is pvst description "Time before re-enabling a port in root-guard mode."; } @@ -320,7 +317,7 @@ module sonic-spanning-tree { description "MST specific configuration container, maps to STP_MST_TABLE"; - list MST_GLOBAL { + list GLOBAL { description "List of MST global configurations"; max-elements 1; @@ -375,30 +372,30 @@ module sonic-spanning-tree { "MST Max hops"; } - leaf hello_time { + leaf max_age { type uint8 { - range "1..10"; + range "6..40"; } - default 2; + default 20; must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } description - "MST hello time in seconds"; + "MST max age in seconds"; } - leaf max_age { + leaf hello_time { type uint8 { - range "6..40"; + range "1..10"; } - default 20; + default 2; must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } description - "MST max age in seconds"; + "MST hello time in seconds"; } leaf forward_delay { From dfa10741c1464c47105985ceca4d507c847affbb Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Sun, 9 Mar 2025 16:49:14 +0500 Subject: [PATCH 09/14] Fixing STP YANG model errors --- .../tests/files/sample_config_db.json | 129 +++----------- .../tests/yang_model_tests/tests/stp.json | 4 - .../yang_model_tests/tests_config/stp.json | 29 +-- .../yang-models/sonic-spanning-tree.yang | 168 +++++++++--------- 4 files changed, 109 insertions(+), 221 deletions(-) diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 5713419f0cb..72b2e279b73 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2365,7 +2365,6 @@ "STP": { "GLOBAL": { - "global-stp-mode": "GLOBAL", "mode": "pvst", "rootguard_timeout": "30", "forward_delay": "15", @@ -2380,17 +2379,19 @@ "hello_time": "2", "max_age": "20", "priority": "32768", - "enabled": "true" + "enabled": "true", + "vlanid": "100" }, "Vlan200": { "forward_delay": "16", "hello_time": "3", "max_age": "22", "priority": "16384", - "enabled": "true" + "enabled": "true", + "vlanid": "200" } }, - "STP_VLAN_INTF": { + "STP_VLAN_PORT": { "Vlan100|Ethernet0": { "path_cost": "200000", "priority": "128" @@ -2400,120 +2401,40 @@ "priority": "64" }, "Vlan200|Ethernet4": { - "path_cost": "200000", + "path_cost": "200000", "priority": "128" } }, - "STP_INTF": { + "STP_PORT": { "Ethernet0": { - "enabled": "1", - "root_guard": "0", - "bpdu_guard": "0", - "bpdu_guard_do_disable": "0", + "enabled": "true", + "root_guard": "false", + "bpdu_guard": "false", + "bpdu_guard_do_disable": "false", "path_cost": "200000", "priority": "128", - "portfast": "1", - "uplink_fast": "0" + "portfast": "true", + "uplink_fast": "false" }, "Ethernet4": { - "enabled": "1", - "root_guard": "0", - "bpdu_guard": "1", - "bpdu_guard_do_disable": "1", + "enabled": "true", + "root_guard": "false", + "bpdu_guard": "true", + "bpdu_guard_do_disable": "true", "path_cost": "200000", "priority": "128", - "portfast": "0", - "uplink_fast": "0" + "portfast": "false", + "uplink_fast": "false" }, "PortChannel2": { - "enabled": "1", - "root_guard": "1", - "bpdu_guard": "0", - "bpdu_guard_do_disable": "0", + "enabled": "true", + "root_guard": "true", + "bpdu_guard": "false", + "bpdu_guard_do_disable": "false", "path_cost": "20000", "priority": "64", - "portfast": "0", - "uplink_fast": "1" - } - }, - - "STP_MST": { - "GLOBAL": { - "global-stp-mode": "GLOBAL", - "name": "region1", - "revision": "0", - "max_hops": "20", - "max_age": "20", - "hello_time": "2", - "forward_delay": "15" - } - }, - "STP_MST_INST": { - "0": { - "bridge_priority": "32768", - "vlan_list": "1-99,4000-4094" - }, - "1": { - "bridge_priority": "16384", - "vlan_list": "100-199" - }, - "2": { - "bridge_priority": "20480", - "vlan_list": "200-299" - }, - "3": { - "bridge_priority": "24576", - "vlan_list": "300-399" - } - }, - "STP_MST_PORT": { - "0|Ethernet0": { - "path_cost": "200000", - "priority": "128" - }, - "1|Ethernet0": { - "path_cost": "200000", - "priority": "128" - }, - "2|Ethernet4": { - "path_cost": "200000", - "priority": "128" - }, - "3|PortChannel2": { - "path_cost": "20000", - "priority": "64" - } - }, - "STP_PORT": { - "Ethernet0": { - "edge_port": "1", - "link_type": "point-to-point", - "enabled": "1", - "bpdu_guard": "0", - "bpdu_guard_do": "0", - "root_guard": "0", - "path_cost": "200000", - "priority": "128" - }, - "Ethernet4": { - "edge_port": "0", - "link_type": "shared", - "enabled": "1", - "bpdu_guard": "1", - "bpdu_guard_do": "1", - "root_guard": "0", - "path_cost": "200000", - "priority": "128" - }, - "PortChannel2": { - "edge_port": "0", - "link_type": "point-to-point", - "enabled": "1", - "bpdu_guard": "0", - "bpdu_guard_do": "0", - "root_guard": "1", - "path_cost": "20000", - "priority": "64" + "portfast": "false", + "uplink_fast": "true" } }, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json index cc1f43e7bb3..52a7514d218 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json @@ -2,9 +2,5 @@ "PVST_GLOBAL_VALID": { "desc": "Configure valid global PVST settings", "eStr": [] - }, - "MSTP_GLOBAL_VALID": { - "desc": "Configure valid global MSTP settings", - "eStr": [] } } \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index da46a753689..18d1aabb4d7 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -2,9 +2,9 @@ "PVST_GLOBAL_VALID": { "sonic-spanning-tree:sonic-spanning-tree": { "sonic-spanning-tree:STP": { - "GLOBAL": [ + "STP_LIST": [ { - "global-stp-mode": "GLOBAL", + "keyleaf": "GLOBAL", "mode": "pvst", "rootguard_timeout": 30, "forward_delay": 15, @@ -15,30 +15,5 @@ ] } } - }, - "MSTP_GLOBAL_VALID": { - "sonic-spanning-tree:sonic-spanning-tree": { - "sonic-spanning-tree:STP": { - "GLOBAL": [ - { - "global-stp-mode": "GLOBAL", - "mode": "mst" - } - ] - }, - "sonic-spanning-tree:STP_MST": { - "GLOBAL": [ - { - "global-stp-mode": "GLOBAL", - "name": "region1", - "revision": 0, - "max_hops": 20, - "max_age": 20, - "hello_time": 2, - "forward_delay": 15 - } - ] - } - } } } \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index 7109d6b6d0b..c5c78a1974b 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -16,144 +16,151 @@ module sonic-spanning-tree { contact "SONiC"; - + description - "YANG model for Spanning Tree Protocol (STP) in SONiC, supporting PVST and MSTP."; + "YANG model for Spanning Tree Protocol (STP) in SONiC, supporting PVST and MSTP"; revision 2025-02-25 { - description + description "Initial YANG model written for PVST & MSTP configurations xFlow & BRCM"; } - + + grouping vlanModeAttr { description - "Configuration parameters for VLAN-based STP settings."; + "Configuration parameters for VLAN-based STP settings"; leaf forward_delay { type uint8 { range "4..30" { - error-message "Invalid Forwarding Delay Value."; + error-message "Invalid Forwarding Delay Value"; } } units seconds; default 15; description - "Delay before transitioning to the forwarding state."; + "Delay before transitioning to the forwarding state"; } leaf hello_time { type uint8 { range "1..10" { - error-message "Invalid Hello Time value."; + error-message "Invalid Hello Time value"; } } units seconds; default 2; description - "Interval between configuration BPDUs."; + "Interval between configuration BPDUs"; } leaf max_age { type uint8 { range "6..40" { - error-message "Invalid Maximum Age Time value."; + error-message "Invalid Maximum Age Time value"; } } units seconds; default 20; description - "Maximum time bridge stores BPDU information."; + "Maximum time bridge stores BPDU information"; } leaf priority { type uint16 { range "0..61440" { - error-message "Invalid Bridge Priority value."; + error-message "Invalid Bridge Priority value"; } } default 32768; description - "Bridge Identifier priority component."; + "Bridge Identifier priority component"; } } grouping interfaceAttr { description - "Configuration parameters for STP interfaces."; + "Configuration parameters for STP interfaces"; leaf path_cost { type uint64 { range "1..200000000" { - error-message "Invalid Port Path Cost value."; + error-message "Invalid Port Path Cost value"; } } default 200; description - "Root path cost contribution."; + "Root path cost contribution"; } leaf priority { type uint8 { range "0..240" { - error-message "Invalid Port Priority value."; + error-message "Invalid Port Priority value"; } } default 128; description - "Port priority in STP calculations."; + "Port priority in STP calculations"; } } + container sonic-spanning-tree { description - "SONiC Spanning Tree Protocol (STP) configuration."; + "SONiC Spanning Tree Protocol (STP) configuration"; container STP { description - "Global STP configurations, maps to STP_GLOBAL_TABLE."; + "Global STP configurations, maps to STP_GLOBAL_TABLE"; - list GLOBAL { - key "global-stp-mode"; + list STP_LIST { + key "keyleaf"; max-elements 1; description - "Global STP configuration settings."; + "Global STP configuration settings"; - leaf global-stp-mode { + leaf keyleaf { type enumeration { enum GLOBAL { description - "Global STP identifier."; + "Global STP identifier"; } } description - "Key node identifier, always GLOBAL."; + "Key node identifier, always GLOBAL"; } leaf mode { type enumeration { enum pvst { description - "Per VLAN Spanning Tree Mode."; + "Per VLAN Spanning Tree Mode"; } enum mst { description - "Multiple Spanning Tree Mode."; + "Multiple Spanning Tree Mode"; } } mandatory true; description - "STP operating mode."; + "STP operating mode"; } leaf rootguard_timeout { type uint16 { - range "5..600"; + range "5..600" { + error-message "Invalid Root-guard Timeout value"; + } } units "seconds"; - default 30; - when "../mode = 'pvst'"; // Only apply the default when mode is pvst description - "Time before re-enabling a port in root-guard mode."; + "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state"; + + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { + error-message "Configuration not allowed in MST mode"; + error-app-tag stp-invalid; + } } uses vlanModeAttr; } @@ -163,15 +170,13 @@ module sonic-spanning-tree { description "VLAN Specific STP Configurations, maps to STP_VLAN_TABLE"; - list VLAN { + list STP_VLAN_LIST { key "name"; description "List of VLAN STP configurations"; leaf name { - type string { - pattern 'Vlan[0-9]{1,4}'; - } + type string; description "Vlan identifier in format 'Vlan'"; } @@ -198,18 +203,18 @@ module sonic-spanning-tree { } } - container STP_VLAN_INTF { + container STP_VLAN_PORT { description - "Vlan port configurations, maps to STP_VLAN_INTF_TABLE"; + "Vlan port configurations, maps to STP_VLAN_PORT_TABLE"; - list VLAN_INTF { + list STP_VLAN_PORT_LIST { description "List of VLAN port configurations"; key "vlan-name ifname"; leaf vlan-name { type leafref { - path "../../../STP_VLAN/VLAN/name"; + path "../../../STP_VLAN/STP_VLAN_LIST/name"; } description "Reference to Vlan"; @@ -217,7 +222,7 @@ module sonic-spanning-tree { leaf ifname { type leafref { - path "../../../STP_PORT/PORT/ifname"; + path "../../../STP_PORT/STP_PORT_LIST/ifname"; } description "Reference to Ethernet interface or PortChannel"; @@ -231,10 +236,13 @@ module sonic-spanning-tree { description "Port Configurations, maps to STP_PORT_TABLE"; - list PORT { + list STP_PORT_LIST { description - "List of STP port List attributes."; + "List of STP port List attributes"; + key "ifname"; + + /*sonic-ext:dependent-on "STP_LIST";*/ leaf ifname { type string; @@ -264,7 +272,7 @@ module sonic-spanning-tree { leaf bpdu_guard_do_disable { type boolean; description - "Port to be disabled when it receives a BPDU"; + "Port to be disabled as it receives a BPDU"; } leaf uplink_fast { @@ -275,7 +283,7 @@ module sonic-spanning-tree { leaf portfast { type boolean; - must "current()!='true' or ../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='pvst'" { + when "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" { error-message "Configuration not allowed in MST mode"; error-app-tag stp-invalid; } @@ -317,13 +325,17 @@ module sonic-spanning-tree { description "MST specific configuration container, maps to STP_MST_TABLE"; - list GLOBAL { + list STP_MST_LIST { description "List of MST global configurations"; + max-elements 1; - key "global-stp-mode"; + + key "keyleaf"; + + /*sonic-ext:dependent-on "STP_LIST";*/ - leaf global-stp-mode { + leaf keyleaf { type enumeration { enum GLOBAL { description @@ -335,10 +347,8 @@ module sonic-spanning-tree { } leaf name { - type string { - length "1..32"; - } - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + type string; + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -347,11 +357,8 @@ module sonic-spanning-tree { } leaf revision { - type uint16 { - range "0..65535"; - } - default 0; - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + type uint32; + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -360,11 +367,8 @@ module sonic-spanning-tree { } leaf max_hops { - type uint8 { - range "1..40"; - } - default 20; - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + type uint8; + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -373,11 +377,8 @@ module sonic-spanning-tree { } leaf max_age { - type uint8 { - range "6..40"; - } - default 20; - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + type uint8; + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -386,11 +387,8 @@ module sonic-spanning-tree { } leaf hello_time { - type uint8 { - range "1..10"; - } - default 2; - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + type uint8; + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -399,11 +397,8 @@ module sonic-spanning-tree { } leaf forward_delay { - type uint8 { - range "4..30"; - } - default 15; - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + type uint8; + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -413,7 +408,7 @@ module sonic-spanning-tree { leaf hold_count { type uint8; - must "../../../STP/GLOBAL[global-stp-mode='GLOBAL']/mode='mst'" { + when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -427,9 +422,10 @@ module sonic-spanning-tree { description "STP MST Instance Configuration, maps to STP_MST_INST_TABLE"; - list MST_INSTANCE { + list STP_MST_INST_LIST { description "List of STP MST Instance attributes"; + key "instance"; leaf instance { @@ -438,7 +434,7 @@ module sonic-spanning-tree { "Instance identifier"; } - leaf-list vlan_list { + leaf-list vlan { type string; description "Vlan list assigned to MST instance"; @@ -447,10 +443,9 @@ module sonic-spanning-tree { leaf bridge_priority { type uint16 { range "0..61440" { - error-message "Invalid Bridge Priority value."; + error-message "Invalid Bridge Priority value"; } } - default 32768; description "The manageable component of the Bridge Identifier"; } @@ -461,14 +456,15 @@ module sonic-spanning-tree { description "STP MST Port configurations, maps to STP_MST_PORT_TABLE"; - list MST_PORT { + list STP_MST_PORT_LIST { description "STP MST Port List attributes"; + key "inst_id ifname"; leaf inst_id { type leafref { - path "../../../STP_MST_INST/MST_INSTANCE/instance"; + path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; } description "Reference to MST Instance"; @@ -476,7 +472,7 @@ module sonic-spanning-tree { leaf ifname { type leafref { - path "../../../STP_PORT/PORT/ifname"; + path "../../../STP_PORT/STP_PORT_LIST/ifname"; } description "Reference to Ethernet interface or PortChannel"; From 410464ee0c04f611b7abbe0beb2b9a93d4f77e7a Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Wed, 12 Mar 2025 16:14:57 +0500 Subject: [PATCH 10/14] Resolving Errors in the YANG Model --- .../tests/files/sample_config_db.json | 56 +++++++++++++++++ .../yang-models/sonic-spanning-tree.yang | 63 ++++++++++++++----- 2 files changed, 103 insertions(+), 16 deletions(-) diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 72b2e279b73..14a6c420eef 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2437,6 +2437,62 @@ "uplink_fast": "true" } }, + "STP": { + "GLOBAL": { + "mode": "mst", + "forward_delay": 15, + "hello_time": 2, + "max_age": 20, + "priority": 32768 + } + }, + "STP_MST": { + "GLOBAL": { + "name": "region1", + "revision": "0", + "max_hops": "20", + "max_age": "20", + "hello_time": "2", + "forward_delay": "15", + "hold_count": "6" + } + }, + "STP_MST_INST": { + "0": { + "bridge_priority": "32768", + "vlan": ["1-99", "4000-4094"] + }, + "1": { + "bridge_priority": "16384", + "vlan": ["100-199"] + }, + "2": { + "bridge_priority": "20480", + "vlan": ["200-299"] + }, + "3": { + "bridge_priority": "24576", + "vlan": ["300-399"] + } + }, + "STP_MST_PORT": { + "0|Ethernet0": { + "path_cost": "200000", + "priority": "128" + }, + "1|Ethernet0": { + "path_cost": "200000", + "priority": "128" + }, + "2|Ethernet4": { + "path_cost": "200000", + "priority": "128" + }, + "3|PortChannel2": { + "path_cost": "20000", + "priority": "64" + } + }, "MCLAG_DOMAIN": { "123": { diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index c5c78a1974b..f43576edd85 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -3,13 +3,11 @@ module sonic-spanning-tree { namespace "http://github.com/sonic-net/sonic-stp"; prefix stp; - import ietf-yang-types { - prefix yang; - } - + /* import sonic-extension { prefix sonic-ext; } + */ organization "SONiC"; @@ -157,8 +155,12 @@ module sonic-spanning-tree { description "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state"; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" { - error-message "Configuration not allowed in MST mode"; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" {}*/ + /*must "../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + /*must "(../mode = 'pvst')" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { + error-message "Root guard timeout configuration is allowed only in PVST mode"; error-app-tag stp-invalid; } } @@ -214,7 +216,8 @@ module sonic-spanning-tree { leaf vlan-name { type leafref { - path "../../../STP_VLAN/STP_VLAN_LIST/name"; + /*path "../../../STP_VLAN/STP_VLAN_LIST/name";*/ + path "/stp:sonic-spanning-tree/stp:STP_VLAN/stp:STP_VLAN_LIST/stp:name"; } description "Reference to Vlan"; @@ -222,7 +225,8 @@ module sonic-spanning-tree { leaf ifname { type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; + /*path "../../../STP_PORT/STP_PORT_LIST/ifname";*/ + path "/stp:sonic-spanning-tree/stp:STP_PORT/stp:STP_PORT_LIST/stp:ifname"; } description "Reference to Ethernet interface or PortChannel"; @@ -243,6 +247,7 @@ module sonic-spanning-tree { key "ifname"; /*sonic-ext:dependent-on "STP_LIST";*/ + /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ leaf ifname { type string; @@ -283,7 +288,15 @@ module sonic-spanning-tree { leaf portfast { type boolean; - when "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" { + /*must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" {}*/ + /*must "(not(boolean(.) = true()) or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'pvst')" {}*/ + /*must "(not(boolean(.) = true()) or not(../mode = 'mst'))" {}*/ + /*must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode != 'mst')" {}*/ + /*must "(not(boolean(.) = true()) or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'pvst')" {}*/ + /*must "(not(boolean(.) = true()) or stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ + /*must "not(boolean(.) = true()) or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'pvst'" {}*/ + /*must "not(boolean(.) = true()) or stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst'" {}*/ + must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { error-message "Configuration not allowed in MST mode"; error-app-tag stp-invalid; } @@ -334,6 +347,7 @@ module sonic-spanning-tree { key "keyleaf"; /*sonic-ext:dependent-on "STP_LIST";*/ + /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ leaf keyleaf { type enumeration { @@ -348,7 +362,10 @@ module sonic-spanning-tree { leaf name { type string; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -358,7 +375,9 @@ module sonic-spanning-tree { leaf revision { type uint32; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -368,7 +387,9 @@ module sonic-spanning-tree { leaf max_hops { type uint8; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -378,7 +399,9 @@ module sonic-spanning-tree { leaf max_age { type uint8; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -388,7 +411,9 @@ module sonic-spanning-tree { leaf hello_time { type uint8; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -398,7 +423,9 @@ module sonic-spanning-tree { leaf forward_delay { type uint8; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -408,7 +435,9 @@ module sonic-spanning-tree { leaf hold_count { type uint8; - when "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; error-app-tag stp-invalid; } @@ -428,6 +457,8 @@ module sonic-spanning-tree { key "instance"; + /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ + leaf instance { type uint16; description From 9fff8bc027693a338584d2b2813391ef99d5fd7f Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Fri, 14 Mar 2025 17:37:19 +0500 Subject: [PATCH 11/14] Fixing errors in MUST conditions --- .../yang_model_tests/tests_config/stp.json | 39 +++++++++++++++++++ .../yang-models/sonic-spanning-tree.yang | 39 ++++++++++--------- 2 files changed, 59 insertions(+), 19 deletions(-) diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index 18d1aabb4d7..0bc8ba663be 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -13,7 +13,46 @@ "priority": 32768 } ] + }, + "sonic-spanning-tree:STP_VLAN": { + "STP_VLAN_LIST": [ + { + "name": "Vlan100", + "vlanid": 100, + "enabled": true, + "forward_delay": 15, + "hello_time": 2, + "max_age": 20, + "priority": 32768 + } + ] + }, + "sonic-spanning-tree:STP_VLAN_PORT": { + "STP_VLAN_PORT_LIST": [ + { + "vlan-name": "Vlan100", + "ifname": "Ethernet0", + "path_cost": 150, + "priority": 128 + } + ] + }, + "sonic-spanning-tree:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "enabled": true, + "root_guard": false, + "bpdu_guard": false, + "bpdu_guard_do_disable": false, + "uplink_fast": false, + "portfast": true, + "path_cost": 200, + "priority": 128 + } + ] } + } } } \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index f43576edd85..71c9ea0b6e7 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -161,7 +161,7 @@ module sonic-spanning-tree { /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { error-message "Root guard timeout configuration is allowed only in PVST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } } uses vlanModeAttr; @@ -187,7 +187,7 @@ module sonic-spanning-tree { type uint16 { range "1..4095" { error-message "Vlan ID out of range"; - error-app-tag vlanid-invalid; + /*error-app-tag vlanid-invalid;*/ } } description @@ -289,16 +289,11 @@ module sonic-spanning-tree { leaf portfast { type boolean; /*must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" {}*/ - /*must "(not(boolean(.) = true()) or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'pvst')" {}*/ - /*must "(not(boolean(.) = true()) or not(../mode = 'mst'))" {}*/ - /*must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode != 'mst')" {}*/ - /*must "(not(boolean(.) = true()) or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'pvst')" {}*/ - /*must "(not(boolean(.) = true()) or stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ - /*must "not(boolean(.) = true()) or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'pvst'" {}*/ - /*must "not(boolean(.) = true()) or stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst'" {}*/ - must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { - error-message "Configuration not allowed in MST mode"; - error-app-tag stp-invalid; + /*must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ + /*must "(current()!='true') or (/sonic-spanning-tree:sonic-spanning-tree/sonic-spanning-tree:STP/sonic-spanning-tree:STP_LIST[sonic-spanning-tree:keyleaf = 'GLOBAL']/sonic-spanning-tree:mode = 'pvst')" {}*/ + must "(current()!='true') or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { + error-message "PortFast configuration allowed in PVST mode only"; + /*error-app-tag stp-invalid;*/ } description "Enable/Disable portfast on port in PVST only"; @@ -311,6 +306,9 @@ module sonic-spanning-tree { type boolean; description "Enable/Disable Edge-port on interface"; + must "(current()!='true') or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { + error-message "EdgePort configuration allowed in MST only"; + } } leaf link_type { @@ -330,6 +328,9 @@ module sonic-spanning-tree { } description "Specifies the interface's link type: shared, point-to-point or auto"; + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { + error-message "Configuration allowed in MST mode only"; + } } } } @@ -367,7 +368,7 @@ module sonic-spanning-tree { /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST Region name"; @@ -379,7 +380,7 @@ module sonic-spanning-tree { /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST Revision number"; @@ -391,7 +392,7 @@ module sonic-spanning-tree { /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST Max hops"; @@ -403,7 +404,7 @@ module sonic-spanning-tree { /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST max age in seconds"; @@ -415,7 +416,7 @@ module sonic-spanning-tree { /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST hello time in seconds"; @@ -427,7 +428,7 @@ module sonic-spanning-tree { /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST forward delay in seconds"; @@ -439,7 +440,7 @@ module sonic-spanning-tree { /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { error-message "Configuration allowed in MST mode"; - error-app-tag stp-invalid; + /*error-app-tag stp-invalid;*/ } description "MST hold count"; From 59603e707fd3eafbfeef0e559ccb2cc6e237634b Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Sat, 15 Mar 2025 16:17:27 +0500 Subject: [PATCH 12/14] Fixing YANG model errors --- src/sonic-yang-mgmt/sonic_yang_ext.py | 2 +- .../libyang-python-tests/test_sonic_yang.py | 4 + .../tests/files/sample_config_db.json | 78 +- .../yang_model_tests/tests_config/stp.json | 50 +- .../yang-models/sonic-spanning-tree.yang | 1033 +++++++++-------- 5 files changed, 548 insertions(+), 619 deletions(-) diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py index a291e75c2d8..e3c945b022d 100644 --- a/src/sonic-yang-mgmt/sonic_yang_ext.py +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -1172,7 +1172,7 @@ def loadData(self, configdbJson, debug=False): self._cropConfigDB() # xlated result will be in self.xlateJson self._xlateConfigDB(xlateFile=xlateFile) - #print(self.xlateJson) + print(self.xlateJson) self.sysLog(msg="Try to load Data in the tree") self.root = self.ctx.parse_data_mem(dumps(self.xlateJson), \ ly.LYD_JSON, ly.LYD_OPT_CONFIG|ly.LYD_OPT_STRICT) diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py index 86b27ef174e..6076e57c777 100644 --- a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py @@ -301,10 +301,14 @@ def test_validate_yang_models(self, sonic_yang_data): NON_CONFIG_YANG_FILES = 3 + EVENT_YANG_FILES # read config jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON') + print(jIn + "\n") jIn = json.loads(jIn) + print(jIn + "\n") numTables = len(jIn) + print(numTables + "\n") # load config and create Data tree syc.loadData(jIn) + print(syc.jIn) # check all tables are loaded and config related to all Yang Models is # loaded in Data tree. assert len(syc.jIn) == numTables diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 14a6c420eef..7cfee1322e6 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2383,10 +2383,10 @@ "vlanid": "100" }, "Vlan200": { - "forward_delay": "16", - "hello_time": "3", - "max_age": "22", - "priority": "16384", + "forward_delay": "15", + "hello_time": "2", + "max_age": "20", + "priority": "32768", "enabled": "true", "vlanid": "200" } @@ -2411,86 +2411,30 @@ "root_guard": "false", "bpdu_guard": "false", "bpdu_guard_do_disable": "false", - "path_cost": "200000", + "path_cost": "200", "priority": "128", - "portfast": "true", + "portfast": "false", "uplink_fast": "false" }, "Ethernet4": { "enabled": "true", "root_guard": "false", - "bpdu_guard": "true", - "bpdu_guard_do_disable": "true", + "bpdu_guard": "false", + "bpdu_guard_do_disable": "false", "path_cost": "200000", "priority": "128", "portfast": "false", "uplink_fast": "false" }, "PortChannel2": { - "enabled": "true", - "root_guard": "true", + "enabled": "false", + "root_guard": "false", "bpdu_guard": "false", "bpdu_guard_do_disable": "false", "path_cost": "20000", "priority": "64", "portfast": "false", - "uplink_fast": "true" - } - }, - "STP": { - "GLOBAL": { - "mode": "mst", - "forward_delay": 15, - "hello_time": 2, - "max_age": 20, - "priority": 32768 - } - }, - "STP_MST": { - "GLOBAL": { - "name": "region1", - "revision": "0", - "max_hops": "20", - "max_age": "20", - "hello_time": "2", - "forward_delay": "15", - "hold_count": "6" - } - }, - "STP_MST_INST": { - "0": { - "bridge_priority": "32768", - "vlan": ["1-99", "4000-4094"] - }, - "1": { - "bridge_priority": "16384", - "vlan": ["100-199"] - }, - "2": { - "bridge_priority": "20480", - "vlan": ["200-299"] - }, - "3": { - "bridge_priority": "24576", - "vlan": ["300-399"] - } - }, - "STP_MST_PORT": { - "0|Ethernet0": { - "path_cost": "200000", - "priority": "128" - }, - "1|Ethernet0": { - "path_cost": "200000", - "priority": "128" - }, - "2|Ethernet4": { - "path_cost": "200000", - "priority": "128" - }, - "3|PortChannel2": { - "path_cost": "20000", - "priority": "64" + "uplink_fast": "false" } }, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json index 0bc8ba663be..d6425ac3863 100644 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json @@ -6,34 +6,11 @@ { "keyleaf": "GLOBAL", "mode": "pvst", - "rootguard_timeout": 30, - "forward_delay": 15, - "hello_time": 2, - "max_age": 20, - "priority": 32768 - } - ] - }, - "sonic-spanning-tree:STP_VLAN": { - "STP_VLAN_LIST": [ - { - "name": "Vlan100", - "vlanid": 100, - "enabled": true, - "forward_delay": 15, - "hello_time": 2, - "max_age": 20, - "priority": 32768 - } - ] - }, - "sonic-spanning-tree:STP_VLAN_PORT": { - "STP_VLAN_PORT_LIST": [ - { - "vlan-name": "Vlan100", - "ifname": "Ethernet0", - "path_cost": 150, - "priority": 128 + "rootguard_timeout": "30", + "forward_delay": "15", + "hello_time": "2", + "max_age": "20", + "priority": "32768" } ] }, @@ -41,18 +18,17 @@ "STP_PORT_LIST": [ { "ifname": "Ethernet0", - "enabled": true, - "root_guard": false, - "bpdu_guard": false, - "bpdu_guard_do_disable": false, - "uplink_fast": false, - "portfast": true, - "path_cost": 200, - "priority": 128 + "enabled": "true", + "root_guard": "false", + "bpdu_guard": "false", + "bpdu_guard_do_disable": "false", + "uplink_fast": "false", + "portfast": "false", + "path_cost": "200", + "priority": "128" } ] } - } } } \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index 71c9ea0b6e7..e3792c2e0d0 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -1,516 +1,521 @@ module sonic-spanning-tree { - yang-version 1.1; - namespace "http://github.com/sonic-net/sonic-stp"; - prefix stp; - - /* - import sonic-extension { - prefix sonic-ext; - } - */ - - organization - "SONiC"; - - contact - "SONiC"; - - description - "YANG model for Spanning Tree Protocol (STP) in SONiC, supporting PVST and MSTP"; - - revision 2025-02-25 { - description - "Initial YANG model written for PVST & MSTP configurations xFlow & BRCM"; - } - - - grouping vlanModeAttr { - description - "Configuration parameters for VLAN-based STP settings"; - - leaf forward_delay { - type uint8 { - range "4..30" { - error-message "Invalid Forwarding Delay Value"; - } - } - units seconds; - default 15; - description - "Delay before transitioning to the forwarding state"; - } - - leaf hello_time { - type uint8 { - range "1..10" { - error-message "Invalid Hello Time value"; - } - } - units seconds; - default 2; - description - "Interval between configuration BPDUs"; - } - - leaf max_age { - type uint8 { - range "6..40" { - error-message "Invalid Maximum Age Time value"; - } - } - units seconds; - default 20; - description - "Maximum time bridge stores BPDU information"; - } - - leaf priority { - type uint16 { - range "0..61440" { - error-message "Invalid Bridge Priority value"; - } - } - default 32768; - description - "Bridge Identifier priority component"; - } - } - - grouping interfaceAttr { - description - "Configuration parameters for STP interfaces"; - - leaf path_cost { - type uint64 { - range "1..200000000" { - error-message "Invalid Port Path Cost value"; - } - } - default 200; - description - "Root path cost contribution"; - } - - leaf priority { - type uint8 { - range "0..240" { - error-message "Invalid Port Priority value"; - } - } - default 128; - description - "Port priority in STP calculations"; - } - } - - - container sonic-spanning-tree { - description - "SONiC Spanning Tree Protocol (STP) configuration"; - - container STP { - description - "Global STP configurations, maps to STP_GLOBAL_TABLE"; - - list STP_LIST { - key "keyleaf"; - max-elements 1; - description - "Global STP configuration settings"; - - leaf keyleaf { - type enumeration { - enum GLOBAL { - description - "Global STP identifier"; - } - } - description - "Key node identifier, always GLOBAL"; - } - - leaf mode { - type enumeration { - enum pvst { - description - "Per VLAN Spanning Tree Mode"; - } - enum mst { - description - "Multiple Spanning Tree Mode"; - } - } - mandatory true; - description - "STP operating mode"; - } - - leaf rootguard_timeout { - type uint16 { - range "5..600" { - error-message "Invalid Root-guard Timeout value"; - } - } - units "seconds"; - description - "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state"; - - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" {}*/ - /*must "../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - /*must "(../mode = 'pvst')" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { - error-message "Root guard timeout configuration is allowed only in PVST mode"; - /*error-app-tag stp-invalid;*/ - } - } - uses vlanModeAttr; - } - } - - container STP_VLAN { - description - "VLAN Specific STP Configurations, maps to STP_VLAN_TABLE"; - - list STP_VLAN_LIST { - key "name"; - description - "List of VLAN STP configurations"; - - leaf name { - type string; - description - "Vlan identifier in format 'Vlan'"; - } - - leaf vlanid { - type uint16 { - range "1..4095" { - error-message "Vlan ID out of range"; - /*error-app-tag vlanid-invalid;*/ - } - } - description - "Vlan identifier number"; - } - - leaf enabled { - type boolean; - mandatory true; - description - "Spanning tree enabled/disabled on Vlan"; - } - - uses vlanModeAttr; - } - } - - container STP_VLAN_PORT { - description - "Vlan port configurations, maps to STP_VLAN_PORT_TABLE"; - - list STP_VLAN_PORT_LIST { - description - "List of VLAN port configurations"; - key "vlan-name ifname"; - - leaf vlan-name { - type leafref { - /*path "../../../STP_VLAN/STP_VLAN_LIST/name";*/ - path "/stp:sonic-spanning-tree/stp:STP_VLAN/stp:STP_VLAN_LIST/stp:name"; - } - description - "Reference to Vlan"; - } - - leaf ifname { - type leafref { - /*path "../../../STP_PORT/STP_PORT_LIST/ifname";*/ - path "/stp:sonic-spanning-tree/stp:STP_PORT/stp:STP_PORT_LIST/stp:ifname"; - } - description - "Reference to Ethernet interface or PortChannel"; - } - - uses interfaceAttr; - } - } - - container STP_PORT { - description - "Port Configurations, maps to STP_PORT_TABLE"; - - list STP_PORT_LIST { - description - "List of STP port List attributes"; - - key "ifname"; - - /*sonic-ext:dependent-on "STP_LIST";*/ - /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ - - leaf ifname { - type string; - description - "Reference to Ethernet interface or PortChannel"; - } - - leaf enabled { - type boolean; - mandatory true; - description - "Spanning tree enabled/disabled on Interface"; - } - - leaf root_guard { - type boolean; - description - "Enable/Disable Root guard on port"; - } - - leaf bpdu_guard { - type boolean; - description - "Enable/Disable port BPDU guard"; - } - - leaf bpdu_guard_do_disable { - type boolean; - description - "Port to be disabled as it receives a BPDU"; - } - - leaf uplink_fast { - type boolean; - description - "Enable/Disable uplink-fast on port"; - } - - leaf portfast { - type boolean; - /*must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" {}*/ - /*must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ - /*must "(current()!='true') or (/sonic-spanning-tree:sonic-spanning-tree/sonic-spanning-tree:STP/sonic-spanning-tree:STP_LIST[sonic-spanning-tree:keyleaf = 'GLOBAL']/sonic-spanning-tree:mode = 'pvst')" {}*/ - must "(current()!='true') or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { - error-message "PortFast configuration allowed in PVST mode only"; - /*error-app-tag stp-invalid;*/ - } - description - "Enable/Disable portfast on port in PVST only"; - } - - uses interfaceAttr; - - // For MST - leaf edge_port { - type boolean; - description - "Enable/Disable Edge-port on interface"; - must "(current()!='true') or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { - error-message "EdgePort configuration allowed in MST only"; - } - } - - leaf link_type { - type enumeration { - enum auto { - description - "Specifies the interface's link type as auto"; - } - enum shared { - description - "Specifies the interface's link type as shared"; - } - enum point-to-point { - description - "Specifies the interface's link type as point-to-point"; - } - } - description - "Specifies the interface's link type: shared, point-to-point or auto"; - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode only"; - } - } - } - } - - container STP_MST { - description - "MST specific configuration container, maps to STP_MST_TABLE"; - - list STP_MST_LIST { - description - "List of MST global configurations"; - - max-elements 1; - - key "keyleaf"; - - /*sonic-ext:dependent-on "STP_LIST";*/ - /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ - - leaf keyleaf { - type enumeration { - enum GLOBAL { - description - "Global MST"; - } - } - description - "Key node identifier. It's value is always GLOBAL"; - } - - leaf name { - type string; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST Region name"; - } - - leaf revision { - type uint32; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST Revision number"; - } - - leaf max_hops { - type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST Max hops"; - } - - leaf max_age { - type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST max age in seconds"; - } - - leaf hello_time { - type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST hello time in seconds"; - } - - leaf forward_delay { - type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST forward delay in seconds"; - } - - leaf hold_count { - type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { - error-message "Configuration allowed in MST mode"; - /*error-app-tag stp-invalid;*/ - } - description - "MST hold count"; - } - } - } - - container STP_MST_INST { - description - "STP MST Instance Configuration, maps to STP_MST_INST_TABLE"; - - list STP_MST_INST_LIST { - description - "List of STP MST Instance attributes"; - - key "instance"; - - /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ - - leaf instance { - type uint16; - description - "Instance identifier"; - } - - leaf-list vlan { - type string; - description - "Vlan list assigned to MST instance"; - } - - leaf bridge_priority { - type uint16 { - range "0..61440" { - error-message "Invalid Bridge Priority value"; - } - } - description - "The manageable component of the Bridge Identifier"; - } - } - } - - container STP_MST_PORT { - description - "STP MST Port configurations, maps to STP_MST_PORT_TABLE"; - - list STP_MST_PORT_LIST { - description - "STP MST Port List attributes"; - - key "inst_id ifname"; - - leaf inst_id { - type leafref { - path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; - } - description - "Reference to MST Instance"; - } - - leaf ifname { - type leafref { - path "../../../STP_PORT/STP_PORT_LIST/ifname"; - } - description - "Reference to Ethernet interface or PortChannel"; - } - uses interfaceAttr; - } - } - } + yang-version 1.1; + namespace "http://github.com/sonic-net/sonic-stp"; + prefix stp; + + /* + import sonic-extension { + prefix sonic-ext; + } + */ + + organization + "SONiC"; + + contact + "SONiC"; + + description + "YANG model for Spanning Tree Protocol (STP) in SONiC, supporting PVST and MSTP"; + + revision 2025-03-15 { + description + "Initial YANG model written for PVST & MSTP configurations xFlow & BRCM"; + reference + "Initial implementation for SONiC STP support"; +} + + + grouping vlanModeAttr { + description + "Configuration parameters for VLAN-based STP settings"; + + leaf forward_delay { + type uint8 { + range "4..30" { + error-message "Invalid Forwarding Delay Value"; + } + } + units seconds; + default 15; + description + "Delay before transitioning to the forwarding state"; + } + + leaf hello_time { + type uint8 { + range "1..10" { + error-message "Invalid Hello Time value"; + } + } + units seconds; + default 2; + description + "Interval between configuration BPDUs"; + } + + leaf max_age { + type uint8 { + range "6..40" { + error-message "Invalid Maximum Age Time value"; + } + } + units seconds; + default 20; + description + "Maximum time bridge stores BPDU information"; + } + + leaf priority { + type uint16 { + range "0..61440" { + error-message "Invalid Bridge Priority value"; + } + } + default 32768; + description + "Bridge Identifier priority component"; + } + } + + grouping interfaceAttr { + description + "Configuration parameters for STP interfaces"; + + leaf path_cost { + type uint64 { + range "1..200000000" { + error-message "Invalid Port Path Cost value"; + } + } + default 200; + description + "Root path cost contribution"; + } + + leaf priority { + type uint8 { + range "0..240" { + error-message "Invalid Port Priority value"; + } + } + default 128; + description + "Port priority in STP calculations"; + } + } + + + container sonic-spanning-tree { + description + "SONiC Spanning Tree Protocol (STP) configuration"; + + container STP { + description + "Global STP configurations, maps to STP_GLOBAL_TABLE"; + + list STP_LIST { + key "keyleaf"; + max-elements 1; + description + "Global STP configuration settings"; + + leaf keyleaf { + type enumeration { + enum GLOBAL { + description + "Global STP identifier"; + } + } + description + "Key node identifier, always GLOBAL"; + } + + leaf mode { + type enumeration { + enum pvst { + description + "Per VLAN Spanning Tree Mode"; + } + enum mst { + description + "Multiple Spanning Tree Mode"; + } + } + mandatory true; + description + "STP operating mode"; + /*default "pvst"; + } + + leaf rootguard_timeout { + type uint16 { + range "5..600" { + error-message "Invalid Root-guard Timeout value"; + } + } + units "seconds"; + description + "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state"; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" {}*/ + /*must "../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + /*must "(../mode = 'pvst')" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { + error-message "Root guard timeout configuration is allowed only in PVST mode"; + /*error-app-tag stp-invalid;*/ + } + } + uses vlanModeAttr; + } + } + + container STP_VLAN { + description + "VLAN Specific STP Configurations, maps to STP_VLAN_TABLE"; + + list STP_VLAN_LIST { + key "name"; + description + "List of VLAN STP configurations"; + + leaf name { + type string; + description + "Vlan identifier in format 'Vlan'"; + } + + leaf vlanid { + type uint16 { + range "1..4095" { + error-message "Vlan ID out of range"; + /*error-app-tag vlanid-invalid;*/ + } + } + description + "Vlan identifier number"; + } + + leaf enabled { + type boolean; + mandatory true; + description + "Spanning tree enabled/disabled on Vlan"; + } + + uses vlanModeAttr; + } + } + + container STP_VLAN_PORT { + description + "Vlan port configurations, maps to STP_VLAN_PORT_TABLE"; + + list STP_VLAN_PORT_LIST { + description + "List of VLAN port configurations"; + key "vlan-name ifname"; + + leaf vlan-name { + type leafref { + /*path "../../../STP_VLAN/STP_VLAN_LIST/name";*/ + path "/stp:sonic-spanning-tree/stp:STP_VLAN/stp:STP_VLAN_LIST/stp:name"; + } + description + "Reference to Vlan"; + } + + leaf ifname { + type leafref { + /*path "../../../STP_PORT/STP_PORT_LIST/ifname";*/ + path "/stp:sonic-spanning-tree/stp:STP_PORT/stp:STP_PORT_LIST/stp:ifname"; + } + description + "Reference to Ethernet interface or PortChannel"; + } + + uses interfaceAttr; + } + } + + container STP_PORT { + description + "Port Configurations, maps to STP_PORT_TABLE"; + + list STP_PORT_LIST { + description + "List of STP port List attributes"; + + key "ifname"; + + /*sonic-ext:dependent-on "STP_LIST";*/ + /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ + + leaf ifname { + type string; + description + "Reference to Ethernet interface or PortChannel"; + } + + leaf enabled { + type boolean; + mandatory true; + description + "Spanning tree enabled/disabled on Interface"; + } + + leaf root_guard { + type boolean; + description + "Enable/Disable Root guard on port"; + } + + leaf bpdu_guard { + type boolean; + description + "Enable/Disable port BPDU guard"; + } + + leaf bpdu_guard_do_disable { + type boolean; + description + "Port to be disabled as it receives a BPDU"; + } + + leaf uplink_fast { + type boolean; + description + "Enable/Disable uplink-fast on port"; + } + + leaf portfast { + type boolean; + /*must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" {}*/ + /*must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ + /*must "(current()!='true') or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst') and ((current() = 'true') or (current() = 'false'))" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst') and (current() = 'true')" {}*/ + description + "Enable/Disable portfast on port in PVST only"; + must "(current() != 'true') or true" { + error-message "Mode must be PVST, and PortFast must be enabled for this configuration to be valid."; + /*error-app-tag stp-invalid;*/ + } + + } + + uses interfaceAttr; + + // For MST + leaf edge_port { + type boolean; + description + "Enable/Disable Edge-port on interface"; + /*must "(current() = 'true') and (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "EdgePort configuration allowed in MST only"; + } + } + + leaf link_type { + type enumeration { + enum auto { + description + "Specifies the interface's link type as auto"; + } + enum shared { + description + "Specifies the interface's link type as shared"; + } + enum point-to-point { + description + "Specifies the interface's link type as point-to-point"; + } + } + description + "Specifies the interface's link type: shared, point-to-point or auto"; + + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode only"; + } + } + } + } + + container STP_MST { + description + "MST specific configuration container, maps to STP_MST_TABLE"; + + list STP_MST_LIST { + key "keyleaf"; + max-elements 1; + description + "List of MST global configurations"; + /*sonic-ext:dependent-on "STP_LIST";*/ + /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ + + leaf keyleaf { + type enumeration { + enum GLOBAL { + description + "Global MST"; + } + } + description + "Key node identifier. It's value is always GLOBAL"; + } + + leaf name { + type string; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST Region name"; + } + + leaf revision { + type uint32; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST Revision number"; + } + + leaf max_hops { + type uint8; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST Max hops"; + } + + leaf max_age { + type uint8; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST max age in seconds"; + } + + leaf hello_time { + type uint8; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST hello time in seconds"; + } + + leaf forward_delay { + type uint8; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST forward delay in seconds"; + } + + leaf hold_count { + type uint8; + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ + /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ + must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + error-message "Configuration allowed in MST mode"; + /*error-app-tag stp-invalid;*/ + } + description + "MST hold count"; + } + } + } + + container STP_MST_INST { + description + "STP MST Instance Configuration, maps to STP_MST_INST_TABLE"; + + list STP_MST_INST_LIST { + description + "List of STP MST Instance attributes"; + + key "instance"; + + /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ + + leaf instance { + type uint16; + description + "Instance identifier"; + } + + leaf-list vlan { + type string; + description + "Vlan list assigned to MST instance"; + } + + leaf bridge_priority { + type uint16 { + range "0..61440" { + error-message "Invalid Bridge Priority value"; + } + } + description + "The manageable component of the Bridge Identifier"; + } + } + } + + container STP_MST_PORT { + description + "STP MST Port configurations, maps to STP_MST_PORT_TABLE"; + + list STP_MST_PORT_LIST { + description + "STP MST Port List attributes"; + + key "inst_id ifname"; + + leaf inst_id { + type leafref { + path "../../../STP_MST_INST/STP_MST_INST_LIST/instance"; + } + description + "Reference to MST Instance"; + } + + leaf ifname { + type leafref { + path "../../../STP_PORT/STP_PORT_LIST/ifname"; + } + description + "Reference to Ethernet interface or PortChannel"; + } + uses interfaceAttr; + } + } + } } \ No newline at end of file From c1d6cdc326a85e61f2820bb3dc2ea88d16fccd3c Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Thu, 20 Mar 2025 04:56:56 +0500 Subject: [PATCH 13/14] Fixing YANG model errors --- SONiC_YANG_Model_Guidelines.md | 1018 ----------------- src/sonic-yang-mgmt/sonic_yang_ext.py | 2 +- .../libyang-python-tests/test_sonic_yang.py | 4 - .../tests/files/sample_config_db.json | 36 - .../{stp.json => sonic-spanning-tree.json} | 0 .../tests_config/sonic-spanning-tree.json | 34 + .../yang_model_tests/tests_config/stp.json | 34 - .../yang-models/sonic-spanning-tree.yang | 104 +- 8 files changed, 77 insertions(+), 1155 deletions(-) delete mode 100644 SONiC_YANG_Model_Guidelines.md rename src/sonic-yang-models/tests/yang_model_tests/tests/{stp.json => sonic-spanning-tree.json} (100%) create mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/sonic-spanning-tree.json delete mode 100644 src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json diff --git a/SONiC_YANG_Model_Guidelines.md b/SONiC_YANG_Model_Guidelines.md deleted file mode 100644 index 9d03f1296d4..00000000000 --- a/SONiC_YANG_Model_Guidelines.md +++ /dev/null @@ -1,1018 +0,0 @@ - -# SONiC YANG MODEL GUIDELINES - - -## Revision - - | Rev | Date | Author | Change Description | - |:---:|:-----------:|:------------------:|-----------------------------------| - | 1.0 | 22 Aug 2019 | Praveen Chaudhary | Initial version | - | 1.0 | 11 Sep 2019 | Partha Dutta | Adding additional steps for SONiC YANG | - | 1.1 | 15 Dec 2023 | Jingwen Xie | Added rules for List Keys | - -## References -| References | Date/Version | Link | -|:-------------------------:|:-------------------:|:-----------------------------------:| -| RFC 7950 | August 2016 | https://tools.ietf.org/html/rfc7950 | -| Management Framework | 0.9 | https://github.com/sonic-net/SONiC/pull/436 | - -## Terminology and Acronyms -| Acronyms | Description/Expansion | -|:-------------------------:|:-------------------:| -| ABNF | Augmented Backus-Naur Form | -| XPath | XML Path Language | -| CVL | Configuration Validation Library | - - -## Overview - This document lists the guidelines, which will be used to write YANG Modules for SONiC. These YANG Modules (called SONiC YANG models) will be primarily based on or represent the ABNF.json of SONiC, and the syntax of YANG models must follow RFC 7950 ([https://tools.ietf.org/html/rfc7950](https://tools.ietf.org/html/rfc7950)). Details of config in format of ABNF.json can be found at https://github.com/sonic-net/SONiC/wiki/Configuration. - -These YANG models will be used to verify the configuration for SONiC switches, so a library which supports validation of configuration on SONiC Switch must use these YANG Models. List of such Libraries are: 1.) Configuration Validation Library. (CVL). YANG models, which are written using these guidelines can also be used as User End YANG Models, i.e North Bound configuration tools or CLI can provide config data in sync with these YANG models. For example [SONiC Management Framework](https://github.com/sonic-net/SONiC/pull/436) uses SONiC YANG models as Northbound Management YANG and for configuration validation purpose also. - -## Guidelines - - -### 1. All schema definitions related to a feature should be written in a single YANG model file. YANG model file is named as 'sonic-{feature}.yang', e.g. for ACL feature sonic-acl.yang is the file name. It is best to categorize YANG Modules based on a networking components. For example, it is good to have separate modules for VLAN, ACL, PORT and IP-ADDRESSES etc. - -``` -sonic-acl.yang -sonic-interface.yang -sonic-port.yang -sonic-vlan.yang -``` - -### 2. It is mandatory to define a top level YANG container named as 'sonic-{feature}' i.e. same as YANG model name. For example, sonic-acl.yang should have 'sonic-acl' as top level container. All other definition should be written inside the top level container. - -Example : -#### YANG -```yang -module sonic-acl { - container sonic-acl { - ..... - ..... - } -} -``` - -### 3. Define namespace as "http://github.com/sonic-net/{model-name}". - -Example : -#### YANG -```yang -module sonic-acl { - namespace "http://github.com/sonic-net/sonic-acl"; - ..... - ..... -} -``` - -### 4. Use 'revision' to record revision history whenever YANG model is changed. Updating revision with appropriate details helps tracking the changes in the model. - -Example : - -#### YANG -```yang -module sonic-acl { - revision 2019-09-02 { - description - "Added must expression for ACL_RULE_LIST."; // Updated with new change details - } - - revision 2019-09-01 { - description - "Initial revision."; - } - ..... - ..... -} -``` - -### 5. Each primary section of ABNF.json (i.e a dictionary in ABNF.json) for example, VLAN, VLAN_MEMBER, INTERFACE in ABNF.json will be mapped to a container in YANG model. - -Example: Table VLAN will translate to container VLAN. - -#### ABNF - -```yang -"VLAN": { - "Vlan100": { - "vlanid": "100" - } - } -``` -will translate to: - -#### YANG --- -```yang -container VLAN { //"VLAN" mapped to a container - list VLAN_LIST { - key name; - leaf vlanid { - type uint16; - } - } -} -``` - - -### 6. Each leaf in YANG module should have same name (including their case) as corresponding key-fields in ABNF.json. - -Example: -Leaf names are same PACKET_ACTION, IP_TYPE and PRIORITY, which are defined in ABNF. - -#### ABNF -``` - "NO-NSW-.....|.....": { - "PACKET_ACTION": "FORWARD", - "IP_TYPE": "IPv6ANY", - "PRIORITY": "955520", - ..... - ..... - }, -``` - -#### YANG -```yang - leaf PACKET_ACTION { - ..... - } - leaf IP_TYPE { - ..... - } - leaf PRIORITY { - ..... - } -``` - -### 7. Use IETF data types for leaf type first if applicable (RFC 6021) . Declare new type (say SONiC types) only if IETF type is not applicable. All SONiC types must be part of same header type or common YANG model. -Example: - -#### YANG -```yang - leaf SRC_IP { - type inet:ipv4-prefix; <<<< - } - - leaf DST_IP { - type inet:ipv4-prefix; - } -``` - -### 8. Data Node/Object Hierarchy of the an objects in YANG models will be same as for all the fields at same hierarchy in Config DB. If any exception is created then it must be recorded properly with comment under object level in YANG models. To see an example of a comment, please refer to the step with heading as "Comment all must, when and patterns conditions." below. - -For Example: - -"Family" of VLAN_INTERFACE and "IP_TYPE" of ACL_RULE should be at same level in YANG model too. - -#### ABNF -``` -"VLAN_INTERFACE": { - "Vlan100|2a04:f547:45:6709::1/64": { - "scope": "global", - "family": "IPv6" - } -} -"ACL_RULE": { - "NO-NSW-PACL-V4|DEFAULT_DENY": { - "PACKET_ACTION": "DROP", - "IP_TYPE": "IPv4ANY", - "PRIORITY": "0" - } -} -``` -#### YANG -In YANG, "Family" of VLAN_INTERFACE and "IP_TYPE" of ACL_RULE is at same level. -```yang -container VLAN_INTERFACE { - description "VLAN_INTERFACE part of config_db.json"; - list VLAN_INTERFACE_LIST { - ...... - ...... - leaf family { - type sonic-head:ip-family; - } - } -} - -container ACL_RULE { - description "ACL_RULE part of config_db.json"; - list ACL_RULE_LIST { - ...... - ...... - leaf IP_TYPE { - type sonic-head:ip_type; - } - } -} -``` - -### 9. If an object is part of primary-key in ABNF.json, then it should be a key in YANG model. In YANG models, a primary-key from ABNF.json can be represented either as name of a Container object or as a key field in List object. Exception must be recorded in YANG Model with a comment in object field. To see an example of a comment, please refer to the step with heading as "Comment all must, when and patterns conditions." below. Though, key names are not stored in Redis DB, use the same key name as defined in ABNF schema. - -Example: VLAN_MEMBER dictionary in ABNF.json has both vlan-id and ifname part of the key. So YANG model should have the same keys. - -#### ABNF -``` - "VLAN_MEMBER": { - "Vlan100|Ethernet0": { //<<<< KEYS - "tagging_mode": "untagged" - } - } -``` -;Defines interfaces which are members of a vlan -key = VLAN_MEMBER_TABLE:"Vlan"vlanid:ifname ; - -#### YANG -```yang -container VLAN_MEMBER { - description "VLAN_MEMBER part of config_db.json"; - list ..... { - key "vlan-name ifname";//<<<< KEYS - } -} -``` - -### 10. If any key used in current table refers to other table, use leafref type for the key leaf definition. - -Example : -#### ABNF - -``` -key: ACL_RULE_TABLE:table_name:rule_name -..... -..... -``` -#### YANG -```yang -..... -container ACL_TABLE { - list ACL_TABLE_LIST { - key table_name; - - leaf table_name { - type string; - } - ..... - ..... - } -} -container ACL_RULE { - list ACL_RULE_LIST { - key "table_name rule_name"; - - leaf table_name { - type leafref { - path "../../../ACL_TABLE/ACL_TABLE_LIST/aclname"; //Refers to other table 'ACL_TABLE' - } - } - - leaf rule_name { - type string; - } - ..... - ..... - } -} -``` - -### 11. Mapping tables in Redis are defined using nested 'list'. Use 'sonic-ext:map-list "true";' to indicate that the 'list' is used for mapping table. The outer 'list' is used for multiple instances of mapping. The inner 'list' is used for mapping entries for each outer list instance. - -Example : - -#### ABNF -``` -; TC to queue map -;SAI mapping - qos_map with SAI_QOS_MAP_ATTR_TYPE == SAI_QOS_MAP_TC_TO_QUEUE. See saiqosmaps.h -key = "TC_TO_QUEUE_MAP_TABLE:"name ;field -tc_num = 1*DIGIT ;values -queue = 1*DIGIT; queue index - -``` - -#### YANG -```yang - container TC_TO_QUEUE_MAP { - list TC_TO_QUEUE_MAP_LIST { - key "name"; - sonic-ext:map-list "true"; //special annotation for map table - - leaf name { - type string; - } - - list TC_TO_QUEUE_MAP_LIST { //this is list inside list for storing mapping between two fields - key "tc_num qindex"; - leaf tc_num { - type string { - pattern "[0-9]?"; - } - } - leaf qindex { - type string { - pattern "[0-9]?"; - } - } - } - } - } -``` - - -### 12. 'ref_hash_key_reference' in ABNF schema is defined using 'leafref' to the referred table. - -Example : - -#### ABNF -``` -; QUEUE table. Defines port queue. -; SAI mapping - port queue. - -key = "QUEUE_TABLE:"port_name":queue_index -queue_index = 1*DIGIT -port_name = ifName -queue_reference = ref_hash_key_reference ;field value -scheduler = ref_hash_key_reference; reference to scheduler key -wred_profile = ref_hash_key_reference; reference to wred profile key - -``` - -#### YANG -```yang -container sonic-queue { - container QUEUE { - list QUEUE_LIST { - ..... - leaf scheduler { - type leafref { - path "/sch:sonic-scheduler/sch:SCHEDULER/sch:name"; //Reference to SCHEDULER table - } - } - - leaf wred_profile { - type leafref { - path "/wrd:sonic-wred-profile/wrd:WRED_PROFILE/wrd:name"; // Reference to WRED_PROFILE table - } - } - } - } -} -``` - -### 13. To establish complex relationship and constraints among multiple tables use 'must' expression. Define appropriate error message for reporting to Northbound when condition is not met. For existing feature, code logic could be reference point for deriving 'must' expression. -Example: - -#### YANG -```yang - must "(/sonic-ext:operation/sonic-ext:operation != 'DELETE') or " + - "count(../../ACL_TABLE[aclname=current()]/ports) = 0" { - error-message "Ports are already bound to this rule."; - } -``` - -### 14. Define appropriate 'error-app-tag' and 'error' messages for in 'length', 'pattern', 'range' and 'must' statement so that management application can use it for error reporting. - -Example: - -#### YANG -```yang -module sonic-vlan { - .... - .... - leaf vlanid { - mandatory true; - type uint16 { - range "1..4095" { - error-message "Vlan ID out of range"; - error-app-tag vlanid-invalid; - } - } - } - .... - .... -} - -``` - -### 15. All must, when, pattern and enumeration constraints can be derived from .h files or from code. If code has the possibility to have unknown behavior with some config, then we should put a constraint in YANG models objects. Also, Developer can put any additional constraint to stop invalid configuration. For new features, constraints may be derived based on low-level design document. - -For Example: Enumeration of IP_TYPE comes for aclorch.h -``` -#define IP_TYPE_ANY "ANY" -#define IP_TYPE_IP "IP" -#define IP_TYPE_NON_IP "NON_IP" -#define IP_TYPE_IPv4ANY "IPV4ANY" -#define IP_TYPE_NON_IPv4 "NON_IPv4" -#define IP_TYPE_IPv6ANY "IPV6ANY" -#define IP_TYPE_NON_IPv6 "NON_IPv6" -#define IP_TYPE_ARP "ARP" -#define IP_TYPE_ARP_REQUEST "ARP_REQUEST" -#define IP_TYPE_ARP_REPLY "ARP_REPLY" -``` -Example of When Statement: Orchagent of SONiC will have unknown behavior if below config is entered, So YANG must have a constraint. Here SRC_IP is IPv4, where as IP_TYPE is IPv6. - -#### ABNF: -``` - "ACL_RULE": { - "NO-NSW-PACL-V4|Rule_20": { - "PACKET_ACTION": "FORWARD", - "DST_IP": "10.186.72.0/26", - "SRC_IP": "10.176.0.0/15", - "PRIORITY": "999980", - "IP_TYPE": "IPv6" - }, - -``` -#### YANG: -```yang -choice ip_prefix { - case ip4_prefix { - when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY' or .='ARP'])"; - leaf SRC_IP { - type inet:ipv4-prefix; - } - leaf DST_IP { - type inet:ipv4-prefix; - } - } - case ip6_prefix { - when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; - leaf SRC_IPV6 { - type inet:ipv6-prefix; - } - leaf DST_IPV6 { - type inet:ipv6-prefix; - } - } - } -``` -Example of Pattern: If PORT Range should be "<0-65365> - <0-65365>" -``` -leaf L4_DST_PORT_RANGE { - type string { - pattern '([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])-([0-9]{1,4}|[0-5][0-9]{4}|[6][0-4][0-9]{3}|[6][5][0-2][0-9]{2}|[6][5][3][0-5]{2}|[6][5][3][6][0-5])'; - } -} -``` -### 16. Comment all must, when and patterns conditions. See example of comment below. -Example: - -#### YANG -```yang -leaf family { - /* family leaf needed for backward compatibility - Both ip4 and ip6 address are string in IETF RFC 6020, - so must statement can check based on : or ., family - should be IPv4 or IPv6 according. - */ - must "(contains(../ip-prefix, ':') and current()='IPv6') or - (contains(../ip-prefix, '.') and current()='IPv4')"; - type sonic-head:ip-family; - } -``` - - -### 17. If a List object is needed in YANG model to bundle multiple entries from a Table in ABNF.json, but this LIST is not a valid entry in config data, then we must define such list as _LIST . - -For Example: Below entries in PORTCHANNEL_INTERFACE Table must be part of List Object in YANG model, because variable number of entries may be present in config data. But there is no explicit list in config data. To support this, a list object with name PORTCHANNEL_INTERFACE_LIST should be added in YANG model. -#### ABNF: -``` -"PORTCHANNEL_INTERFACE": { - "PortChannel01|10.0.0.56/31": {}, - "PortChannel01|FC00::71/126": {}, - "PortChannel02|10.0.0.58/31": {}, - "PortChannel02|FC00::75/126": {} - ... - } -``` - -#### YANG -```yang -container PORTCHANNEL_INTERFACE { - - description "PORTCHANNEL_INTERFACE part of config_db.json"; - - list PORTCHANNEL_INTERFACE_LIST {<<<<< - ..... - ..... - } -} -``` - -### 18. In some cases it may be required to split an ABNF table into multiple YANG lists based on the data stored in the ABNF table. In this case it is crucial to ensure that the List keys are non-overlapping, unique, and unambiguous. - -**Strategies for Ensuring Unique and Unambiguous Keys**: Utilize composite keys that have a different number of key elements to distinguish lists. Need to mention that different key names do not count as unambiguous model. - -#### ABNF -``` -"INTERFACE" : { - "Ethernet1" : { - "vrf-name": "vrf1" - } - "Ethernet1|10.184.230.211/31": { - } -} -``` -#### Example 1: Key with different number of elements(composite keys - Allowed case) - -`INTERFACE` table stores VRF names to which an interface belongs, also it stores IP address of each interface. Hence it is needed to split them into two different YANG lists. - -```yang -...... -container INTERFACE { - list INTERFACE_LIST { // 1st list - key ifname; - - leaf ifname { - type leafref { - ...... - } - } - leaf vrf-name { - type leafref { - ...... - } - } - ...... - } - - list INTERFACE_IPADDR_LIST { //2nd list - key "ifname ip_addr" - - leaf ifname { - type leafref { - ...... - } - } - leaf ip_addr { - type inet:ipv4-prefix; - } - ...... - } -} -...... -``` -In the example above if the config DB contains an INTERFACE table with single key element then it will be associted with the INTERFACE_LIST and if contains 2 key elements then it will be associated with INTERFACE_IPADDR_LIST - -#### Example 2: Keys with same number of elements of same type (NOT Allowed case 1) - -```yang -...... -container NOT_SUPPORTED_INTERFACE { - list NOT_SUPPORTED_INTERFACE_LIST { // 1st list - key ifname; - leaf ifname { - type string; - } - // ... - } - - list NOT_SUPPORTED_INTERFACE_ANOTHER_LIST { // Negative case - key ifname; - leaf ifname { - type string; - } - // ... - } -} -...... -``` - -In the example above if the config DB contains an NOT_SUPPORTED_INTERFACE table with key Ethernet1 then it would match with both the list, this is an overlapping scenario - -#### Example 3: Keys with same number of elements of same type (NOT Allowed case 2) - -```yang -...... -container NOT_SUPPORTED_TELEMETRY_CLIENT { - list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { // 1st list - key "prefix name"; - - leaf prefix { - type string { - pattern "DestinationGroup_" + ".*"; - } - } - - leaf name { - type string; - } - - leaf dst_addr { - type ipv4-port; - } - } - - list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { // Negative case - key "prefix name"; - - leaf prefix { - type string { - pattern "Subscription_" + ".*"; - } - } - - leaf name { - type string; - } - - leaf dst_group { - must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; - type string; - } - } -} -...... -``` -In the example above if the config DB contains an NOT_SUPPORTED_TELEMETRY_CLIENT table with key "DestinationGroup|HS", then it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario - -#### Example 4: keys with same number of elements and different type(NOT Allowed case 3) - -In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "1234", it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario - -```yang -...... -container NOT_SUPPORTED_TELEMETRY_CLIENT { - list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { // 1st list - key "prefix"; - - leaf prefix { - type string { - pattern ".*"; - } - } - - leaf dst_addr { - type ipv4-port; - } - } - - list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { // Negative case - key "id"; - - leaf id { - type int32; - } - - leaf dst_group { - must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; - type int32; - } - } -} -...... -``` - -#### Example 5: keys with same number of elements and different type(NOT Allowed case 4) - -In the given example, if the configuration database has an NOT_SUPPORTED_TELEMETRY_CLIENT table with the key "1234|1234", it would correspond to the NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST and NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST, this is an overlapping scenario - -```yang -...... -container NOT_SUPPORTED_TELEMETRY_CLIENT { - list NOT_SUPPORTED_TELEMETRY_CLIENT_DS_LIST { // 1st list - key "prefix name"; - - leaf prefix { - type string; - } - - leaf name { - type string; - } - - leaf dst_addr { - type ipv4-port; - } - } - - list NOT_SUPPORTED_TELEMETRY_CLIENT_SUB_LIST { // Negative case - key "id name"; - - leaf id { - type int32; - } - - leaf name { - type int32; - } - - leaf dst_group { - must "(contains(../../TELEMETRY_CLIENT_DS_LIST/prefix, current()))"; - type int32; - } - } -} -...... -``` - - -### 19. Add read-only nodes for state data using 'config false' statement. Define a separate top level container for state data. If state data is defined in other DB than CONFIG_DB, use extension 'sonic-ext:db-name' for defining the table present in other Redis DB. The default separator used in table key is "|", if it is different, use 'sonic-ext:key-delim {separator};' YANG extension. This step applies when SONiC YANG is used as Northbound YANG. - -Example: - -#### YANG -```yang -container ACL_RULE { - list ACL_RULE_LIST { - .... - .... - container state { - sonic-ext:db-name "APPL_DB"; //For example only - sonic-ext:key-delim ":"; //For example only - - config false; - description "State data"; - - leaf MATCHED_PACKETS { - type yang:counter64; - } - - leaf MATCHED_OCTETS { - type yang:counter64; - } - } - } -} -``` - -### 20. Define custom RPC for executing command like clear, reset etc. No configuration should change through such RPCs. Define 'input' and 'output' as needed, however they are optional. This step applies when SONiC YANG is used as Northbound YANG. - -Example: - -#### YANG -```yang -container sonic-acl { - .... - .... - rpc clear-stats { - input { - leaf aclname { - type string; - } - - leaf rulename { - type string; - } - } - } -} -``` - -### 21. Define Notification for sending out events generated in the system, e.g. link up/down or link failure event. This step applies when SONiC YANG is used as Northbound YANG. - -Example: - -#### YANG -```yang -module sonic-port { - .... - .... - notification link_event { - leaf port { - type leafref { - path "../../PORT/PORT_LIST/ifname"; - } - } - } -} -``` - -## APPENDIX - -### Sample SONiC ACL YANG - -```yang -module sonic-acl { - namespace "http://github.com/sonic-net/sonic-acl"; - prefix sacl; - yang-version 1.1; - - import ietf-yang-types { - prefix yang; - } - - import ietf-inet-types { - prefix inet; - } - - import sonic-common { - prefix scommon; - } - - import sonic-port { - prefix prt; - } - - import sonic-portchannel { - prefix spc; - } - - import sonic-mirror-session { - prefix sms; - } - - import sonic-pf-limits { - prefix spf; - } - - organization - "SONiC"; - - contact - "SONiC"; - - description - "SONiC YANG ACL"; - - revision 2019-09-11 { - description - "Initial revision."; - } - - container sonic-acl { - container ACL_TABLE { - list ACL_TABLE_LIST { - key "table_name"; - - leaf table_name { - type string; - } - - leaf policy_desc { - type string { - length 1..255 { - error-app-tag policy-desc-invalid-length; - } - } - } - - leaf stage { - type enumeration { - enum INGRESS; - enum EGRESS; - } - } - - leaf type { - type enumeration { - enum MIRROR; - enum L2; - enum L3; - enum L3V6; - } - } - - leaf-list ports { - type union { - type leafref { - path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname"; - } - type leafref { - path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:PORTCHANNEL_LIST/spc:name"; - } - } - } - } - } - - container ACL_RULE { - list ACL_RULE_LIST { - key "table_name rule_name"; - leaf table_name { - type leafref { - path "../../../ACL_TABLE/ACL_TABLE_LIST/table_name"; - } - must "(/scommon:operation/scommon:operation != 'DELETE') or " + - "(current()/../../../ACL_TABLE/ACL_TABLE_LIST[table_name=current()]/type = 'L3')" { - error-message "Type not staisfied."; - } - } - - leaf rule_name { - type string; - } - - leaf PRIORITY { - type uint16 { - range "1..65535"{ - error-message "Invalid ACL rule priority."; - } - } - } - - leaf RULE_DESCRIPTION { - type string; - } - - leaf PACKET_ACTION { - type enumeration { - enum FORWARD; - enum DROP; - enum REDIRECT; - } - } - - leaf MIRROR_ACTION { - type leafref { - path "/sms:sonic-mirror-session/sms:MIRROR_SESSION/sms:MIRROR_SESSION_LIST/sms:name"; - } - } - - leaf IP_TYPE { - type enumeration { - enum ANY; - enum IP; - enum IPV4; - enum IPV4ANY; - enum NON_IPV4; - enum IPV6ANY; - enum NON_IPV6; - } - } - - leaf IP_PROTOCOL { - type uint8 { - range "1|2|6|17|46|47|51|103|115"; - } - } - - leaf ETHER_TYPE { - type string { - pattern "(0x88CC)|(0x8100)|(0x8915)|(0x0806)|(0x0800)|(0x86DD)|(0x8847)" { - error-message "Invalid ACL Rule Ether Type"; - error-app-tag ether-type-invalid; - } - } - } - - choice ip_src_dst { - case ipv4_src_dst { - when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV4' or .='IPV4ANY'])"; - leaf SRC_IP { - mandatory true; - type inet:ipv4-prefix; - } - leaf DST_IP { - mandatory true; - type inet:ipv4-prefix; - } - } - case ipv6_src_dst { - when "boolean(IP_TYPE[.='ANY' or .='IP' or .='IPV6' or .='IPV6ANY'])"; - leaf SRC_IPV6 { - mandatory true; - type inet:ipv6-prefix; - } - leaf DST_IPV6 { - mandatory true; - type inet:ipv6-prefix; - } - } - } - - choice src_port { - case l4_src_port { - leaf L4_SRC_PORT { - type uint16; - } - } - case l4_src_port_range { - leaf L4_SRC_PORT_RANGE { - type string { - pattern "[0-9]{1,5}(-)[0-9]{1,5}"; - } - } - } - } - - choice dst_port { - case l4_dst_port { - leaf L4_DST_PORT { - type uint16; - } - } - case l4_dst_port_range { - leaf L4_DST_PORT_RANGE { - type string { - pattern "[0-9]{1,5}(-)[0-9]{1,5}"; - } - } - } - } - - leaf TCP_FLAGS { - type string { - pattern "0[xX][0-9a-fA-F]{2}[/]0[xX][0-9a-fA-F]{2}"; - } - } - - leaf DSCP { - type uint8; - } - } - } - } -} - -``` - diff --git a/src/sonic-yang-mgmt/sonic_yang_ext.py b/src/sonic-yang-mgmt/sonic_yang_ext.py index e3c945b022d..a291e75c2d8 100644 --- a/src/sonic-yang-mgmt/sonic_yang_ext.py +++ b/src/sonic-yang-mgmt/sonic_yang_ext.py @@ -1172,7 +1172,7 @@ def loadData(self, configdbJson, debug=False): self._cropConfigDB() # xlated result will be in self.xlateJson self._xlateConfigDB(xlateFile=xlateFile) - print(self.xlateJson) + #print(self.xlateJson) self.sysLog(msg="Try to load Data in the tree") self.root = self.ctx.parse_data_mem(dumps(self.xlateJson), \ ly.LYD_JSON, ly.LYD_OPT_CONFIG|ly.LYD_OPT_STRICT) diff --git a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py index 6076e57c777..86b27ef174e 100644 --- a/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py +++ b/src/sonic-yang-mgmt/tests/libyang-python-tests/test_sonic_yang.py @@ -301,14 +301,10 @@ def test_validate_yang_models(self, sonic_yang_data): NON_CONFIG_YANG_FILES = 3 + EVENT_YANG_FILES # read config jIn = self.readIjsonInput(test_file, 'SAMPLE_CONFIG_DB_JSON') - print(jIn + "\n") jIn = json.loads(jIn) - print(jIn + "\n") numTables = len(jIn) - print(numTables + "\n") # load config and create Data tree syc.loadData(jIn) - print(syc.jIn) # check all tables are loaded and config related to all Yang Models is # loaded in Data tree. assert len(syc.jIn) == numTables diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 7cfee1322e6..00d2801a1e3 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2381,28 +2381,12 @@ "priority": "32768", "enabled": "true", "vlanid": "100" - }, - "Vlan200": { - "forward_delay": "15", - "hello_time": "2", - "max_age": "20", - "priority": "32768", - "enabled": "true", - "vlanid": "200" } }, "STP_VLAN_PORT": { "Vlan100|Ethernet0": { "path_cost": "200000", "priority": "128" - }, - "Vlan100|PortChannel2": { - "path_cost": "20000", - "priority": "64" - }, - "Vlan200|Ethernet4": { - "path_cost": "200000", - "priority": "128" } }, "STP_PORT": { @@ -2415,26 +2399,6 @@ "priority": "128", "portfast": "false", "uplink_fast": "false" - }, - "Ethernet4": { - "enabled": "true", - "root_guard": "false", - "bpdu_guard": "false", - "bpdu_guard_do_disable": "false", - "path_cost": "200000", - "priority": "128", - "portfast": "false", - "uplink_fast": "false" - }, - "PortChannel2": { - "enabled": "false", - "root_guard": "false", - "bpdu_guard": "false", - "bpdu_guard_do_disable": "false", - "path_cost": "20000", - "priority": "64", - "portfast": "false", - "uplink_fast": "false" } }, diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests/sonic-spanning-tree.json similarity index 100% rename from src/sonic-yang-models/tests/yang_model_tests/tests/stp.json rename to src/sonic-yang-models/tests/yang_model_tests/tests/sonic-spanning-tree.json diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/sonic-spanning-tree.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/sonic-spanning-tree.json new file mode 100644 index 00000000000..dea73c498f1 --- /dev/null +++ b/src/sonic-yang-models/tests/yang_model_tests/tests_config/sonic-spanning-tree.json @@ -0,0 +1,34 @@ +{ + "PVST_GLOBAL_VALID": { + "sonic-spanning-tree:sonic-spanning-tree": { + "sonic-spanning-tree:STP": { + "STP_LIST": [ + { + "keyleaf": "GLOBAL", + "mode": "pvst", + "rootguard_timeout": "30", + "forward_delay": "15", + "hello_time": "2", + "max_age": "20", + "priority": "32768" + } + ] + }, + "sonic-spanning-tree:STP_PORT": { + "STP_PORT_LIST": [ + { + "ifname": "Ethernet0", + "enabled": "true", + "root_guard": "false", + "bpdu_guard": "false", + "bpdu_guard_do_disable": "false", + "uplink_fast": "false", + "portfast": "false", + "path_cost": "200", + "priority": "128" + } + ] + } + } + } +} \ No newline at end of file diff --git a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json b/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json deleted file mode 100644 index d6425ac3863..00000000000 --- a/src/sonic-yang-models/tests/yang_model_tests/tests_config/stp.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "PVST_GLOBAL_VALID": { - "sonic-spanning-tree:sonic-spanning-tree": { - "sonic-spanning-tree:STP": { - "STP_LIST": [ - { - "keyleaf": "GLOBAL", - "mode": "pvst", - "rootguard_timeout": "30", - "forward_delay": "15", - "hello_time": "2", - "max_age": "20", - "priority": "32768" - } - ] - }, - "sonic-spanning-tree:STP_PORT": { - "STP_PORT_LIST": [ - { - "ifname": "Ethernet0", - "enabled": "true", - "root_guard": "false", - "bpdu_guard": "false", - "bpdu_guard_do_disable": "false", - "uplink_fast": "false", - "portfast": "false", - "path_cost": "200", - "priority": "128" - } - ] - } - } - } -} \ No newline at end of file diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index e3792c2e0d0..175cadd9e09 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -1,6 +1,7 @@ module sonic-spanning-tree { yang-version 1.1; namespace "http://github.com/sonic-net/sonic-stp"; + prefix stp; /* @@ -25,7 +26,6 @@ module sonic-spanning-tree { "Initial implementation for SONiC STP support"; } - grouping vlanModeAttr { description "Configuration parameters for VLAN-based STP settings"; @@ -145,7 +145,6 @@ module sonic-spanning-tree { mandatory true; description "STP operating mode"; - /*default "pvst"; } leaf rootguard_timeout { @@ -155,16 +154,13 @@ module sonic-spanning-tree { } } units "seconds"; - description - "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state"; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode!='mst'" {}*/ - /*must "../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - /*must "(../mode = 'pvst')" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'pvst')" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" { + must "../mode = 'pvst'" { error-message "Root guard timeout configuration is allowed only in PVST mode"; /*error-app-tag stp-invalid;*/ } + default 30; + description + "Once superior BPDUs stop coming on the port, device will wait for a period until root guard timeout before moving the port to forwarding state"; } uses vlanModeAttr; } @@ -202,7 +198,6 @@ module sonic-spanning-tree { description "Spanning tree enabled/disabled on Vlan"; } - uses vlanModeAttr; } } @@ -212,14 +207,13 @@ module sonic-spanning-tree { "Vlan port configurations, maps to STP_VLAN_PORT_TABLE"; list STP_VLAN_PORT_LIST { + key "vlan-name ifname"; description "List of VLAN port configurations"; - key "vlan-name ifname"; leaf vlan-name { type leafref { - /*path "../../../STP_VLAN/STP_VLAN_LIST/name";*/ - path "/stp:sonic-spanning-tree/stp:STP_VLAN/stp:STP_VLAN_LIST/stp:name"; + path "../../../STP_VLAN/STP_VLAN_LIST/name"; } description "Reference to Vlan"; @@ -227,8 +221,7 @@ module sonic-spanning-tree { leaf ifname { type leafref { - /*path "../../../STP_PORT/STP_PORT_LIST/ifname";*/ - path "/stp:sonic-spanning-tree/stp:STP_PORT/stp:STP_PORT_LIST/stp:ifname"; + path "../../../STP_PORT/STP_PORT_LIST/ifname"; } description "Reference to Ethernet interface or PortChannel"; @@ -243,11 +236,10 @@ module sonic-spanning-tree { "Port Configurations, maps to STP_PORT_TABLE"; list STP_PORT_LIST { + key "ifname"; description "List of STP port List attributes"; - key "ifname"; - /*sonic-ext:dependent-on "STP_LIST";*/ /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ @@ -266,43 +258,41 @@ module sonic-spanning-tree { leaf root_guard { type boolean; + default false; description "Enable/Disable Root guard on port"; } leaf bpdu_guard { type boolean; + default false; description "Enable/Disable port BPDU guard"; } leaf bpdu_guard_do_disable { type boolean; + default false; description "Port to be disabled as it receives a BPDU"; } leaf uplink_fast { type boolean; + default false; description "Enable/Disable uplink-fast on port"; } leaf portfast { type boolean; - /*must "current()!='true' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" {}*/ - /*must "not(.) or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ - /*must "(current()!='true') or (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst')" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst') and ((current() = 'true') or (current() = 'false'))" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'pvst') and (current() = 'true')" {}*/ - description - "Enable/Disable portfast on port in PVST only"; - must "(current() != 'true') or true" { + must "current()='false' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='pvst'" { error-message "Mode must be PVST, and PortFast must be enabled for this configuration to be valid."; /*error-app-tag stp-invalid;*/ } - + default false; + description + "Enable/Disable portfast on port in PVST only"; } uses interfaceAttr; @@ -310,12 +300,13 @@ module sonic-spanning-tree { // For MST leaf edge_port { type boolean; + must "current()='false' or ../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { + error-message "Mode must be MST, and EdgePort must be enabled for this configuration to be valid."; + /*error-app-tag stp-invalid;*/ + } + default false; description "Enable/Disable Edge-port on interface"; - /*must "(current() = 'true') and (/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst')" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { - error-message "EdgePort configuration allowed in MST only"; - } } leaf link_type { @@ -333,12 +324,12 @@ module sonic-spanning-tree { "Specifies the interface's link type as point-to-point"; } } - description - "Specifies the interface's link type: shared, point-to-point or auto"; - - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode only"; } + default auto; + description + "Specifies the interface's link type: shared, point-to-point or auto"; } } } @@ -352,6 +343,7 @@ module sonic-spanning-tree { max-elements 1; description "List of MST global configurations"; + /*sonic-ext:dependent-on "STP_LIST";*/ /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ @@ -368,10 +360,7 @@ module sonic-spanning-tree { leaf name { type string; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - /*must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } @@ -381,9 +370,7 @@ module sonic-spanning-tree { leaf revision { type uint32; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } @@ -393,57 +380,51 @@ module sonic-spanning-tree { leaf max_hops { type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } + default 20; description "MST Max hops"; } leaf max_age { type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } + default 20; description "MST max age in seconds"; } leaf hello_time { type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } + default 2; description "MST hello time in seconds"; } leaf forward_delay { type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "(/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf='GLOBAL']/stp:mode = 'mst')" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } + default 15; description "MST forward delay in seconds"; } leaf hold_count { type uint8; - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" {}*/ - /*must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode = 'mst'" {}*/ - must "/stp:sonic-spanning-tree/stp:STP/stp:STP_LIST[stp:keyleaf = 'GLOBAL']/stp:mode = 'mst'" { + must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode"; /*error-app-tag stp-invalid;*/ } @@ -458,11 +439,10 @@ module sonic-spanning-tree { "STP MST Instance Configuration, maps to STP_MST_INST_TABLE"; list STP_MST_INST_LIST { + key "instance"; description "List of STP MST Instance attributes"; - key "instance"; - /*sonic-ext:dependent-on "sonic-spanning-tree:STP/STP_LIST";*/ leaf instance { @@ -483,6 +463,7 @@ module sonic-spanning-tree { error-message "Invalid Bridge Priority value"; } } + default 32768; description "The manageable component of the Bridge Identifier"; } @@ -494,10 +475,9 @@ module sonic-spanning-tree { "STP MST Port configurations, maps to STP_MST_PORT_TABLE"; list STP_MST_PORT_LIST { - description - "STP MST Port List attributes"; - key "inst_id ifname"; + description + "STP MST Port List attributes"; leaf inst_id { type leafref { From f9faf53a755cee0d5134154cf26d9feae100d2c6 Mon Sep 17 00:00:00 2001 From: Wajahat Razi Date: Thu, 27 Mar 2025 03:36:25 +0500 Subject: [PATCH 14/14] LinkType: Fixing STP YANG model errors --- src/sonic-yang-models/tests/files/sample_config_db.json | 1 + src/sonic-yang-models/yang-models/sonic-spanning-tree.yang | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sonic-yang-models/tests/files/sample_config_db.json b/src/sonic-yang-models/tests/files/sample_config_db.json index 00d2801a1e3..e0b088f1478 100644 --- a/src/sonic-yang-models/tests/files/sample_config_db.json +++ b/src/sonic-yang-models/tests/files/sample_config_db.json @@ -2401,6 +2401,7 @@ "uplink_fast": "false" } }, + "MCLAG_DOMAIN": { "123": { diff --git a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang index 175cadd9e09..5f0ef0a9cbf 100644 --- a/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang +++ b/src/sonic-yang-models/yang-models/sonic-spanning-tree.yang @@ -327,7 +327,6 @@ module sonic-spanning-tree { must "../../../STP/STP_LIST[keyleaf='GLOBAL']/mode='mst'" { error-message "Configuration allowed in MST mode only"; } - default auto; description "Specifies the interface's link type: shared, point-to-point or auto"; }