diff --git a/models/yang/sonic/Makefile b/models/yang/sonic/Makefile
new file mode 100644
index 0000000000..9141ff952a
--- /dev/null
+++ b/models/yang/sonic/Makefile
@@ -0,0 +1,53 @@
+TOPDIR := ../../../
+SONIC_YANGAPI_DIR := $(TOPDIR)/build/yaml
+SONIC_YANGDIR := $(TOPDIR)/models/yang/sonic
+SONIC_YANGDIR_DEVIATION := $(TOPDIR)/models/yang/sonic/deviation
+SONIC_YANGDIR_COMMON := $(TOPDIR)/models/yang/sonic/common
+SONIC_YANGDIR_COMMON_IETF := $(TOPDIR)/models/yang/sonic/common/ietf
+SONIC_YANG_MOD_FILES := $(shell find $(SONIC_YANGDIR) -maxdepth 1 -name '*.yang' | sort)
+SONIC_YANG_COMMON_FILES := $(shell find $(SONIC_YANGDIR_COMMON) -name '*.yang' | sort)
+SONIC_YANG_COMMON_FILES += $(shell find $(SONIC_YANGDIR_COMMON_IETF) -name '*.yang' | sort)
+
+SONIC_TOOLS_DIR := $(TOPDIR)/tools
+SONIC_PYANG_DIR := $(SONIC_TOOLS_DIR)/pyang
+SONIC_PYANG_PLUGIN_DIR := $(SONIC_PYANG_DIR)/pyang_plugins
+SONIC_PYANG_BIN := pyang
+
+all: yamlGen allyangs.tree allyangs_tree.html
+
+#yamlGen: $(SONIC_YANGAPI_DIR)/.done
+
+allyangs.tree: $(SONIC_YANG_MOD_FILES) $(SONIC_YANG_COMMON_FILES)
+ $(SONIC_PYANG_BIN) \
+ -f tree \
+ -o $(SONIC_YANGDIR)/$@ \
+ -p $(SONIC_YANGDIR_COMMON):$(SONIC_YANGDIR) \
+ $(SONIC_YANG_MOD_FILES)
+ @echo "+++++ Generation of YANG tree for Sonic Yang modules completed +++++"
+
+allyangs_tree.html: $(SONIC_YANG_MOD_FILES) $(SONIC_YANG_COMMON_FILES)
+ $(SONIC_PYANG_BIN) \
+ -f jstree \
+ -o $(SONIC_YANGDIR)/$@ \
+ -p $(SONIC_YANGDIR_COMMON):$(SONIC_YANGDIR) \
+ $(SONIC_YANG_MOD_FILES)
+ @echo "+++++ Generation of HTML tree for Sonic Yang modules completed +++++"
+
+#======================================================================
+# Generate YAML files for SONiC YANG modules
+#======================================================================
+yamlGen:
+ @echo "+++++ Generating YAML files for Sonic Yang modules +++++"
+ mkdir -p $(SONIC_YANGAPI_DIR)
+ $(SONIC_PYANG_BIN) \
+ -f swaggerapi \
+ --outdir $(SONIC_YANGAPI_DIR) \
+ --plugindir $(SONIC_PYANG_PLUGIN_DIR) \
+ -p $(SONIC_YANGDIR_COMMON):$(SONIC_YANGDIR) \
+ $(SONIC_YANG_MOD_FILES)
+ @echo "+++++ Generation of YAML files for Sonic Yang modules completed +++++"
+
+clean:
+ @echo "Removing files ..."
+ rm -rf $(SONIC_YANGAPI_DIR)
+ rm -rf allyangs.tree allyangs_tree.html
diff --git a/models/yang/sonic/common/ietf/ietf-inet-types.yang b/models/yang/sonic/common/ietf/ietf-inet-types.yang
new file mode 100644
index 0000000000..2f14270dec
--- /dev/null
+++ b/models/yang/sonic/common/ietf/ietf-inet-types.yang
@@ -0,0 +1,457 @@
+module ietf-inet-types {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+ prefix "inet";
+
+ organization
+ "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+ contact
+ "WG Web:
+ WG List:
+
+ WG Chair: David Kessens
+
+
+ WG Chair: Juergen Schoenwaelder
+
+
+ Editor: Juergen Schoenwaelder
+ ";
+
+ description
+ "This module contains a collection of generally useful derived
+ YANG data types for Internet addresses and related things.
+
+ Copyright (c) 2013 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 6991; see
+ the RFC itself for full legal notices.";
+
+ revision 2013-07-15 {
+ description
+ "This revision adds the following new data types:
+ - ip-address-no-zone
+ - ipv4-address-no-zone
+ - ipv6-address-no-zone";
+ reference
+ "RFC 6991: Common YANG Data Types";
+ }
+
+ revision 2010-09-24 {
+ description
+ "Initial revision.";
+ reference
+ "RFC 6021: Common YANG Data Types";
+ }
+
+ /*** collection of types related to protocol fields ***/
+
+ typedef ip-version {
+ type enumeration {
+ enum unknown {
+ value "0";
+ description
+ "An unknown or unspecified version of the Internet
+ protocol.";
+ }
+ enum ipv4 {
+ value "1";
+ description
+ "The IPv4 protocol as defined in RFC 791.";
+ }
+ enum ipv6 {
+ value "2";
+ description
+ "The IPv6 protocol as defined in RFC 2460.";
+ }
+ }
+ description
+ "This value represents the version of the IP protocol.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetVersion textual convention of the SMIv2.";
+ reference
+ "RFC 791: Internet Protocol
+ RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ typedef dscp {
+ type uint8 {
+ range "0..63";
+ }
+ description
+ "The dscp type represents a Differentiated Services Code Point
+ that may be used for marking packets in a traffic stream.
+ In the value set and its semantics, this type is equivalent
+ to the Dscp textual convention of the SMIv2.";
+ reference
+ "RFC 3289: Management Information Base for the Differentiated
+ Services Architecture
+ RFC 2474: Definition of the Differentiated Services Field
+ (DS Field) in the IPv4 and IPv6 Headers
+ RFC 2780: IANA Allocation Guidelines For Values In
+ the Internet Protocol and Related Headers";
+ }
+
+ typedef ipv6-flow-label {
+ type uint32 {
+ range "0..1048575";
+ }
+ description
+ "The ipv6-flow-label type represents the flow identifier or Flow
+ Label in an IPv6 packet header that may be used to
+ discriminate traffic flows.
+
+ In the value set and its semantics, this type is equivalent
+ to the IPv6FlowLabel textual convention of the SMIv2.";
+ reference
+ "RFC 3595: Textual Conventions for IPv6 Flow Label
+ RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+ }
+
+ typedef port-number {
+ type uint16 {
+ range "0..65535";
+ }
+ description
+ "The port-number type represents a 16-bit port number of an
+ Internet transport-layer protocol such as UDP, TCP, DCCP, or
+ SCTP. Port numbers are assigned by IANA. A current list of
+ all assignments is available from .
+
+ Note that the port number value zero is reserved by IANA. In
+ situations where the value zero does not make sense, it can
+ be excluded by subtyping the port-number type.
+ In the value set and its semantics, this type is equivalent
+ to the InetPortNumber textual convention of the SMIv2.";
+ reference
+ "RFC 768: User Datagram Protocol
+ RFC 793: Transmission Control Protocol
+ RFC 4960: Stream Control Transmission Protocol
+ RFC 4340: Datagram Congestion Control Protocol (DCCP)
+ RFC 4001: Textual Conventions for Internet Network Addresses";
+ }
+
+ /*** collection of types related to autonomous systems ***/
+
+ typedef as-number {
+ type uint32;
+ description
+ "The as-number type represents autonomous system numbers
+ which identify an Autonomous System (AS). An AS is a set
+ of routers under a single technical administration, using
+ an interior gateway protocol and common metrics to route
+ packets within the AS, and using an exterior gateway
+ protocol to route packets to other ASes. IANA maintains
+ the AS number space and has delegated large parts to the
+ regional registries.
+
+ Autonomous system numbers were originally limited to 16
+ bits. BGP extensions have enlarged the autonomous system
+ number space to 32 bits. This type therefore uses an uint32
+ base type without a range restriction in order to support
+ a larger autonomous system number space.
+
+ In the value set and its semantics, this type is equivalent
+ to the InetAutonomousSystemNumber textual convention of
+ the SMIv2.";
+ reference
+ "RFC 1930: Guidelines for creation, selection, and registration
+ of an Autonomous System (AS)
+ RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+ RFC 4001: Textual Conventions for Internet Network Addresses
+ RFC 6793: BGP Support for Four-Octet Autonomous System (AS)
+ Number Space";
+ }
+
+ /*** collection of types related to IP addresses and hostnames ***/
+
+ typedef ip-address {
+ type union {
+ type inet:ipv4-address;
+ type inet:ipv6-address;
+ }
+ description
+ "The ip-address type represents an IP address and is IP
+ version neutral. The format of the textual representation
+ implies the IP version. This type supports scoped addresses
+ by allowing zone identifiers in the address format.";
+ reference
+ "RFC 4007: IPv6 Scoped Address Architecture";
+ }
+
+ typedef ipv4-address {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '(%[\p{N}\p{L}]+)?';
+ }
+ description
+ "The ipv4-address type represents an IPv4 address in
+ dotted-quad notation. The IPv4 address may include a zone
+ index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format for the zone index is the numerical
+ format";
+ }
+
+ typedef ipv6-address {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(%[\p{N}\p{L}]+)?';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(%.+)?';
+ }
+ description
+ "The ipv6-address type represents an IPv6 address in full,
+ mixed, shortened, and shortened-mixed notation. The IPv6
+ address may include a zone index, separated by a % sign.
+
+ The zone index is used to disambiguate identical address
+ values. For link-local addresses, the zone index will
+ typically be the interface index number or the name of an
+ interface. If the zone index is not present, the default
+ zone of the device will be used.
+
+ The canonical format of IPv6 addresses uses the textual
+ representation defined in Section 4 of RFC 5952. The
+ canonical format for the zone index is the numerical
+ format as described in Section 11.2 of RFC 4007.";
+ reference
+ "RFC 4291: IP Version 6 Addressing Architecture
+ RFC 4007: IPv6 Scoped Address Architecture
+ RFC 5952: A Recommendation for IPv6 Address Text
+ Representation";
+ }
+
+ typedef ip-address-no-zone {
+ type union {
+ type inet:ipv4-address-no-zone;
+ type inet:ipv6-address-no-zone;
+ }
+ description
+ "The ip-address-no-zone type represents an IP address and is
+ IP version neutral. The format of the textual representation
+ implies the IP version. This type does not support scoped
+ addresses since it does not allow zone identifiers in the
+ address format.";
+ reference
+ "RFC 4007: IPv6 Scoped Address Architecture";
+ }
+
+ typedef ipv4-address-no-zone {
+ type inet:ipv4-address {
+ pattern '[0-9\.]*';
+ }
+ description
+ "An IPv4 address without a zone index. This type, derived from
+ ipv4-address, may be used in situations where the zone is
+ known from the context and hence no zone index is needed.";
+ }
+
+ typedef ipv6-address-no-zone {
+ type inet:ipv6-address {
+ pattern '[0-9a-fA-F:\.]*';
+ }
+ description
+ "An IPv6 address without a zone index. This type, derived from
+ ipv6-address, may be used in situations where the zone is
+ known from the context and hence no zone index is needed.";
+ reference
+ "RFC 4291: IP Version 6 Addressing Architecture
+ RFC 4007: IPv6 Scoped Address Architecture
+ RFC 5952: A Recommendation for IPv6 Address Text
+ Representation";
+ }
+
+ typedef ip-prefix {
+ type union {
+ type inet:ipv4-prefix;
+ type inet:ipv6-prefix;
+ }
+ description
+ "The ip-prefix type represents an IP prefix and is IP
+ version neutral. The format of the textual representations
+ implies the IP version.";
+ }
+
+ typedef ipv4-prefix {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+ + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+ }
+ description
+ "The ipv4-prefix type represents an IPv4 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal to 32.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The canonical format of an IPv4 prefix has all bits of
+ the IPv4 address set to zero that are not part of the
+ IPv4 prefix.";
+ }
+
+ typedef ipv6-prefix {
+ type string {
+ pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+ + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+ + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+ + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+ + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+ pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(/.+)';
+ }
+ description
+ "The ipv6-prefix type represents an IPv6 address prefix.
+ The prefix length is given by the number following the
+ slash character and must be less than or equal to 128.
+
+ A prefix length value of n corresponds to an IP address
+ mask that has n contiguous 1-bits from the most
+ significant bit (MSB) and all other bits set to 0.
+
+ The IPv6 address should have all bits that do not belong
+ to the prefix set to zero.
+
+ The canonical format of an IPv6 prefix has all bits of
+ the IPv6 address set to zero that are not part of the
+ IPv6 prefix. Furthermore, the IPv6 address is represented
+ as defined in Section 4 of RFC 5952.";
+ reference
+ "RFC 5952: A Recommendation for IPv6 Address Text
+ Representation";
+ }
+
+ /*** collection of domain name and URI types ***/
+
+ typedef domain-name {
+ type string {
+ length "1..253";
+ pattern
+ '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+ + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+ + '|\.';
+ }
+ description
+ "The domain-name type represents a DNS domain name. The
+ name SHOULD be fully qualified whenever possible.
+
+ Internet domain names are only loosely specified. Section
+ 3.5 of RFC 1034 recommends a syntax (modified in Section
+ 2.1 of RFC 1123). The pattern above is intended to allow
+ for current practice in domain name use, and some possible
+ future expansion. It is designed to hold various types of
+ domain names, including names used for A or AAAA records
+ (host names) and other records, such as SRV records. Note
+ that Internet host names have a stricter syntax (described
+ in RFC 952) than the DNS recommendations in RFCs 1034 and
+ 1123, and that systems that want to store host names in
+ schema nodes using the domain-name type are recommended to
+ adhere to this stricter standard to ensure interoperability.
+
+ The encoding of DNS names in the DNS protocol is limited
+ to 255 characters. Since the encoding consists of labels
+ prefixed by a length bytes and there is a trailing NULL
+ byte, only 253 characters can appear in the textual dotted
+ notation.
+
+ The description clause of schema nodes using the domain-name
+ type MUST describe when and how these names are resolved to
+ IP addresses. Note that the resolution of a domain-name value
+ may require to query multiple DNS records (e.g., A for IPv4
+ and AAAA for IPv6). The order of the resolution process and
+ which DNS record takes precedence can either be defined
+ explicitly or may depend on the configuration of the
+ resolver.
+
+ Domain-name values use the US-ASCII encoding. Their canonical
+ format uses lowercase US-ASCII characters. Internationalized
+ domain names MUST be A-labels as per RFC 5890.";
+ reference
+ "RFC 952: DoD Internet Host Table Specification
+ RFC 1034: Domain Names - Concepts and Facilities
+ RFC 1123: Requirements for Internet Hosts -- Application
+ and Support
+ RFC 2782: A DNS RR for specifying the location of services
+ (DNS SRV)
+ RFC 5890: Internationalized Domain Names in Applications
+ (IDNA): Definitions and Document Framework";
+ }
+
+ typedef host {
+ type union {
+ type inet:ip-address;
+ type inet:domain-name;
+ }
+ description
+ "The host type represents either an IP address or a DNS
+ domain name.";
+ }
+
+ typedef uri {
+ type string;
+ description
+ "The uri type represents a Uniform Resource Identifier
+ (URI) as defined by STD 66.
+
+ Objects using the uri type MUST be in US-ASCII encoding,
+ and MUST be normalized as described by RFC 3986 Sections
+ 6.2.1, 6.2.2.1, and 6.2.2.2. All unnecessary
+ percent-encoding is removed, and all case-insensitive
+ characters are set to lowercase except for hexadecimal
+ digits, which are normalized to uppercase as described in
+ Section 6.2.2.1.
+
+ The purpose of this normalization is to help provide
+ unique URIs. Note that this normalization is not
+ sufficient to provide uniqueness. Two URIs that are
+ textually distinct after this normalization may still be
+ equivalent.
+
+ Objects using the uri type may restrict the schemes that
+ they permit. For example, 'data:' and 'urn:' schemes
+ might not be appropriate.
+
+ A zero-length URI is not a valid URI. This can be used to
+ express 'URI absent' where required.
+
+ In the value set and its semantics, this type is equivalent
+ to the Uri SMIv2 textual convention defined in RFC 5017.";
+ reference
+ "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+ RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+ Group: Uniform Resource Identifiers (URIs), URLs,
+ and Uniform Resource Names (URNs): Clarifications
+ and Recommendations
+ RFC 5017: MIB Textual Conventions for Uniform Resource
+ Identifiers (URIs)";
+ }
+
+}
diff --git a/models/yang/sonic/common/ietf/ietf-yang-types.yang b/models/yang/sonic/common/ietf/ietf-yang-types.yang
new file mode 100644
index 0000000000..ee58fa3ab0
--- /dev/null
+++ b/models/yang/sonic/common/ietf/ietf-yang-types.yang
@@ -0,0 +1,474 @@
+module ietf-yang-types {
+
+ namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+ prefix "yang";
+
+ organization
+ "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+ contact
+ "WG Web:
+ WG List:
+
+ WG Chair: David Kessens
+
+
+ WG Chair: Juergen Schoenwaelder
+
+
+ Editor: Juergen Schoenwaelder
+ ";
+
+ description
+ "This module contains a collection of generally useful derived
+ YANG data types.
+
+ Copyright (c) 2013 IETF Trust and the persons identified as
+ authors of the code. All rights reserved.
+
+ Redistribution and use in source and binary forms, with or
+ without modification, is permitted pursuant to, and subject
+ to the license terms contained in, the Simplified BSD License
+ set forth in Section 4.c of the IETF Trust's Legal Provisions
+ Relating to IETF Documents
+ (http://trustee.ietf.org/license-info).
+
+ This version of this YANG module is part of RFC 6991; see
+ the RFC itself for full legal notices.";
+
+ revision 2013-07-15 {
+ description
+ "This revision adds the following new data types:
+ - yang-identifier
+ - hex-string
+ - uuid
+ - dotted-quad";
+ reference
+ "RFC 6991: Common YANG Data Types";
+ }
+
+ revision 2010-09-24 {
+ description
+ "Initial revision.";
+ reference
+ "RFC 6021: Common YANG Data Types";
+ }
+
+ /*** collection of counter and gauge types ***/
+
+ typedef counter32 {
+ type uint32;
+ description
+ "The counter32 type represents a non-negative integer
+ that monotonically increases until it reaches a
+ maximum value of 2^32-1 (4294967295 decimal), when it
+ wraps around and starts increasing again from zero.
+
+ Counters have no defined 'initial' value, and thus, a
+ single value of a counter has (in general) no information
+ content. Discontinuities in the monotonically increasing
+ value normally occur at re-initialization of the
+ management system, and at other times as specified in the
+ description of a schema node using this type. If such
+ other times can occur, for example, the creation of
+ a schema node of type counter32 at times other than
+ re-initialization, then a corresponding schema node
+ should be defined, with an appropriate type, to indicate
+ the last discontinuity.
+
+ The counter32 type should not be used for configuration
+ schema nodes. A default statement SHOULD NOT be used in
+ combination with the type counter32.
+
+ In the value set and its semantics, this type is equivalent
+ to the Counter32 type of the SMIv2.";
+ reference
+ "RFC 2578: Structure of Management Information Version 2
+ (SMIv2)";
+ }
+
+ typedef zero-based-counter32 {
+ type yang:counter32;
+ default "0";
+ description
+ "The zero-based-counter32 type represents a counter32
+ that has the defined 'initial' value zero.
+
+ A schema node of this type will be set to zero (0) on creation
+ and will thereafter increase monotonically until it reaches
+ a maximum value of 2^32-1 (4294967295 decimal), when it
+ wraps around and starts increasing again from zero.
+
+ Provided that an application discovers a new schema node
+ of this type within the minimum time to wrap, it can use the
+ 'initial' value as a delta. It is important for a management
+ station to be aware of this minimum time and the actual time
+ between polls, and to discard data if the actual time is too
+ long or there is no defined minimum time.
+
+ In the value set and its semantics, this type is equivalent
+ to the ZeroBasedCounter32 textual convention of the SMIv2.";
+ reference
+ "RFC 4502: Remote Network Monitoring Management Information
+ Base Version 2";
+ }
+
+ typedef counter64 {
+ type uint64;
+ description
+ "The counter64 type represents a non-negative integer
+ that monotonically increases until it reaches a
+ maximum value of 2^64-1 (18446744073709551615 decimal),
+ when it wraps around and starts increasing again from zero.
+
+ Counters have no defined 'initial' value, and thus, a
+ single value of a counter has (in general) no information
+ content. Discontinuities in the monotonically increasing
+ value normally occur at re-initialization of the
+ management system, and at other times as specified in the
+ description of a schema node using this type. If such
+ other times can occur, for example, the creation of
+ a schema node of type counter64 at times other than
+ re-initialization, then a corresponding schema node
+ should be defined, with an appropriate type, to indicate
+ the last discontinuity.
+
+ The counter64 type should not be used for configuration
+ schema nodes. A default statement SHOULD NOT be used in
+ combination with the type counter64.
+
+ In the value set and its semantics, this type is equivalent
+ to the Counter64 type of the SMIv2.";
+ reference
+ "RFC 2578: Structure of Management Information Version 2
+ (SMIv2)";
+ }
+
+ typedef zero-based-counter64 {
+ type yang:counter64;
+ default "0";
+ description
+ "The zero-based-counter64 type represents a counter64 that
+ has the defined 'initial' value zero.
+
+ A schema node of this type will be set to zero (0) on creation
+ and will thereafter increase monotonically until it reaches
+ a maximum value of 2^64-1 (18446744073709551615 decimal),
+ when it wraps around and starts increasing again from zero.
+
+ Provided that an application discovers a new schema node
+ of this type within the minimum time to wrap, it can use the
+ 'initial' value as a delta. It is important for a management
+ station to be aware of this minimum time and the actual time
+ between polls, and to discard data if the actual time is too
+ long or there is no defined minimum time.
+
+ In the value set and its semantics, this type is equivalent
+ to the ZeroBasedCounter64 textual convention of the SMIv2.";
+ reference
+ "RFC 2856: Textual Conventions for Additional High Capacity
+ Data Types";
+ }
+
+ typedef gauge32 {
+ type uint32;
+ description
+ "The gauge32 type represents a non-negative integer, which
+ may increase or decrease, but shall never exceed a maximum
+ value, nor fall below a minimum value. The maximum value
+ cannot be greater than 2^32-1 (4294967295 decimal), and
+ the minimum value cannot be smaller than 0. The value of
+ a gauge32 has its maximum value whenever the information
+ being modeled is greater than or equal to its maximum
+ value, and has its minimum value whenever the information
+ being modeled is smaller than or equal to its minimum value.
+ If the information being modeled subsequently decreases
+ below (increases above) the maximum (minimum) value, the
+ gauge32 also decreases (increases).
+
+ In the value set and its semantics, this type is equivalent
+ to the Gauge32 type of the SMIv2.";
+ reference
+ "RFC 2578: Structure of Management Information Version 2
+ (SMIv2)";
+ }
+
+ typedef gauge64 {
+ type uint64;
+ description
+ "The gauge64 type represents a non-negative integer, which
+ may increase or decrease, but shall never exceed a maximum
+ value, nor fall below a minimum value. The maximum value
+ cannot be greater than 2^64-1 (18446744073709551615), and
+ the minimum value cannot be smaller than 0. The value of
+ a gauge64 has its maximum value whenever the information
+ being modeled is greater than or equal to its maximum
+ value, and has its minimum value whenever the information
+ being modeled is smaller than or equal to its minimum value.
+ If the information being modeled subsequently decreases
+ below (increases above) the maximum (minimum) value, the
+ gauge64 also decreases (increases).
+
+ In the value set and its semantics, this type is equivalent
+ to the CounterBasedGauge64 SMIv2 textual convention defined
+ in RFC 2856";
+ reference
+ "RFC 2856: Textual Conventions for Additional High Capacity
+ Data Types";
+ }
+
+ /*** collection of identifier-related types ***/
+
+ typedef object-identifier {
+ type string {
+ pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+ + '(\.(0|([1-9]\d*)))*';
+ }
+ description
+ "The object-identifier type represents administratively
+ assigned names in a registration-hierarchical-name tree.
+
+ Values of this type are denoted as a sequence of numerical
+ non-negative sub-identifier values. Each sub-identifier
+ value MUST NOT exceed 2^32-1 (4294967295). Sub-identifiers
+ are separated by single dots and without any intermediate
+ whitespace.
+
+ The ASN.1 standard restricts the value space of the first
+ sub-identifier to 0, 1, or 2. Furthermore, the value space
+ of the second sub-identifier is restricted to the range
+ 0 to 39 if the first sub-identifier is 0 or 1. Finally,
+ the ASN.1 standard requires that an object identifier
+ has always at least two sub-identifiers. The pattern
+ captures these restrictions.
+
+ Although the number of sub-identifiers is not limited,
+ module designers should realize that there may be
+ implementations that stick with the SMIv2 limit of 128
+ sub-identifiers.
+
+ This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+ since it is not restricted to 128 sub-identifiers. Hence,
+ this type SHOULD NOT be used to represent the SMIv2 OBJECT
+ IDENTIFIER type; the object-identifier-128 type SHOULD be
+ used instead.";
+ reference
+ "ISO9834-1: Information technology -- Open Systems
+ Interconnection -- Procedures for the operation of OSI
+ Registration Authorities: General procedures and top
+ arcs of the ASN.1 Object Identifier tree";
+ }
+
+ typedef object-identifier-128 {
+ type object-identifier {
+ pattern '\d*(\.\d*){1,127}';
+ }
+ description
+ "This type represents object-identifiers restricted to 128
+ sub-identifiers.
+
+ In the value set and its semantics, this type is equivalent
+ to the OBJECT IDENTIFIER type of the SMIv2.";
+ reference
+ "RFC 2578: Structure of Management Information Version 2
+ (SMIv2)";
+ }
+
+ typedef yang-identifier {
+ type string {
+ length "1..max";
+ pattern '[a-zA-Z_][a-zA-Z0-9\-_.]*';
+ pattern '.|..|[^xX].*|.[^mM].*|..[^lL].*';
+ }
+ description
+ "A YANG identifier string as defined by the 'identifier'
+ rule in Section 12 of RFC 6020. An identifier must
+ start with an alphabetic character or an underscore
+ followed by an arbitrary sequence of alphabetic or
+ numeric characters, underscores, hyphens, or dots.
+
+ A YANG identifier MUST NOT start with any possible
+ combination of the lowercase or uppercase character
+ sequence 'xml'.";
+ reference
+ "RFC 6020: YANG - A Data Modeling Language for the Network
+ Configuration Protocol (NETCONF)";
+ }
+
+ /*** collection of types related to date and time***/
+
+ typedef date-and-time {
+ type string {
+ pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+ + '(Z|[\+\-]\d{2}:\d{2})';
+ }
+ description
+ "The date-and-time type is a profile of the ISO 8601
+ standard for representation of dates and times using the
+ Gregorian calendar. The profile is defined by the
+ date-time production in Section 5.6 of RFC 3339.
+
+ The date-and-time type is compatible with the dateTime XML
+ schema type with the following notable exceptions:
+
+ (a) The date-and-time type does not allow negative years.
+
+ (b) The date-and-time time-offset -00:00 indicates an unknown
+ time zone (see RFC 3339) while -00:00 and +00:00 and Z
+ all represent the same time zone in dateTime.
+
+ (c) The canonical format (see below) of data-and-time values
+ differs from the canonical format used by the dateTime XML
+ schema type, which requires all times to be in UTC using
+ the time-offset 'Z'.
+
+ This type is not equivalent to the DateAndTime textual
+ convention of the SMIv2 since RFC 3339 uses a different
+ separator between full-date and full-time and provides
+ higher resolution of time-secfrac.
+
+ The canonical format for date-and-time values with a known time
+ zone uses a numeric time zone offset that is calculated using
+ the device's configured known offset to UTC time. A change of
+ the device's offset to UTC time will cause date-and-time values
+ to change accordingly. Such changes might happen periodically
+ in case a server follows automatically daylight saving time
+ (DST) time zone offset changes. The canonical format for
+ date-and-time values with an unknown time zone (usually
+ referring to the notion of local time) uses the time-offset
+ -00:00.";
+ reference
+ "RFC 3339: Date and Time on the Internet: Timestamps
+ RFC 2579: Textual Conventions for SMIv2
+ XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+ }
+
+ typedef timeticks {
+ type uint32;
+ description
+ "The timeticks type represents a non-negative integer that
+ represents the time, modulo 2^32 (4294967296 decimal), in
+ hundredths of a second between two epochs. When a schema
+ node is defined that uses this type, the description of
+ the schema node identifies both of the reference epochs.
+
+ In the value set and its semantics, this type is equivalent
+ to the TimeTicks type of the SMIv2.";
+ reference
+ "RFC 2578: Structure of Management Information Version 2
+ (SMIv2)";
+ }
+
+ typedef timestamp {
+ type yang:timeticks;
+ description
+ "The timestamp type represents the value of an associated
+ timeticks schema node at which a specific occurrence
+ happened. The specific occurrence must be defined in the
+ description of any schema node defined using this type. When
+ the specific occurrence occurred prior to the last time the
+ associated timeticks attribute was zero, then the timestamp
+ value is zero. Note that this requires all timestamp values
+ to be reset to zero when the value of the associated timeticks
+ attribute reaches 497+ days and wraps around to zero.
+
+ The associated timeticks schema node must be specified
+ in the description of any schema node using this type.
+
+ In the value set and its semantics, this type is equivalent
+ to the TimeStamp textual convention of the SMIv2.";
+ reference
+ "RFC 2579: Textual Conventions for SMIv2";
+ }
+
+ /*** collection of generic address types ***/
+
+ typedef phys-address {
+ type string {
+ pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+ }
+
+ description
+ "Represents media- or physical-level addresses represented
+ as a sequence octets, each octet represented by two hexadecimal
+ numbers. Octets are separated by colons. The canonical
+ representation uses lowercase characters.
+
+ In the value set and its semantics, this type is equivalent
+ to the PhysAddress textual convention of the SMIv2.";
+ reference
+ "RFC 2579: Textual Conventions for SMIv2";
+ }
+
+ typedef mac-address {
+ type string {
+ pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+ }
+ description
+ "The mac-address type represents an IEEE 802 MAC address.
+ The canonical representation uses lowercase characters.
+
+ In the value set and its semantics, this type is equivalent
+ to the MacAddress textual convention of the SMIv2.";
+ reference
+ "IEEE 802: IEEE Standard for Local and Metropolitan Area
+ Networks: Overview and Architecture
+ RFC 2579: Textual Conventions for SMIv2";
+ }
+
+ /*** collection of XML-specific types ***/
+
+ typedef xpath1.0 {
+ type string;
+ description
+ "This type represents an XPATH 1.0 expression.
+
+ When a schema node is defined that uses this type, the
+ description of the schema node MUST specify the XPath
+ context in which the XPath expression is evaluated.";
+ reference
+ "XPATH: XML Path Language (XPath) Version 1.0";
+ }
+
+ /*** collection of string types ***/
+
+ typedef hex-string {
+ type string {
+ pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+ }
+ description
+ "A hexadecimal string with octets represented as hex digits
+ separated by colons. The canonical representation uses
+ lowercase characters.";
+ }
+
+ typedef uuid {
+ type string {
+ pattern '[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-'
+ + '[0-9a-fA-F]{4}-[0-9a-fA-F]{12}';
+ }
+ description
+ "A Universally Unique IDentifier in the string representation
+ defined in RFC 4122. The canonical representation uses
+ lowercase characters.
+
+ The following is an example of a UUID in string representation:
+ f81d4fae-7dec-11d0-a765-00a0c91e6bf6
+ ";
+ reference
+ "RFC 4122: A Universally Unique IDentifier (UUID) URN
+ Namespace";
+ }
+
+ typedef dotted-quad {
+ type string {
+ pattern
+ '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+ + '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])';
+ }
+ description
+ "An unsigned 32-bit number expressed in the dotted-quad
+ notation, i.e., four octets written as decimal numbers
+ and separated with the '.' (full stop) character.";
+ }
+}
diff --git a/models/yang/sonic/common/sonic-common.yang b/models/yang/sonic/common/sonic-common.yang
new file mode 100644
index 0000000000..77a81c5f84
--- /dev/null
+++ b/models/yang/sonic/common/sonic-common.yang
@@ -0,0 +1,41 @@
+
+module sonic-common {
+ namespace "http://github.com/Azure/sonic-common";
+ prefix scommon;
+
+ organization
+ "SONiC";
+
+ contact
+ "SONiC";
+
+ description
+ "SONIC VLAN";
+
+ revision 2019-05-15 {
+ description
+ "Initial revision.";
+ }
+
+ typedef tagging_mode {
+ type enumeration {
+ enum untagged;
+ enum tagged;
+ enum priority_tagged;
+ }
+ }
+
+ typedef admin-status {
+ type enumeration {
+ enum up;
+ enum down;
+ }
+ }
+
+
+ container operation {
+ leaf operation {
+ type string;
+ }
+ }
+}
diff --git a/src/cvl/schema/sonic-common.yang b/models/yang/sonic/common/sonic-extension.yang
similarity index 61%
rename from src/cvl/schema/sonic-common.yang
rename to models/yang/sonic/common/sonic-extension.yang
index 329d40c537..f488809586 100644
--- a/src/cvl/schema/sonic-common.yang
+++ b/models/yang/sonic/common/sonic-extension.yang
@@ -1,11 +1,7 @@
-module sonic-common {
- namespace "http://github.com/Azure/sonic-common";
- prefix sv;
-
- import ietf-yang-types {
- prefix yang;
- }
+module sonic-extension {
+ namespace "http://github.com/Azure/sonic-extension";
+ prefix sonic-ext;
organization
"SONiC";
@@ -14,28 +10,13 @@ module sonic-common {
"SONiC";
description
- "SONIC VLAN";
+ "SONIC Extension";
- revision 2019-05-15 {
+ revision 2019-09-18 {
description
"Initial revision.";
}
- typedef tagging_mode {
- type enumeration {
- enum untagged;
- enum tagged;
- enum priority_tagged;
- }
- }
-
- typedef admin-status {
- type enumeration {
- enum up;
- enum down;
- }
- }
-
extension custom-handler {
description
"Node should be handled by custom handler";
@@ -63,13 +44,13 @@ module sonic-common {
extension map-list {
description
"If it is a map list";
- argument "value";
+ argument "value";
}
extension map-leaf {
description
"Map leaf names";
- argument "value";
+ argument "value";
}
extension pf-check {
@@ -77,10 +58,4 @@ module sonic-common {
"Platform specific validation";
argument "handler";
}
-
- container operation {
- leaf operation {
- type string;
- }
- }
}
diff --git a/models/yang/sonic/sonic-acl.yang b/models/yang/sonic/sonic-acl.yang
new file mode 100644
index 0000000000..6c57edcbba
--- /dev/null
+++ b/models/yang/sonic/sonic-acl.yang
@@ -0,0 +1,221 @@
+module sonic-acl {
+ namespace "http://github.com/Azure/sonic-acl";
+ prefix sacl;
+ yang-version 1.1;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ import sonic-common {
+ prefix cmn;
+ }
+
+ import sonic-port {
+ prefix prt;
+ }
+
+ import sonic-mirror-session {
+ prefix sms;
+ }
+
+ organization
+ "SONiC";
+
+ contact
+ "SONiC";
+
+ description
+ "SONIC ACL";
+
+ revision 2019-05-15 {
+ description
+ "Initial revision.";
+ }
+
+ container sonic-acl {
+
+ container ACL_TABLE {
+
+ list ACL_TABLE_LIST {
+ key "aclname";
+
+ leaf aclname {
+ type string {
+ pattern '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,71})';
+ length 1..72;
+ }
+ }
+
+ 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 leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
+ }
+ }
+ }
+
+ container ACL_RULE {
+
+ list ACL_RULE_LIST {
+ key "aclname rulename";
+
+ leaf aclname {
+ type leafref {
+ path "../../../ACL_TABLE/ACL_TABLE_LIST/aclname";
+ }
+ must "(/cmn:operation/cmn:operation != 'DELETE') or " +
+ "count(current()/../../../ACL_TABLE/ACL_TABLE_LIST[aclname=current()]/ports) = 0" {
+ error-message "Ports are already bound to this rule.";
+ }
+ }
+
+ leaf rulename {
+ 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/models/yang/sonic/sonic-interface.yang b/models/yang/sonic/sonic-interface.yang
new file mode 100644
index 0000000000..30f1f02c42
--- /dev/null
+++ b/models/yang/sonic/sonic-interface.yang
@@ -0,0 +1,63 @@
+module sonic-interface {
+ namespace "http://github.com/Azure/sonic-interface";
+ prefix sint;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ import sonic-port {
+ prefix prt;
+ }
+
+ organization
+ "SONiC";
+
+ contact
+ "SONiC";
+
+ description
+ "SONIC INTERFACE";
+
+ revision 2019-07-02 {
+ description
+ "Initial revision.";
+ }
+
+ container sonic-interface {
+
+ container INTERFACE {
+
+ list INTERFACE_LIST {
+ key "portname";
+
+ leaf portname{
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
+ }
+
+ leaf vrf-name {
+ type string;
+ }
+
+ }
+
+ list INTERFACE_IPADDR_LIST {
+ key "portname ip_prefix";
+
+ leaf portname{
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
+ }
+
+ leaf ip_prefix {
+ mandatory true;
+ type inet:ip-prefix;
+
+ }
+ }
+ }
+ }
+}
diff --git a/models/yang/sonic/sonic-mirror-session.yang b/models/yang/sonic/sonic-mirror-session.yang
new file mode 100644
index 0000000000..ff18b5a14a
--- /dev/null
+++ b/models/yang/sonic/sonic-mirror-session.yang
@@ -0,0 +1,60 @@
+module sonic-mirror-session {
+ namespace "http://github.com/Azure/sonic-mirror-session";
+ prefix sms;
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ organization
+ "SONiC";
+
+ contact
+ "SONiC";
+
+ description
+ "SONIC MIRROR SESSION";
+
+ revision 2019-05-15 {
+ description
+ "Initial revision.";
+ }
+
+ container sonic-mirror-session {
+
+ container MIRROR_SESSION {
+
+ list MIRROR_SESSION_LIST {
+ key "name";
+
+ leaf name {
+ type string;
+ }
+
+ leaf src_ip {
+ type inet:ipv4-address;
+ }
+
+ leaf dst_ip {
+ type inet:ipv4-address;
+ }
+
+ leaf gre_type {
+ type string;
+ }
+
+ leaf dscp {
+ type uint8;
+ }
+
+ leaf ttl {
+ type uint8;
+ }
+
+ leaf queue {
+ type uint8;
+ }
+ }
+ }
+ }
+}
diff --git a/models/yang/sonic/sonic-port.yang b/models/yang/sonic/sonic-port.yang
new file mode 100644
index 0000000000..ba0959f3b6
--- /dev/null
+++ b/models/yang/sonic/sonic-port.yang
@@ -0,0 +1,79 @@
+module sonic-port {
+ namespace "http://github.com/Azure/sonic-port";
+ prefix prt;
+
+ import sonic-common {
+ prefix scommon;
+ }
+
+ organization
+ "SONiC";
+
+ contact
+ "SONiC";
+
+ description
+ "SONIC VLAN";
+
+ revision 2019-05-15 {
+ description
+ "Initial revision.";
+ }
+
+
+ container sonic-port {
+
+ container PORT {
+
+ list PORT_LIST {
+ key "ifname";
+
+ leaf ifname {
+ type string {
+ pattern "Ethernet([1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[0-9])" {
+ error-message "Invalid interface name";
+ error-app-tag interface-name-invalid;
+ }
+ }
+ }
+
+ leaf index {
+ type uint16;
+ }
+
+ leaf speed {
+ type uint64;
+ }
+
+ leaf valid_speeds {
+ type string;
+ }
+
+ leaf alias {
+ type string;
+ }
+
+ leaf description {
+ type string;
+ }
+
+ leaf mtu{
+ type uint32 {
+ range "1312..9216" {
+ error-message "Invalid MTU value";
+ error-app-tag mtu-invalid;
+ }
+ }
+ }
+
+ leaf lanes {
+ type string;
+ }
+
+ leaf admin_status {
+ type scommon:admin-status;
+ }
+ }
+ }
+ }
+}
diff --git a/src/cvl/cvl.go b/src/cvl/cvl.go
index 7701372c7f..2b81dbcaac 100644
--- a/src/cvl/cvl.go
+++ b/src/cvl/cvl.go
@@ -70,6 +70,7 @@ var luaScripts map[string]*redis.Script
type modelTableInfo struct {
dbNum uint8
modelName string
+ redisTableName string //To which Redis table it belongs to, used for 1 Redis to N Yang List
module *yparser.YParserModule
keys []string
redisKeyDelim string
@@ -111,8 +112,9 @@ type modelNamespace struct {
}
type modelDataInfo struct {
- modelNs map[string]modelNamespace//model namespace
- tableInfo map[string]modelTableInfo //redis table to model name and keys
+ modelNs map[string]modelNamespace //model namespace
+ tableInfo map[string]*modelTableInfo //redis table to model name and keys
+ redisTableToYangList map[string][]string //Redis table to all YANG lists when it is not 1:1 mapping
allKeyDelims map[string]bool
}
@@ -245,16 +247,26 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
modelInfo.modelNs[modelName] = modelNs
- //Store metadata present in each list
- nodes = xmlquery.Find(root, "//module/container/list")
+ //Store metadata present in each list.
+ //Each list represent one Redis table in general.
+ //However when one Redis table is mapped to multiple
+ //YANG lists need to store the information in redisTableToYangList map
+ nodes = xmlquery.Find(root, "//module/container/container/list")
if (nodes == nil) {
return
}
+ //number list under one table container i.e. ACL_TABLE container
+ //has only one ACL_TABLE_LIST list
for _, node := range nodes {
- //for each list
+ //for each list, remove "_LIST" suffix
tableName := node.Attr[0].Value
+ if (strings.HasSuffix(tableName, "_LIST")) {
+ tableName = tableName[0:len(tableName) - len("_LIST")]
+ }
tableInfo := modelTableInfo{modelName: modelName}
+ //Store Redis table name
+ tableInfo.redisTableName = node.Parent.Attr[0].Value
//Store the reference for list node to be used later
listNode := node
node = node.FirstChild
@@ -263,6 +275,7 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
tableInfo.dbNum = CONFIG_DB
//default delim '|'
tableInfo.redisKeyDelim = "|"
+ modelInfo.allKeyDelims[tableInfo.redisKeyDelim] = true
fieldCount := 0
@@ -309,10 +322,20 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
}
*/
+ //If container has more than one list, it means one Redis table is mapped to
+ //multiple lists, store the info in redisTableToYangList
+ allLists := xmlquery.Find(listNode.Parent, "/list")
+ if len(allLists) > 1 {
+ yangList := modelInfo.redisTableToYangList[tableInfo.redisTableName]
+ yangList = append(yangList, tableName)
+ //Update the map
+ modelInfo.redisTableToYangList[tableInfo.redisTableName] = yangList
+ }
+
leafRefNodes := xmlquery.Find(listNode, "//type[@name='leafref']")
if (leafRefNodes == nil) {
//Store the tableInfo in global data
- modelInfo.tableInfo[tableName] = tableInfo
+ modelInfo.tableInfo[tableName] = &tableInfo
continue
}
@@ -340,11 +363,11 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
}
}
- //Find all 'must' expression and store the agains its parent node
+ //Find all 'must' expression and store the against its parent node
mustExps := xmlquery.Find(listNode, "//must")
if (mustExps == nil) {
//Update the tableInfo in global data
- modelInfo.tableInfo[tableName] = tableInfo
+ modelInfo.tableInfo[tableName] = &tableInfo
continue
}
@@ -368,7 +391,8 @@ func storeModelInfo(modelFile string, module *yparser.YParserModule) { //such mo
}
//Update the tableInfo in global data
- modelInfo.tableInfo[tableName] = tableInfo
+ modelInfo.tableInfo[tableName] = &tableInfo
+
}
}
@@ -453,6 +477,48 @@ func splitRedisKey(key string) (string, string) {
return tblName, key[prefixLen:]
}
+//Get the YANG list name from Redis key
+//This just returns same YANG list name as Redis table name
+//when 1:1 mapping is there. For one Redis table to
+//multiple YANG list, it returns appropriate YANG list name
+//INTERFACE:Ethernet12 returns ==> INTERFACE
+//INTERFACE:Ethernet12:1.1.1.0/32 ==> INTERFACE_IPADDR
+func getRedisKeyToYangList(tableName, key string) string {
+ mapArr, exists := modelInfo.redisTableToYangList[tableName]
+
+ if exists == false {
+ //1:1 mapping case
+ return tableName
+ }
+
+ //As of now determine the mapping based on number of keys
+ var foundIdx int = -1
+ numOfKeys := 1 //Assume only one key initially
+ for keyDelim, _ := range modelInfo.allKeyDelims {
+ foundIdx = strings.Index(key, keyDelim)
+ if (foundIdx >= 0) {
+ //Matched with key delim
+ keyComps := strings.Split(key, keyDelim)
+ numOfKeys = len(keyComps)
+ break
+ }
+ }
+
+ //Check which list has number of keys as 'numOfKeys'
+ for i := 0; i < len(mapArr); i++ {
+ tblInfo, exists := modelInfo.tableInfo[mapArr[i]]
+ if exists == true {
+ if (len(tblInfo.keys) == numOfKeys) {
+ //Found the YANG list matching the number of keys
+ return mapArr[i]
+ }
+ }
+ }
+
+ //No matches
+ return tableName
+}
+
//Convert Redis key to Yang keys, if multiple key components are there,
//they are separated based on Yang schema
func getRedisToYangKeys(tableName string, redisKey string)[]keyValuePairStruct{
@@ -529,9 +595,9 @@ func (c *CVL) checkPathForTableEntry(tableName string, currentValue string, cfgD
//Table name should appear like "../VLAN_MEMBER/tagging_mode' or '
// "/prt:PORT/prt:ifname"
//re := regexp.MustCompile(fmt.Sprintf(".*[/]([a-zA-Z]*:)?%s[\\[/]", tblNameSrch))
- tblSrchIdx := strings.Index(xpath, fmt.Sprintf("/%s", tblNameSrch)) //no preifx
+ tblSrchIdx := strings.Index(xpath, fmt.Sprintf("/%s_LIST", tblNameSrch)) //no preifx
if (tblSrchIdx < 0) {
- tblSrchIdx = strings.Index(xpath, fmt.Sprintf(":%s", tblNameSrch)) //with prefix
+ tblSrchIdx = strings.Index(xpath, fmt.Sprintf(":%s_LIST", tblNameSrch)) //with prefix
}
if (tblSrchIdx < 0) {
continue
@@ -1005,14 +1071,16 @@ func (c *CVL) addLeafRef(config bool, tableName string, name string, value strin
//only key is there, value wil be fetched and stored here,
//if value can't fetched this entry will be deleted that time
- if (c.tmpDbCache[refTableName] == nil) {
- c.tmpDbCache[refTableName] = map[string]interface{}{redisKey: nil}
+ //Strip "_LIST" suffix
+ refRedisTableName := refTableName[0:len(refTableName) - len("_LIST")]
+ if (c.tmpDbCache[refRedisTableName] == nil) {
+ c.tmpDbCache[refRedisTableName] = map[string]interface{}{redisKey: nil}
} else {
- tblMap := c.tmpDbCache[refTableName]
+ tblMap := c.tmpDbCache[refRedisTableName]
_, exist := tblMap.(map[string]interface{})[redisKey]
if (exist == false) {
tblMap.(map[string]interface{})[redisKey] = nil
- c.tmpDbCache[refTableName] = tblMap
+ c.tmpDbCache[refRedisTableName] = tblMap
}
}
}
@@ -1323,13 +1391,26 @@ parent *yparser.YParserNode) CVLRetCode {
func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser.YParserNode, CVLErrorInfo) {
var cvlErrObj CVLErrorInfo
+
tableName := fmt.Sprintf("%s",jsonNode.Data)
c.batchLeaf = ""
+ //Every Redis table is mapped as list within a container,
+ //E.g. ACL_RULE is mapped as
+ // container ACL_RULE { list ACL_RULE_LIST {} }
var topNode *yparser.YParserNode
+
+ // Add top most conatiner e.g. 'container sonic-acl {...}'
+ if _, exists := modelInfo.tableInfo[tableName]; exists == false {
+ return nil, cvlErrObj
+ }
topNode = c.yp.AddChildNode(modelInfo.tableInfo[tableName].module,
nil, modelInfo.tableInfo[tableName].modelName)
+ //Add the container node for each list
+ //e.g. 'container ACL_TABLE { list ACL_TABLE_LIST ...}
+ listConatinerNode := c.yp.AddChildNode(modelInfo.tableInfo[tableName].module,
+ topNode, tableName)
//Traverse each key instance
for jsonNode = jsonNode.FirstChild; jsonNode != nil; jsonNode = jsonNode.NextSibling {
@@ -1337,6 +1418,9 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser.
//For each field check if is key
//If it is key, create list as child of top container
// Get all key name/value pairs
+ if yangListName := getRedisKeyToYangList(tableName, jsonNode.Data); yangListName!= "" {
+ tableName = yangListName
+ }
keyValuePair := getRedisToYangKeys(tableName, jsonNode.Data)
keyCompCount := len(keyValuePair)
totalKeyComb := 1
@@ -1351,9 +1435,12 @@ func (c *CVL) generateTableData(config bool, jsonNode *jsonquery.Node)(*yparser.
}
for ; totalKeyComb > 0 ; totalKeyComb-- {
+ //Get the YANG list name from Redis table name
+ //Ideally they are same except when one Redis table is split
+ //into multiple YANG lists
//Add table i.e. create list element
- listNode := c.addChildNode(tableName, topNode, tableName) //Add the list to the top node
+ listNode := c.addChildNode(tableName, listConatinerNode, tableName + "_LIST") //Add the list to the top node
//For each key combination
//Add keys as leaf to the list
diff --git a/src/cvl/cvl_api.go b/src/cvl/cvl_api.go
index 83b6842519..faac5b3481 100644
--- a/src/cvl/cvl_api.go
+++ b/src/cvl/cvl_api.go
@@ -123,8 +123,9 @@ func Initialize() CVLRetCode {
yparser.Initialize()
modelInfo.modelNs = make(map[string]modelNamespace) //redis table to model name
- modelInfo.tableInfo = make(map[string]modelTableInfo) //model namespace
+ modelInfo.tableInfo = make(map[string]*modelTableInfo) //model namespace
modelInfo.allKeyDelims = make(map[string]bool) //all key delimiter
+ modelInfo.redisTableToYangList = make(map[string][]string) //Redis table to Yang list map
dbNameToDbNum = map[string]uint8{"APPL_DB": APPL_DB, "CONFIG_DB": CONFIG_DB}
/* schema */
diff --git a/src/cvl/internal/yparser/yparser.go b/src/cvl/internal/yparser/yparser.go
index 59d8e87c92..0277088d62 100644
--- a/src/cvl/internal/yparser/yparser.go
+++ b/src/cvl/internal/yparser/yparser.go
@@ -95,15 +95,15 @@ int lyd_data_validate_all(const char *data, const char *depData, const char *oth
int lyd_multi_new_leaf(struct lyd_node *parent, const struct lys_module *module, const char *leafVal)
{
char s[4048];
- char *name, *val;
+ char *name, *val, *saveptr;
strcpy(s, leafVal);
- name = strtok(s, "#");
+ name = strtok_r(s, "#", &saveptr);
while (name != NULL)
{
- val = strtok(NULL, "#");
+ val = strtok_r(NULL, "#", &saveptr);
if (val != NULL)
{
if (NULL == lyd_new_leaf(parent, module, name, val))
@@ -112,7 +112,7 @@ int lyd_multi_new_leaf(struct lyd_node *parent, const struct lys_module *module,
}
}
- name = strtok(NULL, "#");
+ name = strtok_r(NULL, "#", &saveptr);
}
return 0;
diff --git a/src/cvl/schema/Makefile b/src/cvl/schema/Makefile
index f5f970c264..8f1276b68b 100644
--- a/src/cvl/schema/Makefile
+++ b/src/cvl/schema/Makefile
@@ -17,77 +17,47 @@
# #
################################################################################
-TOPDIR := ../../..
-CVL_YANGAPI_DIR := $(TOPDIR)/build/yaml
-CVL_YANGDIR := $(TOPDIR)/src/cvl/schema
-CVL_YANGDIR_COMMON := $(TOPDIR)/src/cvl/schema/ietf
-CVL_YANG_MOD_FILES := $(shell find $(CVL_YANGDIR) -maxdepth 1 -name '*.yang' | sort)
-CVL_YANG_COMMON_FILES := $(shell find $(CVL_YANGDIR_COMMON) -name '*.yang' | sort)
+sonic_yang=../../../models/yang/sonic
+sonic_yang_common=../../../models/yang/sonic/common
+pyang_plugin_dir=../../../tools/pyang/pyang_plugins
-CVL_TOOLS_DIR := $(TOPDIR)/tools
-CVL_PYANG_DIR := $(CVL_TOOLS_DIR)/pyang
-CVL_PYANG_PLUGIN_DIR := $(CVL_PYANG_DIR)/pyang_plugins
-CVL_PYANG_BIN := pyang
-
-src_files=$(wildcard *.yang)
-out=$(patsubst %.yang, %.yin, $(src_files))
-out_ext=$(patsubst %.yang, %.tree, $(src_files))
+src_files=$(wildcard $(sonic_yang)/*.yang)
+src_files += $(wildcard $(sonic_yang_common)/*.yang)
+out=$(patsubst %.yang, %.yin, $(shell ls -1 $(sonic_yang)/*.yang | cut -d'/' -f7))
+out_common=$(patsubst %.yang, %.yin, $(shell ls -1 $(sonic_yang_common)/*.yang | cut -d'/' -f8))
+out_tree=$(patsubst %.yang, %.tree, $(src_files))
+search_path=$(sonic_yang):$(sonic_yang_common):$(sonic_yang_common)/ietf
all: yamlGen allyangs.tree allyangs_tree.html schema
-schema: $(out)
-
-#yamlGen: $(CVL_YANGAPI_DIR)/.done
+schema: $(out) $(out_common)
-%.yin:%.yang
- @echo "Generating $@ ..."
- @devFile="`echo $< | cut -d . -f1`-dev.yang"; \
- if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \
- pyang -p ./ietf/ -f yin $$devOpt $< -o $@.tmp
- @xmllint --noblanks $@.tmp > $@
- @rm -rf $@.tmp
-allyangs.tree: $(CVL_YANG_MOD_FILES) $(CVL_YANG_COMMON_FILES)
- $(CVL_PYANG_BIN) \
- -f tree \
- -o $(CVL_YANGDIR)/$@ \
- -p $(CVL_YANGDIR_COMMON):$(CVL_YANGDIR) \
- $(CVL_YANG_MOD_FILES)
- @echo "+++++ Generation of YANG tree for Sonic Yang modules completed +++++"
+schema-tree: $(out_tree)
-allyangs_tree.html: $(CVL_YANG_MOD_FILES) $(CVL_YANG_COMMON_FILES)
- $(CVL_PYANG_BIN) \
- -f jstree \
- -o $(CVL_YANGDIR)/$@ \
- -p $(CVL_YANGDIR_COMMON):$(CVL_YANGDIR) \
- $(CVL_YANG_MOD_FILES)
- @echo "+++++ Generation of HTML tree for Sonic Yang modules completed +++++"
+#Build YANG models
+%.yin:$(sonic_yang)/%.yang
+ @echo "Generating `basename $@` ..."
+ @devFile="`echo $@ | cut -d . -f1`-deviation.yang"; \
+ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \
+ pyang -p $(search_path) --plugindir $(pyang_plugin_dir) \
+ -f yin-cvl $$devOpt $< -o `basename $@`
-#======================================================================
-# Generate YAML files for Sonic Yang modules
-#======================================================================
-yamlGen:
- @echo "+++++ Generating YAML files for Sonic Yang modules +++++"
- mkdir -p $(CVL_YANGAPI_DIR)
- $(CVL_PYANG_BIN) \
- -f swaggerapi \
- --outdir $(CVL_YANGAPI_DIR) \
- --plugindir $(CVL_PYANG_PLUGIN_DIR) \
- -p $(CVL_YANGDIR_COMMON):$(CVL_YANGDIR) \
- $(CVL_YANG_MOD_FILES)
- @echo "+++++ Generation of YAML files for Sonic Yang modules completed +++++"
- # touch $@
+#Build common YANG models
+%.yin:$(sonic_yang_common)/%.yang
+ @echo "Generating `basename $@` ..."
+ @devFile="`echo $@ | cut -d . -f1`-deviation.yang"; \
+ if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \
+ pyang -p $(search_path) --plugindir $(pyang_plugin_dir) \
+ -f yin-cvl $$devOpt $< -o `basename $@`
%.tree:%.yang
- @echo "Generating $@ ..."
+ @echo "Generating `basename $@` ..."
@devFile="`echo $< | cut -d . -f1`-dev.yang"; \
if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \
- pyang -p ./ietf/ -f tree $$devOpt $< -o $@
+ pyang -p $(search_path) -f tree $$devOpt $< -o `basename $@`
clean:
@echo "Removing files ..."
- rm -rf $(out)
- rm -rf $(out_ext)
- rm -rf $(CVL_YANGAPI_DIR)
- rm -rf allyangs.tree allyangs_tree.html
+ rm -rf *.yin *.tree
diff --git a/src/cvl/schema/sonic-acl.yang b/src/cvl/schema/sonic-acl.yang
deleted file mode 100644
index fc65e5ac4a..0000000000
--- a/src/cvl/schema/sonic-acl.yang
+++ /dev/null
@@ -1,220 +0,0 @@
-module sonic-acl {
- namespace "http://github.com/Azure/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-mirror-session {
- prefix sms;
- }
-
- organization
- "SONiC";
-
- contact
- "SONiC";
-
- description
- "SONIC ACL";
-
- revision 2019-05-15 {
- description
- "Initial revision.";
- }
-
- container sonic-acl {
-
- list ACL_TABLE {
- key "aclname";
-
-
- leaf aclname {
- type string {
- pattern '[a-zA-Z0-9]{1}([-a-zA-Z0-9_]{0,71})';
- length 1..72;
- }
- }
-
- 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 leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
- }
- }
- }
-
- list ACL_RULE {
- key "aclname rulename";
-
- leaf aclname {
- type leafref {
- path "../../ACL_TABLE/aclname";
- }
- must "(/scommon:operation/scommon:operation != 'DELETE') or " +
- "count(current()/../../ACL_TABLE[aclname=current()]/ports) = 0" {
- error-message "Ports are already bound to this rule.";
- }
- }
-
- leaf rulename {
- 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: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/cvl/schema/sonic-interface.yang b/src/cvl/schema/sonic-interface.yang
deleted file mode 100644
index 540b3a16b8..0000000000
--- a/src/cvl/schema/sonic-interface.yang
+++ /dev/null
@@ -1,52 +0,0 @@
-module sonic-interface {
- namespace "http://github.com/Azure/sonic-interface";
- prefix sint;
-
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
- import sonic-port {
- prefix prt;
- }
-
- organization
- "SONiC";
-
- contact
- "SONiC";
-
- description
- "SONIC INTERFACE";
-
- revision 2019-07-02 {
- description
- "Initial revision.";
- }
-
- container sonic-interface {
- list INTERFACE {
- key "portname ip_prefix";
-
- leaf portname{
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
- }
- }
-
- leaf ip_prefix {
- mandatory true;
- type inet:ip-prefix;
-
- }
- }
- }
-}
diff --git a/src/cvl/schema/sonic-mirror-session.yang b/src/cvl/schema/sonic-mirror-session.yang
deleted file mode 100644
index 1a2591cc0c..0000000000
--- a/src/cvl/schema/sonic-mirror-session.yang
+++ /dev/null
@@ -1,65 +0,0 @@
-module sonic-mirror-session {
- namespace "http://github.com/Azure/sonic-mirror-session";
- prefix sms;
-
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
- organization
- "SONiC";
-
- contact
- "SONiC";
-
- description
- "SONIC MIRROR SESSION";
-
- revision 2019-05-15 {
- description
- "Initial revision.";
- }
-
- container sonic-mirror-session {
-
- list MIRROR_SESSION {
- key "name";
-
- leaf name {
- type string;
- }
-
- leaf src_ip {
- type inet:ipv4-address;
- }
-
- leaf dst_ip {
- type inet:ipv4-address;
- }
-
- leaf gre_type {
- type string;
- }
-
- leaf dscp {
- type uint8;
- }
-
- leaf ttl {
- type uint8;
- }
-
- leaf queue {
- type uint8;
- }
- }
- }
-}
diff --git a/src/cvl/schema/sonic-port.yang b/src/cvl/schema/sonic-port.yang
deleted file mode 100644
index 3d99d0534f..0000000000
--- a/src/cvl/schema/sonic-port.yang
+++ /dev/null
@@ -1,79 +0,0 @@
-module sonic-port {
- namespace "http://github.com/Azure/sonic-port";
- prefix prt;
-
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
- organization
- "SONiC";
-
- contact
- "SONiC";
-
- description
- "SONIC VLAN";
-
- revision 2019-05-15 {
- description
- "Initial revision.";
- }
-
-
- container sonic-port {
- list PORT {
- key "ifname";
-
- leaf ifname {
- type string {
- pattern "Ethernet([1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[0-9])"{
- error-message "Invalid interface name";
- error-app-tag interface-name-invalid;
- }
- }
- }
-
- leaf index {
- type uint16;
- }
-
- leaf speed {
- type uint64;
- }
-
- leaf valid_speeds {
- type string;
- }
-
- leaf alias {
- type string;
- }
-
- leaf description {
- type string;
- }
-
- leaf mtu{
- type uint32 {
- range "1312..9216" {
- error-message "Invalid MTU value";
- error-app-tag mtu-invalid;
- }
- }
- }
-
- leaf lanes {
- type string;
- }
-
- leaf admin_status {
- type scommon:admin-status;
- }
- }
- }
-}
diff --git a/src/cvl/testdata/schema/Makefile b/src/cvl/testdata/schema/Makefile
index 308b3eaf6b..43fee356bf 100644
--- a/src/cvl/testdata/schema/Makefile
+++ b/src/cvl/testdata/schema/Makefile
@@ -17,6 +17,8 @@
# #
################################################################################
+sonic_yang=../../../../models/yang/sonic
+pyang_plugin_dir=../../../../tools/pyang/pyang_plugins
src_files=$(wildcard *.yang)
out=$(patsubst %.yang, %.yin, $(src_files))
out_ext=$(patsubst %.yang, %.tree, $(src_files))
@@ -25,20 +27,22 @@ all:schema
schema: $(out)
+schema-tree: $(out_ext)
+
%.yin:%.yang
- @echo "Generating $@ ..."
+ @echo "Generating `basename $@` ..."
@devFile="`echo $< | cut -d . -f1`-dev.yang"; \
if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \
- pyang -p ../../schema/:../../schema/ietf/ -f yin $$devOpt $< -o $@.tmp
- @xmllint --noblanks $@.tmp > $@
- @rm -rf $@.tmp
+ pyang -p $(sonic_yang):$(sonic_yang)/common:$(sonic_yang)/common/ietf \
+ --plugindir $(pyang_plugin_dir) -f yin-cvl $$devOpt $< -o `basename $@`
%.tree:%.yang
- @echo "Generating $@ ..."
+ @echo "Generating `basename $@` ..."
@devFile="`echo $< | cut -d . -f1`-dev.yang"; \
if [ -f $$devFile ] ; then devOpt="--deviation-module $$devFile"; fi; \
- pyang -p ../../schema/:../../schema/ietf/ -f tree $$devOpt $< -o $@
+ pyang -p $(sonic_yang):$(sonic_yang)/common:$(sonic_yang)/common/ietf \
+ -f tree $$devOpt $< -o `basename $@`
clean:
@echo "Removing files ..."
- rm -rf *.yin
+ rm -rf *.yin *.tree
diff --git a/src/cvl/testdata/schema/sonic-acl-dev.yang b/src/cvl/testdata/schema/sonic-acl-deviation.yang
similarity index 71%
rename from src/cvl/testdata/schema/sonic-acl-dev.yang
rename to src/cvl/testdata/schema/sonic-acl-deviation.yang
index 7fcf99f931..c1d701c29d 100644
--- a/src/cvl/testdata/schema/sonic-acl-dev.yang
+++ b/src/cvl/testdata/schema/sonic-acl-deviation.yang
@@ -1,25 +1,12 @@
-module sonic-acl-dev {
- namespace "http://github.com/Azure/sonic-acl-dev";
+module sonic-acl-deviation {
+ namespace "http://github.com/Azure/sonic-acl-deviation";
prefix acld;
yang-version 1.1;
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
import sonic-acl {
prefix sacl;
}
- import sonic-common {
- prefix scommon;
- }
-
-
organization
"SONiC";
diff --git a/src/cvl/testdata/schema/sonic-bgp-neighbor.yang b/src/cvl/testdata/schema/sonic-bgp-neighbor.yang
index 2264e5238e..14504d6f9b 100644
--- a/src/cvl/testdata/schema/sonic-bgp-neighbor.yang
+++ b/src/cvl/testdata/schema/sonic-bgp-neighbor.yang
@@ -2,22 +2,14 @@ module sonic-bgp-neighbor {
namespace "http://github.com/Azure/sonic-bgp-neighbor";
prefix sbn;
- import ietf-yang-types {
- prefix yang;
- }
-
import ietf-inet-types {
- prefix inet;
- }
+ prefix inet;
+ }
import sonic-common {
prefix scommon;
}
- import sonic-port {
- prefix prt;
- }
-
organization
"SONiC";
@@ -33,54 +25,58 @@ module sonic-bgp-neighbor {
}
container sonic-bgp-neighbor {
- list BGP_NEIGHBOR {
- key "ipaddress";
- leaf ipaddress{
- type inet:ip-address;
- }
+ container BGP_NEIGHBOR {
- leaf rrclient {
- type uint8 {
- range "0..255";
+ list BGP_NEIGHBOR_LIST {
+ key "ipaddress";
+
+ leaf ipaddress{
+ type inet:ip-address;
}
- }
- leaf admin_status{
- type scommon:admin-status;
- }
+ leaf rrclient {
+ type uint8 {
+ range "0..255";
+ }
+ }
- leaf peer_addr{
- type inet:ip-address;
- }
+ leaf admin_status{
+ type scommon:admin-status;
+ }
- leaf name {
- type string;
- }
+ leaf peer_addr{
+ type inet:ip-address;
+ }
- leaf local_addr {
- type inet:ipv4-address;
- }
+ leaf name {
+ type string;
+ }
- leaf nhopself {
- type uint8 {
- range "0..255";
+ leaf local_addr {
+ type inet:ipv4-address;
}
- }
- leaf holdtime {
- type uint8 {
- range "0..255";
+ leaf nhopself {
+ type uint8 {
+ range "0..255";
+ }
}
- }
- leaf asn {
- type uint64;
- }
+ leaf holdtime {
+ type uint8 {
+ range "0..255";
+ }
+ }
+
+ leaf asn {
+ type uint64;
+ }
- leaf keepalive {
- type uint8 {
- range "0..255";
+ leaf keepalive {
+ type uint8 {
+ range "0..255";
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-buffer-pg.yang b/src/cvl/testdata/schema/sonic-buffer-pg.yang
index 61b5013fed..27918081e8 100644
--- a/src/cvl/testdata/schema/sonic-buffer-pg.yang
+++ b/src/cvl/testdata/schema/sonic-buffer-pg.yang
@@ -2,16 +2,8 @@ module sonic-buffer-pg {
namespace "http://github.com/Azure/sonic-buffer-pg";
prefix bpg;
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
import sonic-port {
@@ -38,32 +30,37 @@ module sonic-buffer-pg {
container sonic-buffer-pg {
- list BUFFER_PG {
- key "ifname pg_num";
- scommon:key-pattern "BUFFER_PG|({ifname},)*|{pg_num}"; //special pattern used for extracting keys from redis-key and fill populate the yang instance
- // Total list instance = number(key1) * number(key2) * number(key3)
- leaf ifname {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
+ container BUFFER_PG {
+
+ list BUFFER_PG_LIST {
+ key "ifname pg_num";
+ sonic-ext:key-pattern "BUFFER_PG|({ifname},)*|{pg_num}"; //special pattern used for extracting keys from
+ //redis-key and fill populate the yang instance
+ // Total list instance = number(key1) * number(key2) * number(key3)
+
+ leaf ifname {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
}
- }
- leaf pg_num {
- type string {
- pattern "[0-7]((-)[0-7])?"{
- error-message "Invalid Buffer PG number";
- error-app-tag pg-num-invalid;
+ leaf pg_num {
+ type string {
+ pattern "[0-7]((-)[0-7])?" {
+ error-message "Invalid Buffer PG number";
+ error-app-tag pg-num-invalid;
+ }
}
}
- }
- leaf profile { //Hash reference key
- type leafref {
- path "/bpf:sonic-buffer-profile/bpf:BUFFER_PROFILE/bpf:name";
+ leaf profile { //Hash reference key
+ type leafref {
+ path "/bpf:sonic-buffer-profile/bpf:BUFFER_PROFILE/bpf:BUFFER_PROFILE_LIST/bpf:name";
+ }
}
- }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-buffer-pool.yang b/src/cvl/testdata/schema/sonic-buffer-pool.yang
index 130c28287f..5f935b3f94 100644
--- a/src/cvl/testdata/schema/sonic-buffer-pool.yang
+++ b/src/cvl/testdata/schema/sonic-buffer-pool.yang
@@ -2,18 +2,6 @@ module sonic-buffer-pool {
namespace "http://github.com/Azure/sonic-buffer-pool";
prefix bpl;
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
organization
"SONiC";
@@ -30,31 +18,34 @@ module sonic-buffer-pool {
container sonic-buffer-pool {
- list BUFFER_POOL {
- key "name";
+ container BUFFER_POOL {
- leaf name {
- type string;
- }
+ list BUFFER_POOL_LIST {
+ key "name";
- leaf type {
- type enumeration {
- enum ingress;
- enum egress;
+ leaf name {
+ type string;
}
- }
- leaf mode {
- type enumeration {
- enum static;
- enum dynamic;
+ leaf type {
+ type enumeration {
+ enum ingress;
+ enum egress;
+ }
}
- }
- leaf size {
- type uint64;
- }
+ leaf mode {
+ type enumeration {
+ enum static;
+ enum dynamic;
+ }
+ }
+ leaf size {
+ type uint64;
+ }
+
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-buffer-profile.yang b/src/cvl/testdata/schema/sonic-buffer-profile.yang
index 895def38c4..71f077654d 100644
--- a/src/cvl/testdata/schema/sonic-buffer-profile.yang
+++ b/src/cvl/testdata/schema/sonic-buffer-profile.yang
@@ -2,18 +2,6 @@ module sonic-buffer-profile {
namespace "http://github.com/Azure/sonic-buffer-profile";
prefix bpf;
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
import sonic-buffer-pool {
prefix bpl;
}
@@ -35,41 +23,44 @@ module sonic-buffer-profile {
container sonic-buffer-profile {
- list BUFFER_PROFILE {
- key "name";
+ container BUFFER_PROFILE {
- leaf name {
- type string;
- }
+ list BUFFER_PROFILE_LIST {
+ key "name";
- leaf static_th {
- type uint64;
- }
+ leaf name {
+ type string;
+ }
- leaf dynamic_th {
- type int64;
- }
+ leaf static_th {
+ type uint64;
+ }
- leaf size {
- type uint64;
- }
+ leaf dynamic_th {
+ type int64;
+ }
- leaf pool {
- type leafref {
- path "/bpl:sonic-buffer-pool/bpl:BUFFER_POOL/bpl:name";
+ leaf size {
+ type uint64;
}
- }
- leaf xon_offset {
- type uint64;
- }
+ leaf pool {
+ type leafref {
+ path "/bpl:sonic-buffer-pool/bpl:BUFFER_POOL/bpl:BUFFER_POOL_LIST/bpl:name";
+ }
+ }
- leaf xon {
- type uint64;
- }
+ leaf xon_offset {
+ type uint64;
+ }
- leaf xoff {
- type uint64;
+ leaf xon {
+ type uint64;
+ }
+
+ leaf xoff {
+ type uint64;
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-cablelength.yang b/src/cvl/testdata/schema/sonic-cablelength.yang
index e4eeed031c..af4746211b 100644
--- a/src/cvl/testdata/schema/sonic-cablelength.yang
+++ b/src/cvl/testdata/schema/sonic-cablelength.yang
@@ -2,16 +2,8 @@ module sonic-cablelength {
namespace "http://github.com/Azure/sonic-cablelength";
prefix scl;
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
import sonic-port {
@@ -33,32 +25,36 @@ module sonic-cablelength {
}
container sonic-cablelength {
- list CABLE_LENGTH {
- key "name";
- scommon:map-list true; //special conversion for map tables
- scommon:map-leaf "port length"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- leaf name {
- type string;
- }
-
- list CABLE_LENGTH { //this is list inside list for storing mapping between two fields
- key "port length";
+ container CABLE_LENGTH {
- leaf port {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
- }
+ list CABLE_LENGTH_LIST {
+ key "name";
+ sonic-ext:map-list true; //special conversion for map tables
+ sonic-ext:map-leaf "port length"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
+ leaf name {
+ type string;
}
- leaf length {
- type string {
- pattern "[0-9]?[0-9]m";
+ list CABLE_LENGTH { //this is list inside list for storing mapping between two fields
+ key "port length";
+
+ leaf port {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
+
+ }
+
+ leaf length {
+ type string {
+ pattern "[0-9]?[0-9]m";
+ }
}
}
- }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-device-metadata.yang b/src/cvl/testdata/schema/sonic-device-metadata.yang
index 0bd953836b..014f88cd47 100644
--- a/src/cvl/testdata/schema/sonic-device-metadata.yang
+++ b/src/cvl/testdata/schema/sonic-device-metadata.yang
@@ -29,64 +29,68 @@ module sonic-device-metadata {
}
container sonic-device-metadata {
- list DEVICE_METADATA {
- key "name";
- leaf name{
- type string;
- }
+ container DEVICE_METADATA {
- leaf hwsku {
- type string;
- }
+ list DEVICE_METADATA_LIST {
+ key "name";
- leaf hostname {
- type string;
- }
+ leaf name{
+ type string;
+ }
- leaf platform {
- type string;
- }
+ leaf hwsku {
+ type string;
+ }
- leaf mac {
- type yang:mac-address;
- }
+ leaf hostname {
+ type string;
+ }
- leaf bgp_asn {
- type leafref {
- path "/sbn:sonic-bgp-neighbor/sbn:BGP_NEIGHBOR/sbn:asn";
+ leaf platform {
+ type string;
}
- }
- leaf default_pfcwd_status {
- type enumeration {
- enum enable;
- enum disable;
- }
- }
+ leaf mac {
+ type yang:mac-address;
+ }
- leaf default_bgp_status {
- type scommon:admin-status;
- }
+ leaf bgp_asn {
+ type leafref {
+ path "/sbn:sonic-bgp-neighbor/sbn:BGP_NEIGHBOR/sbn:BGP_NEIGHBOR_LIST/sbn:asn";
+ }
+ }
- leaf docker_routing_config_mode {
- type enumeration {
- enum unified;
- enum separated;
- }
- }
+ leaf default_pfcwd_status {
+ type enumeration {
+ enum enable;
+ enum disable;
+ }
+ }
- leaf deployment_id {
- type uint8 {
- range "0..255";
+ leaf default_bgp_status {
+ type scommon:admin-status;
}
- }
- leaf type {
- type enumeration {
- enum ToRRouter;
- enum LeafRouter;
- }
+ leaf docker_routing_config_mode {
+ type enumeration {
+ enum unified;
+ enum separated;
+ }
+ }
+
+ leaf deployment_id {
+ type uint8 {
+ range "0..255";
+ }
+ }
+
+ leaf type {
+ type enumeration {
+ enum ToRRouter;
+ enum LeafRouter;
+ }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-device-neighbor.yang b/src/cvl/testdata/schema/sonic-device-neighbor.yang
index 9dc28187ef..a91302ac24 100644
--- a/src/cvl/testdata/schema/sonic-device-neighbor.yang
+++ b/src/cvl/testdata/schema/sonic-device-neighbor.yang
@@ -2,16 +2,8 @@ module sonic-device-neighbor {
namespace "http://github.com/Azure/sonic-device-neighbor";
prefix sdn;
- import ietf-yang-types {
- prefix yang;
- }
-
import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
+ prefix inet;
}
import sonic-port {
@@ -34,42 +26,46 @@ module sonic-device-neighbor {
}
container sonic-device-neighbor {
- list DEVICE_NEIGHBOR {
- key "name";
-
- leaf name{
- type string;
- }
-
- leaf mgmt_addr{
- type inet:ip-address;
- }
-
- leaf hwsku {
- type string;
- }
-
- leaf lo_addr {
- type inet:ip-address;
- }
-
- leaf local_port {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
- }
- }
-
- leaf type {
- type enumeration {
- enum ToRRouter;
- enum LeafRouter;
- }
- }
- leaf port {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
- }
+ container DEVICE_NEIGHBOR {
+
+ list DEVICE_NEIGHBOR_LIST {
+ key "name";
+
+ leaf name{
+ type string;
+ }
+
+ leaf mgmt_addr{
+ type inet:ip-address;
+ }
+
+ leaf hwsku {
+ type string;
+ }
+
+ leaf lo_addr {
+ type inet:ip-address;
+ }
+
+ leaf local_port {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
+ }
+
+ leaf type {
+ type enumeration {
+ enum ToRRouter;
+ enum LeafRouter;
+ }
+ }
+
+ leaf port {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-dscp-tc-map.yang b/src/cvl/testdata/schema/sonic-dscp-tc-map.yang
index 481cfbece0..14dccddd3d 100644
--- a/src/cvl/testdata/schema/sonic-dscp-tc-map.yang
+++ b/src/cvl/testdata/schema/sonic-dscp-tc-map.yang
@@ -2,16 +2,8 @@ module sonic-dscp-tc-map {
namespace "http://github.com/Azure/sonic-dscp-tc-map";
prefix dtm;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
- import sonic-port {
- prefix sif;
+ import sonic-extension {
+ prefix sonic-ext;
}
organization
@@ -29,34 +21,38 @@ module sonic-dscp-tc-map {
}
container sonic-dscp-tc-map {
- list DSCP_TO_TC_MAP {
- key "name";
- scommon:map-list true; //special conversion for map tables
- scommon:map-leaf "dscp tc_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- leaf name {
- type string;
- }
+ container DSCP_TO_TC_MAP {
+
+ list DSCP_TO_TC_MAP_LIST {
+ key "name";
+ sonic-ext:map-list true; //special conversion for map tables
+ sonic-ext:map-leaf "dscp tc_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- list DSCP_TO_TC_MAP { //this is list inside list for storing mapping between two fields
- key "dscp tc_num";
+ leaf name {
+ type string;
+ }
+
+ list DSCP_TO_TC_MAP { //this is list inside list for storing mapping between two fields
+ key "dscp tc_num";
- leaf tc_num {
- type string {
- pattern "[0-9]?"{
- error-message "Invalid Traffic Class number";
- error-app-tag tc-num-invalid;
+ leaf tc_num {
+ type string {
+ pattern "[0-9]?"{
+ error-message "Invalid Traffic Class number";
+ error-app-tag tc-num-invalid;
+ }
}
}
- }
- leaf dscp {
- type string {
- pattern "[1-9][0-9]?|[0-9]?";
+ leaf dscp {
+ type string {
+ pattern "[1-9][0-9]?|[0-9]?";
+ }
}
}
- }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-pf-limits.yang b/src/cvl/testdata/schema/sonic-pf-limits.yang
index 6b92e97dba..658a6e9a8d 100644
--- a/src/cvl/testdata/schema/sonic-pf-limits.yang
+++ b/src/cvl/testdata/schema/sonic-pf-limits.yang
@@ -3,16 +3,8 @@ module sonic-pf-limits {
prefix spf;
yang-version 1.1;
- import ietf-yang-types {
- prefix yang;
- }
-
- import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
organization
@@ -30,7 +22,7 @@ module sonic-pf-limits {
}
container sonic-pf-limits {
- scommon:db-name "APPL_DB";
+ sonic-ext:db-name "APPL_DB";
container acl {
leaf MAX_ACL_RULES {
diff --git a/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang b/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang
index b5c8952e6b..ad51874d69 100644
--- a/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang
+++ b/src/cvl/testdata/schema/sonic-pfc-priority-queue-map.yang
@@ -2,12 +2,8 @@ module sonic-pfc-priority-queue-map {
namespace "http://github.com/Azure/sonic-pfc-priority-queue-map";
prefix ppq;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
organization
@@ -25,31 +21,35 @@ module sonic-pfc-priority-queue-map {
}
container sonic-pfc-priority-queue-map {
- list MAP_PFC_PRIORITY_TO_QUEUE {
- key "name";
- scommon:map-list true; //special conversion for map tables
- scommon:map-leaf "pfc_priority qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- leaf name {
- type string;
- }
+ container MAP_PFC_PRIORITY_TO_QUEUE {
- list MAP_PFC_PRIORITY_TO_QUEUE { //this is list inside list for storing mapping between two fields
- key "pfc_priority qindex";
+ list MAP_PFC_PRIORITY_TO_QUEUE_LIST {
+ key "name";
+ sonic-ext:map-list true; //special conversion for map tables
+ sonic-ext:map-leaf "pfc_priority qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- leaf pfc_priority {
- type string {
- pattern "[0-9]?";
- }
+ leaf name {
+ type string;
}
- leaf qindex {
- type string {
- pattern "[0-9]?";
+ list MAP_PFC_PRIORITY_TO_QUEUE { //this is list inside list for storing mapping between two fields
+ key "pfc_priority qindex";
+
+ leaf pfc_priority {
+ type string {
+ pattern "[0-9]?";
+ }
+ }
+
+ leaf qindex {
+ type string {
+ pattern "[0-9]?";
+ }
}
}
- }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-port-qos-map.yang b/src/cvl/testdata/schema/sonic-port-qos-map.yang
index eeb5ca0bbc..f9785cb46a 100644
--- a/src/cvl/testdata/schema/sonic-port-qos-map.yang
+++ b/src/cvl/testdata/schema/sonic-port-qos-map.yang
@@ -2,12 +2,8 @@ module sonic-port-qos-map {
namespace "http://github.com/Azure/sonic-port-qos-map";
prefix pqm;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
import sonic-port {
@@ -48,24 +44,24 @@ module sonic-port-qos-map {
list PORT_QOS_MAP {
key "ifname";
- scommon:key-pattern "PORT_QOS_MAP|({ifname},)*"; //special pattern used for extracting keys from redis-key and fill populate the yang instance
+ sonic-ext:key-pattern "PORT_QOS_MAP|({ifname},)*"; //special pattern used for extracting keys from redis-key and fill populate the yang instance
// Total list instance = number(key1) * number(key2) * number(key3)
leaf ifname {
type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
}
}
leaf tc_to_pg_map {
type leafref {
- path "/tpg:sonic-tc-priority-group-map/tpg:TC_TO_PRIORITY_GROUP_MAP/tpg:name";
+ path "/tpg:sonic-tc-priority-group-map/tpg:TC_TO_PRIORITY_GROUP_MAP/tpg:TC_TO_PRIORITY_GROUP_MAP_LIST/tpg:name";
}
}
leaf tc_to_queue_map {
type leafref {
- path "/tqm:sonic-tc-queue-map/tqm:TC_TO_QUEUE_MAP/tqm:name";
+ path "/tqm:sonic-tc-queue-map/tqm:TC_TO_QUEUE_MAP/tqm:TC_TO_QUEUE_MAP_LIST/tqm:name";
}
}
@@ -77,13 +73,13 @@ module sonic-port-qos-map {
leaf pfc_to_queue_map {
type leafref {
- path "/ppq:sonic-pfc-priority-queue-map/ppq:MAP_PFC_PRIORITY_TO_QUEUE/ppq:name";
+ path "/ppq:sonic-pfc-priority-queue-map/ppq:MAP_PFC_PRIORITY_TO_QUEUE/ppq:MAP_PFC_PRIORITY_TO_QUEUE_LIST/ppq:name";
}
}
leaf dscp_to_tc_map {
type leafref {
- path "/dtm:sonic-dscp-tc-map/dtm:DSCP_TO_TC_MAP/dtm:name";
+ path "/dtm:sonic-dscp-tc-map/dtm:DSCP_TO_TC_MAP/dtm:DSCP_TO_TC_MAP_LIST/dtm:name";
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-portchannel-interface.yang b/src/cvl/testdata/schema/sonic-portchannel-interface.yang
index 305fd6ae76..45d92787d2 100644
--- a/src/cvl/testdata/schema/sonic-portchannel-interface.yang
+++ b/src/cvl/testdata/schema/sonic-portchannel-interface.yang
@@ -2,16 +2,8 @@ module sonic-portchannel-interface {
namespace "http://github.com/Azure/sonic-portchannel-interface";
prefix spchint;
- import ietf-yang-types {
- prefix yang;
- }
-
import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
+ prefix inet;
}
import sonic-portchannel {
@@ -33,19 +25,23 @@ module sonic-portchannel-interface {
}
container sonic-portchannel-interface {
- list PORTCHANNEL_INTERFACE {
- key "pch_name ip_prefix";
- leaf pch_name{
- type leafref {
- path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:name";
- }
- }
+ container PORTCHANNEL_INTERFACE {
+
+ list PORTCHANNEL_INTERFACE_LIST {
+ key "pch_name ip_prefix";
+
+ leaf pch_name{
+ type leafref {
+ path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:PORTCHANNEL_LIST/spc:name";
+ }
+ }
- leaf ip_prefix {
- mandatory true;
- type inet:ip-prefix;
+ leaf ip_prefix {
+ mandatory true;
+ type inet:ip-prefix;
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-portchannel.yang b/src/cvl/testdata/schema/sonic-portchannel.yang
index 4ecd3a33d6..afe308f4e5 100644
--- a/src/cvl/testdata/schema/sonic-portchannel.yang
+++ b/src/cvl/testdata/schema/sonic-portchannel.yang
@@ -2,10 +2,6 @@ module sonic-portchannel {
namespace "http://github.com/Azure/sonic-portchannel";
prefix spc;
- import ietf-yang-types {
- prefix yang;
- }
-
import sonic-common {
prefix scommon;
}
@@ -30,48 +26,52 @@ module sonic-portchannel {
container sonic-portchannel {
- list PORTCHANNEL {
- key "name";
+ container PORTCHANNEL {
- max-elements 3;
+ list PORTCHANNEL_LIST {
+ key "name";
- leaf name {
- type string;
- }
+ max-elements 3;
- leaf admin_status {
- type scommon:admin-status;
- }
+ leaf name {
+ type string;
+ }
- leaf mtu {
- type uint16;
- }
+ leaf admin_status {
+ type scommon:admin-status;
+ }
- leaf min_links {
- type uint8;
- }
+ leaf mtu {
+ type uint16;
+ }
+
+ leaf min_links {
+ type uint8;
+ }
- leaf fallback {
- type boolean;
+ leaf fallback {
+ type boolean;
+ }
}
}
- list PORTCHANNEL_MEMBER {
- key "name ifname";
- scommon:key-delim "|";
- scommon:key-pattern "PORTCHANNEL|{name}|{ifname}";
+ container PORTCHANNEL_MEMBER {
- leaf name {
- type leafref {
- path "../../PORTCHANNEL/name";
+ list PORTCHANNEL_MEMBER_LIST {
+ key "name ifname";
+
+ leaf name {
+ type leafref {
+ path "../../../PORTCHANNEL/PORTCHANNEL_LIST/name";
+ }
}
- }
- leaf ifname {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
+ leaf ifname {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
}
}
}
- }
+ }
}
diff --git a/src/cvl/testdata/schema/sonic-queue.yang b/src/cvl/testdata/schema/sonic-queue.yang
index fb55793443..92a7f4c96f 100644
--- a/src/cvl/testdata/schema/sonic-queue.yang
+++ b/src/cvl/testdata/schema/sonic-queue.yang
@@ -2,12 +2,8 @@ module sonic-queue {
namespace "http://github.com/Azure/sonic-queue";
prefix squeue;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
import sonic-port {
@@ -38,35 +34,39 @@ module sonic-queue {
container sonic-queue {
- list QUEUE {
- key "ifname qindex";
- scommon:key-pattern "QUEUE|({ifname},)*|{qindex}"; //special pattern used for extracting keys from redis-key and populate the yang instance
- // Total list instances = number(key1) * number(key2) * number(key3)
-
- leaf ifname {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
+
+ container QUEUE {
+
+ list QUEUE_LIST {
+ key "ifname qindex";
+ sonic-ext:key-pattern "QUEUE|({ifname},)*|{qindex}"; //special pattern used for extracting keys from redis-key and populate the yang instance
+ // Total list instances = number(key1) * number(key2) * number(key3)
+
+ leaf ifname {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
}
- }
- leaf qindex {
- type string {
- pattern "[0-8]((-)[0-8])?"{
- error-message "Invalid Q-index";
- error-app-tag qindex-invalid;
+ leaf qindex {
+ type string {
+ pattern "[0-8]((-)[0-8])?"{
+ error-message "Invalid Q-index";
+ error-app-tag qindex-invalid;
+ }
}
}
- }
- leaf scheduler {
- type leafref {
- path "/sch:sonic-scheduler/sch:SCHEDULER/sch:name";
+ leaf scheduler {
+ type leafref {
+ path "/sch:sonic-scheduler/sch:SCHEDULER/sch:SCHEDULER_LIST/sch:name";
+ }
}
- }
- leaf wred_profile {
- type leafref {
- path "/wrd:sonic-wred-profile/wrd:WRED_PROFILE/wrd:name";
+ leaf wred_profile {
+ type leafref {
+ path "/wrd:sonic-wred-profile/wrd:WRED_PROFILE/wrd:WRED_PROFILE_LIST/wrd:name";
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-scheduler.yang b/src/cvl/testdata/schema/sonic-scheduler.yang
index d1e26ab359..2fc7997f71 100644
--- a/src/cvl/testdata/schema/sonic-scheduler.yang
+++ b/src/cvl/testdata/schema/sonic-scheduler.yang
@@ -2,14 +2,6 @@ module sonic-scheduler {
namespace "http://github.com/Azure/sonic-scheduler";
prefix sch;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
organization
"SONiC";
@@ -25,30 +17,34 @@ module sonic-scheduler {
}
container sonic-scheduler {
- list SCHEDULER {
- key "name";
- leaf name{
- type string;
- }
+ container SCHEDULER {
- leaf type {
- type enumeration {
- enum DWRR;
- enum WRR;
- enum PRIORITY;
+ list SCHEDULER_LIST {
+ key "name";
+
+ leaf name{
+ type string;
}
- }
- leaf weight {
- type uint8 {
- range "0..255";
+ leaf type {
+ type enumeration {
+ enum DWRR;
+ enum WRR;
+ enum PRIORITY;
+ }
+ }
+
+ leaf weight {
+ type uint8 {
+ range "0..255";
+ }
}
- }
- leaf priority {
- type uint8 {
- range "0..9";
+ leaf priority {
+ type uint8 {
+ range "0..9";
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang b/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang
index 253ed0f47b..ed89a281ec 100644
--- a/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang
+++ b/src/cvl/testdata/schema/sonic-tc-priority-group-map.yang
@@ -2,12 +2,8 @@ module sonic-tc-priority-group-map {
namespace "http://github.com/Azure/sonic-tc-priority-group-map";
prefix tpg;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
organization
@@ -25,31 +21,34 @@ module sonic-tc-priority-group-map {
}
container sonic-tc-priority-group-map {
- list TC_TO_PRIORITY_GROUP_MAP {
- key "name";
- scommon:map-list "true"; //special conversion for map tables
- scommon:map-leaf "tc_num pg_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- leaf name {
- type string;
- }
+ container TC_TO_PRIORITY_GROUP_MAP {
- list TC_TO_PRIORITY_GROUP_MAP { //this is list inside list for storing mapping between two fields
- key "tc_num pg_num";
+ list TC_TO_PRIORITY_GROUP_MAP_LIST {
+ key "name";
+ sonic-ext:map-list "true"; //special conversion for map tables
+ sonic-ext:map-leaf "tc_num pg_num"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, dscp=7
- leaf tc_num {
- type string {
- pattern "[0-9]?";
- }
+ leaf name {
+ type string;
}
- leaf pg_num {
- type string {
- pattern "[0-7]?";
+ list TC_TO_PRIORITY_GROUP_MAP { //this is list inside list for storing mapping between two fields
+ key "tc_num pg_num";
+
+ leaf tc_num {
+ type string {
+ pattern "[0-9]?";
+ }
+ }
+
+ leaf pg_num {
+ type string {
+ pattern "[0-7]?";
+ }
}
}
}
-
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-tc-queue-map.yang b/src/cvl/testdata/schema/sonic-tc-queue-map.yang
index 385b9edfac..37ab1c8113 100644
--- a/src/cvl/testdata/schema/sonic-tc-queue-map.yang
+++ b/src/cvl/testdata/schema/sonic-tc-queue-map.yang
@@ -2,12 +2,8 @@ module sonic-tc-queue-map {
namespace "http://github.com/Azure/sonic-tc-queue-map";
prefix tqm;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
+ import sonic-extension {
+ prefix sonic-ext;
}
organization
@@ -25,31 +21,35 @@ module sonic-tc-queue-map {
}
container sonic-tc-queue-map {
- list TC_TO_QUEUE_MAP {
- key "name";
- scommon:map-list "true"; //special conversion for map tables
- scommon:map-leaf "tc_num qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, qindex=7
- leaf name {
- type string;
- }
+ container TC_TO_QUEUE_MAP {
- list TC_TO_QUEUE_MAP { //this is list inside list for storing mapping between two fields
- key "tc_num qindex";
+ list TC_TO_QUEUE_MAP_LIST {
+ key "name";
+ sonic-ext:map-list "true"; //special conversion for map tables
+ sonic-ext:map-leaf "tc_num qindex"; //every key:value pair is mapped to list keys, e.g. "1":"7" ==> tc_num=1, qindex=7
- leaf tc_num {
- type string {
- pattern "[0-9]?";
- }
+ leaf name {
+ type string;
}
- leaf qindex {
- type string {
- pattern "[0-9]?";
+ list TC_TO_QUEUE_MAP { //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]?";
+ }
}
}
- }
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-vlan-dev.yang b/src/cvl/testdata/schema/sonic-vlan-deviation.yang
similarity index 78%
rename from src/cvl/testdata/schema/sonic-vlan-dev.yang
rename to src/cvl/testdata/schema/sonic-vlan-deviation.yang
index dcb6531126..ff426fb30c 100644
--- a/src/cvl/testdata/schema/sonic-vlan-dev.yang
+++ b/src/cvl/testdata/schema/sonic-vlan-deviation.yang
@@ -1,15 +1,13 @@
-module sonic-vlan-dev {
- namespace "http://github.com/Azure/sonic-vlan-dev";
+module sonic-vlan-deviation {
+ namespace "http://github.com/Azure/sonic-vlan-deviation";
prefix svd;
yang-version 1.1;
- import ietf-yang-types {
- prefix yang;
- }
-
+ /*
import sonic-vlan {
prefix svlan;
}
+ */
organization
"SONiC";
diff --git a/src/cvl/testdata/schema/sonic-vlan-interface.yang b/src/cvl/testdata/schema/sonic-vlan-interface.yang
index 86b9f8c0f3..554feb1f58 100644
--- a/src/cvl/testdata/schema/sonic-vlan-interface.yang
+++ b/src/cvl/testdata/schema/sonic-vlan-interface.yang
@@ -2,16 +2,8 @@ module sonic-vlan-interface {
namespace "http://github.com/Azure/sonic-vlan-interface";
prefix svint;
- import ietf-yang-types {
- prefix yang;
- }
-
import ietf-inet-types {
- prefix inet;
- }
-
- import sonic-common {
- prefix scommon;
+ prefix inet;
}
import sonic-vlan {
@@ -33,19 +25,23 @@ module sonic-vlan-interface {
}
container sonic-vlan-interface {
- list VLAN_INTERFACE {
- key "portname ip_prefix";
- leaf portname{
- type leafref {
- path "/svlan:sonic-vlan/svlan:VLAN/svlan:name";
- }
- }
+ container VLAN_INTERFACE {
+
+ list VLAN_INTERFACE_LIST {
+ key "portname ip_prefix";
+
+ leaf portname{
+ type leafref {
+ path "/svlan:sonic-vlan/svlan:VLAN/svlan:VLAN_LIST/svlan:name";
+ }
+ }
- leaf ip_prefix {
- mandatory true;
- type inet:ip-prefix;
+ leaf ip_prefix {
+ mandatory true;
+ type inet:ip-prefix;
+ }
}
}
}
diff --git a/src/cvl/testdata/schema/sonic-vlan.yang b/src/cvl/testdata/schema/sonic-vlan.yang
index 5a043b5f22..1170960df1 100644
--- a/src/cvl/testdata/schema/sonic-vlan.yang
+++ b/src/cvl/testdata/schema/sonic-vlan.yang
@@ -3,10 +3,6 @@ module sonic-vlan {
prefix svlan;
yang-version 1.1;
- import ietf-yang-types {
- prefix yang;
- }
-
import sonic-common {
prefix scommon;
}
@@ -36,72 +32,76 @@ module sonic-vlan {
container sonic-vlan {
- list VLAN {
- key "name";
- must "./name = concat('Vlan', string(./vlanid))"{
- error-app-tag vlan-invalid;
- }
+ container VLAN {
- leaf name {
- type string {
- pattern "Vlan(409[0-5]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[1-9])" {
- error-message "Invalid Vlan name pattern";
- error-app-tag vlan-name-invalid;
+ list VLAN_LIST {
+ key "name";
+ must "./name = concat('Vlan', string(./vlanid))"{
+ error-app-tag vlan-invalid;
+ }
+
+ leaf name {
+ type string {
+ pattern "Vlan(409[0-5]|40[0-8][0-9]|[1-3][0-9]{3}|[1-9][0-9]{2}|[1-9][0-9]|[1-9])" {
+ error-message "Invalid Vlan name pattern";
+ error-app-tag vlan-name-invalid;
+ }
}
}
- }
- leaf vlanid {
- mandatory true;
- type uint16 {
- range "1..4095" {
- error-message "Vlan ID out of range";
- error-app-tag vlanid-invalid;
+ leaf vlanid {
+ mandatory true;
+ type uint16 {
+ range "1..4095" {
+ error-message "Vlan ID out of range";
+ error-app-tag vlanid-invalid;
+ }
}
}
- }
- leaf-list members {
- must "count(../members[text()=/spc:sonic-portchannel/" +
- "spc:PORTCHANNEL_MEMBER[spc:ifname=current()]/spc:name]) = 0 and " +
- "count(../members[text()=/spc:sonic-portchannel/" +
- "spc:PORTCHANNEL_MEMBER[spc:name=current()]/spc:ifname]) = 0 " {
- error-message "A vlan interface member cannot be part of portchannel which is already a vlan member";
- }
+ leaf-list members {
+ must "count(../members[text()=/spc:sonic-portchannel/spc:PORTCHANNEL_MEMBER/" +
+ "spc:PORTCHANNEL_MEMBER_LIST[spc:ifname=current()]/spc:name]) = 0 and " +
+ "count(../members[text()=/spc:sonic-portchannel/spc:PORTCHANNEL_MEMBER/" +
+ "spc:PORTCHANNEL_MEMBER_LIST[spc:name=current()]/spc:ifname]) = 0 " {
+ error-message "A vlan interface member cannot be part of portchannel which is already a vlan member";
+ }
- type union {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
- }
- type leafref {
- path "/spc:sonic-portchannel/spc:PORTCHANNEL/spc:name";
+ 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";
+ }
}
}
}
}
- list VLAN_MEMBER {
- key "name ifname";
+ container VLAN_MEMBER {
- leaf name {
- type leafref {
- path "../../VLAN/name";
+ list VLAN_MEMBER_LIST {
+ key "name ifname";
+
+ leaf name {
+ type leafref {
+ path "../../../VLAN/VLAN_LIST/name";
+ }
}
- }
- leaf ifname {
- type leafref {
- path "/prt:sonic-port/prt:PORT/prt:ifname";
+ leaf ifname {
+ type leafref {
+ path "/prt:sonic-port/prt:PORT/prt:PORT_LIST/prt:ifname";
+ }
}
- }
- leaf tagging_mode {
- type scommon:tagging_mode;
- default tagged;
+ leaf tagging_mode {
+ type scommon:tagging_mode;
+ default tagged;
+ }
}
}
-
}
-
}
diff --git a/src/cvl/testdata/schema/sonic-wred-profile.yang b/src/cvl/testdata/schema/sonic-wred-profile.yang
index 89b9c90ef5..e3c5abe363 100644
--- a/src/cvl/testdata/schema/sonic-wred-profile.yang
+++ b/src/cvl/testdata/schema/sonic-wred-profile.yang
@@ -2,14 +2,6 @@ module sonic-wred-profile {
namespace "http://github.com/Azure/sonic-wred-profile";
prefix wrd;
- import ietf-yang-types {
- prefix yang;
- }
-
- import sonic-common {
- prefix scommon;
- }
-
organization
"SONiC";
@@ -25,59 +17,63 @@ module sonic-wred-profile {
}
container sonic-wred-profile {
- list WRED_PROFILE {
- key "name";
- leaf name{
- type string;
- }
+ container WRED_PROFILE {
- leaf yellow_min_threshold {
- type uint64;
- }
+ list WRED_PROFILE_LIST {
+ key "name";
- leaf green_min_threshold {
- type uint64;
- }
+ leaf name{
+ type string;
+ }
- leaf red_min_threshold {
- type uint64;
- }
- leaf yellow_max_threshold {
- type uint64;
- }
+ leaf yellow_min_threshold {
+ type uint64;
+ }
- leaf green_max_threshold {
- type uint64;
- }
+ leaf green_min_threshold {
+ type uint64;
+ }
- leaf red_max_threshold {
- type uint64;
- }
+ leaf red_min_threshold {
+ type uint64;
+ }
+ leaf yellow_max_threshold {
+ type uint64;
+ }
- leaf ecn {
- type enumeration {
- enum ecn_none;
- enum ecn_green;
- enum ecn_yellow;
- enum ecn_red;
- enum ecn_green_yellow;
- enum ecn_green_red;
- enum ecn_yellow_red;
- enum ecn_all;
+ leaf green_max_threshold {
+ type uint64;
}
- }
- leaf wred_green_enable {
- type boolean;
- }
+ leaf red_max_threshold {
+ type uint64;
+ }
- leaf wred_yellow_enable {
- type boolean;
- }
+ leaf ecn {
+ type enumeration {
+ enum ecn_none;
+ enum ecn_green;
+ enum ecn_yellow;
+ enum ecn_red;
+ enum ecn_green_yellow;
+ enum ecn_green_red;
+ enum ecn_yellow_red;
+ enum ecn_all;
+ }
+ }
+
+ leaf wred_green_enable {
+ type boolean;
+ }
- leaf wred_red_enable {
- type boolean;
+ leaf wred_yellow_enable {
+ type boolean;
+ }
+
+ leaf wred_red_enable {
+ type boolean;
+ }
}
}
}
diff --git a/tools/pyang/pyang_plugins/yin_cvl.py b/tools/pyang/pyang_plugins/yin_cvl.py
new file mode 100644
index 0000000000..71689003b0
--- /dev/null
+++ b/tools/pyang/pyang_plugins/yin_cvl.py
@@ -0,0 +1,179 @@
+################################################################################
+# #
+# Copyright 2019 Broadcom. The term Broadcom refers to Broadcom Inc. and/or #
+# its subsidiaries. #
+# #
+# Licensed under the Apache License, Version 2.0 (the "License"); #
+# you may not use this file except in compliance with the License. #
+# You may obtain a copy of the License at #
+# #
+# http://www.apache.org/licenses/LICENSE-2.0 #
+# #
+# Unless required by applicable law or agreed to in writing, software #
+# distributed under the License is distributed on an "AS IS" BASIS, #
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. #
+# See the License for the specific language governing permissions and #
+# limitations under the License. #
+# #
+################################################################################
+"""CVL YIN output plugin"""
+
+from xml.sax.saxutils import quoteattr
+from xml.sax.saxutils import escape
+
+import optparse
+import re
+
+from pyang import plugin
+from pyang import util
+from pyang import grammar
+from pyang import syntax
+from pyang import statements
+
+new_line ='' #replace with '\n' for adding new line
+indent_space = '' #replace with ' ' for indentation
+ns_indent_space = '' #replace with ' ' for indentation
+yin_namespace = "urn:ietf:params:xml:ns:yang:yin:1"
+revision_added = False
+
+def pyang_plugin_init():
+ plugin.register_plugin(YINPluginCVL())
+
+class YINPluginCVL(plugin.PyangPlugin):
+ def add_output_format(self, fmts):
+ fmts['yin-cvl'] = self
+ def emit(self, ctx, modules, fd):
+ module = modules[0]
+ emit_yin(ctx, module, fd)
+
+def emit_yin(ctx, module, fd):
+ fd.write('' + new_line)
+ fd.write(('<%s name="%s"' + new_line) % (module.keyword, module.arg))
+ fd.write(ns_indent_space * len(module.keyword) + ns_indent_space + ' xmlns="%s"' % yin_namespace)
+
+ prefix = module.search_one('prefix')
+ if prefix is not None:
+ namespace = module.search_one('namespace')
+ fd.write('' + new_line)
+ fd.write(ns_indent_space * len(module.keyword))
+ fd.write(ns_indent_space + ' xmlns:' + prefix.arg + '=' +
+ quoteattr(namespace.arg))
+ else:
+ belongs_to = module.search_one('belongs-to')
+ if belongs_to is not None:
+ prefix = belongs_to.search_one('prefix')
+ if prefix is not None:
+ # read the parent module in order to find the namespace uri
+ res = ctx.read_module(belongs_to.arg, extra={'no_include':True})
+ if res is not None:
+ namespace = res.search_one('namespace')
+ if namespace is None or namespace.arg is None:
+ pass
+ else:
+ # success - namespace found
+ fd.write('' + new_line)
+ fd.write(sonic-acl.yin * len(module.keyword))
+ fd.write(sonic-acl.yin + ' xmlns:' + prefix.arg + '=' +
+ quoteattr(namespace.arg))
+
+ for imp in module.search('import'):
+ prefix = imp.search_one('prefix')
+ if prefix is not None:
+ rev = None
+ r = imp.search_one('revision-date')
+ if r is not None:
+ rev = r.arg
+ mod = statements.modulename_to_module(module, imp.arg, rev)
+ if mod is not None:
+ ns = mod.search_one('namespace')
+ if ns is not None:
+ fd.write('' + new_line)
+ fd.write(ns_indent_space * len(module.keyword))
+ fd.write(ns_indent_space + ' xmlns:' + prefix.arg + '=' +
+ quoteattr(ns.arg))
+ fd.write('>' + new_line)
+
+ substmts = module.substmts
+ for s in substmts:
+ emit_stmt(ctx, module, s, fd, indent_space, indent_space)
+ fd.write(('%s>' + new_line) % module.keyword)
+
+def emit_stmt(ctx, module, stmt, fd, indent, indentstep):
+ global revision_added
+
+ if stmt.raw_keyword == "revision" and revision_added == False:
+ revision_added = True
+ elif stmt.raw_keyword == "revision" and revision_added == True:
+ #Only add the latest revision
+ return
+
+ #Don't keep the following keywords as they are not used in CVL
+ # stmt.raw_keyword == "revision" or
+ if ((stmt.raw_keyword == "organization" or
+ stmt.raw_keyword == "contact" or
+ stmt.raw_keyword == "rpc" or
+ stmt.raw_keyword == "notification" or
+ stmt.raw_keyword == "description") or
+ (len(stmt.substmts) > 0 and stmt.substmts[0].raw_keyword == "config" and
+ stmt.substmts[0].arg == "false")):
+ return
+
+ if util.is_prefixed(stmt.raw_keyword):
+ # this is an extension. need to find its definition
+ (prefix, identifier) = stmt.raw_keyword
+ tag = prefix + ':' + identifier
+ if stmt.i_extension is not None:
+ ext_arg = stmt.i_extension.search_one('argument')
+ if ext_arg is not None:
+ yin_element = ext_arg.search_one('yin-element')
+ if yin_element is not None and yin_element.arg == 'true':
+ argname = prefix + ':' + ext_arg.arg
+ argiselem = True
+ else:
+ # explicit false or no yin-element given
+ argname = ext_arg.arg
+ argiselem = False
+ else:
+ argiselem = False
+ argname = None
+ else:
+ argiselem = False
+ argname = None
+ else:
+ (argname, argiselem) = syntax.yin_map[stmt.raw_keyword]
+ tag = stmt.raw_keyword
+ if argiselem == False or argname is None:
+ if argname is None:
+ attr = ''
+ else:
+ attr = ' ' + argname + '=' + quoteattr(stmt.arg)
+ if len(stmt.substmts) == 0:
+ fd.write(indent + '<' + tag + attr + '/>' + new_line)
+ else:
+ fd.write(indent + '<' + tag + attr + '>' + new_line)
+ for s in stmt.substmts:
+ emit_stmt(ctx, module, s, fd, indent + indentstep,
+ indentstep)
+ fd.write(indent + '' + tag + '>' + new_line)
+ else:
+ fd.write(indent + '<' + tag + '>' + new_line)
+ fd.write(indent + indentstep + '<' + argname + '>' + \
+ escape(stmt.arg) + \
+ '' + argname + '>' + new_line)
+ substmts = stmt.substmts
+
+ for s in substmts:
+ emit_stmt(ctx, module, s, fd, indent + indentstep, indentstep)
+
+ fd.write(indent + '' + tag + '>' + new_line)
+
+def fmt_text(indent, data):
+ res = []
+ for line in re.split("(\n)", escape(data)):
+ if line == '':
+ continue
+ if line == '' + new_line:
+ res.extend(line)
+ else:
+ res.extend(indent + line)
+ return ''.join(res)