--- /dev/null
+module alto-service-types {
+ yang-version 1;
+
+ namespace "urn:opendaylight:alto-service-types";
+ // TODO: replace with IANA namespace when assigned
+
+ prefix "alto";
+
+ import ietf-inet-types {
+ prefix inet;
+ }
+
+ organization "ALTO WG";
+ contact "alto@ietf.org";
+
+ description
+ "This module defines the data types and groupings for a semantically
+ equivalent data model for the ALTO services defined in RFC7285.";
+
+ revision 2014-11-01 {
+ description "Separate types module";
+ }
+
+ revision 2014-10-24 {
+ description "Initial version.";
+ }
+
+ /********************
+ * TYPE DEFINITIONS *
+ ********************/
+
+ /***********************************************************
+ Definitions for addresses
+
+ ALTO RFC7285 uses the following addresses, as shown in the
+ examples below:
+
+ - Endpoint property service (Sec. 11.4.1.7):
+ "endpoints" : [ "ipv4:192.0.2.34",
+ "ipv4:203.0.113.129" ]
+ - Endpoint cost service (Sec. 11.5.1.7):
+ "endpoints" : {
+ "srcs": [ "ipv4:192.0.2.2" ],
+ "dsts": [
+ "ipv4:192.0.2.89",
+ "ipv4:198.51.100.34",
+ "ipv4:203.0.113.45"
+ - Network map (Sec. 11.2.1.7.):
+ "ipv4": [
+ "192.0.2.0/24",
+ "198.51.100.0/25"
+ ],
+ "ipv6": [
+ "2001:db8:0:1::/64",
+ "2001:db8:0:2::/64"
+ ]
+
+ To handle the proceeding, we need the following definitions:
+ ipv4-address (e.g., 192.0.2.0, already defined in rfc6991),
+ ipv6-address (already defined in rfc6991),
+ ipv4-prefix (e.g., 192.0.2.0/24, already defined in rfc6991),
+ ipv6-prefix (defined in rfc6991),
+ typed-ipv4-address (e.g., ipv4:192.0.2.1, to be defined below)
+ typed-ipv6-address
+ typed-ipv4-prefix-list (e.g., "ipv4": [
+ "192.0.2.0/24",
+ "198.51.100.0/25"
+ ],
+
+ *******************************************************************/
+
+ /*
+ First define typed-ipv4-address and typed-ipv6-address, as used
+ by endpoint services.
+
+ The ideal case is to define it as "ipv4:"+ipv4-address, but there
+ is not such a type constructor (YANG EXTENSION). Hence, the
+ current definition cuts-and-pastes (i.e., repeats verbatim) the
+ definition of ipv4-address and prepend "ipv4:". The downside is
+ that if someone redefines ipv4-address, there could be
+ inconsistency.
+ */
+
+ typedef typed-ipv4-address {
+ type string {
+ pattern
+ 'ipv4:(([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}]+)?';
+ }
+ }
+
+
+ typedef typed-ipv6-address {
+ type string {
+ pattern 'ipv6:((:|[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 'ipv6:(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+ + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+ + '(%.+)?';
+ }
+ }
+
+ typedef typed-endpoint-address {
+ type union {
+ type typed-ipv4-address;
+ type typed-ipv6-address;
+ // EXTENSION: ADD NEW TYPE HERE.
+ }
+ description
+ "Ref: RFC7285 Sec. 10.4.1 Typed Endpoint Addresses" +
+ "= AddressType:EndpointAddr";
+ }
+
+ /* Next, we define endpoint address group, as used in the definition
+ of ALTO network maps. Specifically, an endpoint address group in
+ ALTO is defined as a key-value store, with address type as key,
+ and an array of prefix as the value of each key:
+
+ EndpointAddrGroup. RFC7285 Sec. 10.4.5." +
+ object-map {
+ AddressType -> endpoint-prefix<0..*>;
+ } EndpointAddrGroup;
+
+ There are two challenges:
+
+ 1) To specify that AddressType is key, we must use the list type,
+ which is the only type that one can specify key. However, the
+ current JSON-YANG encoding generates an array, instead of a
+ key-value map;
+
+ 2) Ideally, we want to enforce address type and prefix
+ consistency; for example, an ipv6 prefix in an ipv4 type should
+ not be allowed. However, we encounter problems. We leave this as
+ an OPEN ISSUE.
+ */
+
+ typedef endpoint-address-type {
+ type union {
+ type enumeration {
+ enum ipv4;
+ enum ipv6;
+ // EXTENSION: ADD NEW TYPE HERE
+ }
+ }
+ description
+ "Ref: RFC7285 Sec 2.2.";
+ }
+ /*
+ typedef endpoint-prefix {
+ type inet:ip-prefix;
+ description
+ "endpoint prefix, identical to ip-prefix defined in RFC6991.";
+ }
+ */
+
+ grouping endpoint-address-group {
+ list endpoint-address-group {
+ key address-type;
+ leaf address-type {
+ type endpoint-address-type;
+ mandatory true;
+ }
+ leaf-list endpoint-prefix {
+ type inet:ip-prefix;
+ }
+ }
+ description
+ "EndpointAddrGroup. RFC7285 Sec. 10.4.5." +
+ " object-map {
+ AddressType -> endpoint-prefix<0..*>;
+ } EndpointAddrGroup;";
+ }
+
+ /**************************************************************
+ * Definitions for IDs and names
+ *
+ * ALTO defines the following concepts that are names and IDs:
+ *
+ * pid name (used in network map, cost map),
+ * resource IDs (used to identify alto network/cost maps),
+ * version tag (used to indicate uniqueness of resource),
+ * cost-type-name (used in IRD),
+ * cost-metric,
+ * cost-mode
+ *
+ * We group their definitions together below.
+ **************************************************************/
+
+ typedef valid-id-string {
+ type string {
+ length "1..64";
+ pattern "[0-9a-zA-Z_\-:@\.]+";
+ }
+ description
+ "Type for valid ID strings.";
+ }
+
+ typedef tag-string {
+ type string {
+ length "1..64";
+ pattern "[!-~]+";
+ }
+ description
+ "Tag. RFC7285 Sec. 10.3. U+0021-U+007E";
+ }
+
+ typedef pid-name {
+ type valid-id-string;
+ description
+ "Name for the PID." +
+ "RFC7285, Section 10.1. Note: the '.' separator MUST NOT be" +
+ "used unless specifically indicated in RFC7285 or an" +
+ " extension document.";
+ }
+
+ typedef resource-id {
+ type valid-id-string;
+ description
+ "Resource-ID.";
+ }
+
+ grouping vtag {
+ leaf resource-id {
+ type resource-id;
+ mandatory true;
+ }
+ leaf tag {
+ type tag-string;
+ mandatory true;
+ }
+ description
+ "Version tag. Both resource-id and tag must be equal
+ byte-for-byte. RFC7285 Sec. 10.3." +
+ " object {
+ ResourceID resource-id;
+ JSONString tag;
+ } VersionTag;";
+ }
+
+ grouping dependent-vtags {
+ list dependent-vtags {
+ uses vtag;
+ min-elements 1;
+ }
+ }
+
+ /*************************************
+ Definitions for cost type and cost types
+
+ In ALTO, a cost type consists of two required components:
+
+ cost-metric,
+ cost-mode
+ and an optional description component.
+
+ In the IRD, one can name each cost type. Such info is collected
+ in a hash map called cost types.
+ *************************************/
+
+ typedef cost-metric {
+ type union {
+ type enumeration {
+ enum routingcost {
+ description
+ "Default metric. MUST support. RFC7285 Sec. 6.1.1.1.";
+ }
+ enum hopcount {
+ description
+ "Hopcount metric.";
+ }
+ // EXTENSION: Additional cost-metric will be defined here.
+ }
+ type string {
+ length 1..32;
+ pattern "priv:[0-9a-zA-Z_\-:\.]+";
+ }
+ }
+ description
+ "Cost metric. for type string,
+ 'priv:' reserved for Private Use.";
+ }
+
+ typedef cost-mode {
+ type enumeration {
+ enum numerical {
+ description
+ "Numerical cost mode.";
+ }
+ enum ordinal {
+ description
+ "Ordinal cost mode.";
+ }
+ // EXTENSION: Additional cost-mode will be defined here.
+ }
+ description
+ "Cost mode. MUST support at least one of numerical and ordinal";
+ }
+
+ grouping cost-type {
+ leaf cost-mode {
+ type cost-mode;
+ mandatory true;
+ description
+ "Cost mode.";
+ }
+ leaf cost-metric {
+ type cost-metric;
+ mandatory true;
+ description
+ "Cost metric.";
+ }
+ leaf description {
+ type string;
+ description
+ "Optional description field.";
+ }
+ description
+ "Cost type. RFC7285 Sec. 10.7." +
+ " object {
+ CostMetric cost-metric;
+ CostMode cost-mode;
+ [JSONString description;]
+ } CostType;";
+ }
+
+ typedef cost-type-name {
+ type valid-id-string;
+ // NOTE: not fully specified in RFC7285, default as valid id
+ }
+
+ grouping cost-types {
+ list cost-types {
+ key cost-type-name;
+ leaf cost-type-name {
+ type cost-type-name;
+ }
+ uses cost-type;
+ }
+ description
+ "RFC 7285 Sec. 9.2.2." +
+ "object-map {
+ JSONString -> CostType;
+ } IRDMetaCostTypes;";
+ }
+
+
+ /**************************************
+ * Definitions for endpoint properties *
+ **************************************/
+ typedef global-endpoint-property {
+ type union {
+ type enumeration {
+ enum pid {
+ description "PID property.";
+ }
+ // EXTENSION: other options here
+ }
+ type string {
+ pattern "priv:[\w\-:@]+";
+ }
+ }
+ description
+ "Global endpoint property. RFC7285 Sec. 10.8.2." +
+ "'priv:' for Private Use " +
+ " length 1..32; ‘.’ is not allowed";
+ }
+
+ /*
+ * Ideally we would want to extend the typedef of resource-id and
+ * global endpoint properties, however, YANG 1.0 does not allow
+ * that, hence we simply copied the regex for resource-id over
+ * verbatim.
+ */
+
+ typedef resource-specific-endpoint-property {
+ type string {
+ length "3..97"; //len(resource-id) + 1 + len(global-property)
+ pattern "(priv:)?[\w\-:@\.]+\.[\w\-:_]+"; // resource-id.property
+ }
+ description
+ "Resource-specific endpoint property.";
+ }
+
+ typedef endpoint-property-type {
+ type union {
+ type resource-specific-endpoint-property;
+ type global-endpoint-property;
+ }
+ description
+ "Endpoint property type. RFC7285 Sec. 10.8.";
+ }
+
+ typedef endpoint-property-value {
+ type string;
+ description
+ "Endpoint property (value).";
+ }
+
+ /*************************************
+ * Definitions for response header
+ *************************************/
+
+ typedef media-type {
+ type union {
+ type string {
+ pattern "application/alto\-.*";
+ }
+ type enumeration {
+ enum alto-directory; //+json
+ enum alto-networkmap; //+json
+ enum alto-networkmapfilter; //+json
+ enum alto-costmap; //+json
+ enum alto-costmapfilter; //+json
+ enum alto-endpointprop; //+json
+ enum alto-endpointpropparams; //+json
+ enum alto-endpointcost; //+json
+ enum alto-endpointcostparams; //+json
+ enum alto-error; //+json
+ }
+ }
+ }
+
+ grouping alto-cost {
+ anyxml cost {
+ mandatory true;
+ description
+ "ALTO cost is a JSONValue, which could be
+ an object, array, string, etc. (Ref: RFC 7159 Sec.3.)";
+ }
+ }
+
+ typedef constraint {
+ type string {
+ pattern "(gt|ge|lt|le|eq) [0-9]+";
+ }
+ description
+ "RFC7285 Sec. 11.3.2.3. The second part must be in the" +
+ "same unit as cost-metric, IEEE 754 2008 floating point.";
+ }
+
+ /******************************************
+ Groupings for ALTO information resource
+ *******************************************/
+
+ /* meta */
+ grouping IRD-meta {
+ uses cost-types;
+ leaf default-alto-network-map {
+ type resource-id;
+ mandatory true;
+ }
+ }
+
+ grouping network-map-meta {
+ container vtag {
+ uses vtag;
+ }
+ }
+
+ grouping cost-map-meta {
+ uses dependent-vtags {
+ refine dependent-vtags {
+ max-elements 1;
+ }
+ }
+ container cost-type {
+ uses cost-type;
+ }
+ }
+
+ grouping endpoint-property-meta {
+ uses dependent-vtags;
+ }
+
+ /* accepts (optional) */
+ grouping accepts {
+ leaf-list accepts {
+ type media-type;
+ min-elements 1;
+ }
+ }
+
+ /* capabilities (capabilities) */
+ grouping IRD-capabilities {
+ container capabilities {
+ leaf cost-constraints {
+ type boolean;
+ }
+ leaf-list cost-type-names {
+ type cost-type-name;
+ }
+ leaf-list prop-types {
+ type endpoint-property-type;
+ }
+ }
+ }
+
+ /* uses (optional) */
+ grouping uses {
+ leaf-list uses {
+ type resource-id;
+ min-elements 1;
+ }
+ }
+
+ /* Information Resource Directory Grouping */
+ grouping IRD {
+ container meta {
+ uses IRD-meta;
+ }
+ uses IRD-data;
+ }
+
+ grouping IRD-data {
+ list resources {
+ key resource-id;
+ leaf resource-id {
+ type resource-id;
+ mandatory true;
+ }
+ leaf uri {
+ type inet:uri;
+ mandatory true;
+ }
+ leaf media-type {
+ type media-type;
+ mandatory true;
+ }
+ uses accepts {
+ when "current()";
+ }
+ uses IRD-capabilities {
+ when "current()";
+ }
+ uses uses {
+ when "current()";
+ }
+ description
+ "IRDResourceEntry. RFC7285 9.2.2." +
+ " object {
+ JSONString uri;
+ JSONString media-type;
+ [JSONString accepts;]
+ [Capabilities capabilities;]
+ [ResourceID uses<0..*>;]
+ } IRDResourceEntry;" +
+ "IRDResourceEntries. RFC7285 9.2.2." +
+ " object-map {
+ ResourceID -> IRDResourceEntry;
+ } IRDResourceEntries;" +
+ "InformationResourceDirectory. RFC7285 9.2.2." +
+ " object {
+ IRDResourceEntries resources;
+ } InfoResourceDirectory : ResponseEntityBase;";
+ }
+ }
+
+ /* Network Map Grouping */
+ grouping network-map {
+ container meta {
+ uses network-map-meta;
+ }
+ uses network-map-data;
+ }
+
+ grouping network-map-data {
+ list network-map {
+ key "pid";
+ leaf pid {
+ type pid-name;
+ }
+ uses endpoint-address-group;
+ description
+ "RFC7285 Sec. 11.2.1.6." +
+ " object-map {
+ PIDName -> EndpointAddrGroup;
+ } NetworkMapData;";
+ }
+ description
+ "Network map. RFC7285 Sec. 11.2.1.6." +
+ "object {
+ NetworkMapData network-map;
+ } InfoResourceNetworkMap : ResponseEntityBase;";
+ }
+
+ /* Cost Map Grouping */
+ grouping cost-map {
+ container meta {
+ uses cost-map-meta;
+ }
+ uses cost-map-data;
+ }
+
+ grouping cost-map-data {
+ list cost-map {
+ leaf src {
+ type pid-name;
+ description
+ "Source PID.";
+ }
+ key "src";
+ list dst-costs {
+ leaf dst {
+ type pid-name;
+ description
+ "Destination PID.";
+ }
+ key "dst";
+ uses alto-cost {
+ description
+ "Cost from source to destination.";
+ }
+ description
+ "The list represents the inner part of the cost matrix." +
+ "DstCosts. RFC7285 Sec. 11.2.3.6." +
+ " object-map {
+ PIDName -> JSONValue;
+ } DstCosts;";
+ }
+ description
+ "The list represents the outer part of the cost matrix." +
+ "CostMapData. RFC7285 Sec. 11.2.3.6." +
+ " object-map {
+ PIDName -> DstCosts;
+ } CostMapData;";
+ }
+ description
+ "Cost map. RFC7285 Sec. 11.2.3.6." +
+ " object {
+ CostMapData cost-map;
+ } InfoResourceCostMap : ResponseEntityBase;";
+ }
+
+ /* Endpoint Property Map Grouping */
+ grouping endpoint-property-map {
+ container meta {
+ uses endpoint-property-meta;
+ }
+ uses endpoint-property-map-data;
+ }
+
+ grouping endpoint-property-map-data {
+ list endpoint-properties {
+ key endpoint;
+ leaf endpoint {
+ type typed-endpoint-address;
+ mandatory true;
+ }
+ list properties {
+ key property-type;
+ leaf property-type {
+ type endpoint-property-type;
+ mandatory true;
+ }
+ leaf property {
+ type endpoint-property-value;
+ mandatory true;
+ }
+ description
+ "EndpointProps. RFC7285 Sec. 11.4.1.6." +
+ " object {
+ EndpointPropertyType -> JSONValue;
+ } EndpointProps;";
+ }
+ description
+ "EndpointPropertyMapData. Sec. 11.4.1.6." +
+ " object-map {
+ TypedEndpointAddr -> EndpointProps;
+ } EndpointPropertyMapData;";
+ }
+ description
+ "InfoResourceEndpointProperties. Sec. 11.4.1.6." +
+ " object {
+ EndpointPropertyMapData endpoint-properties;
+ } InfoResourceEndpointProperties : ResponseEntityBase;";
+ }
+}