Technology: CORECONF

The CoAP Management Interface (CORECONF) is used to access datastore and data node resources in a VelocityDRIVE-SP device. It is documented in RFC TBD - 'CoAP Management Interface (CORECONF)'.

CORECONF uses CoAP/UDP as a transport protocol and CBOR as a payload format RFC 8949.

The connection to the CoAP server can either be made via MUP1 or IP and with or without DTLS (See Securing CoAP for additional details).

1. CORECONF Datastores

VelocityDRIVE-SP uses a datastore model similar to the NMDA model as defined in REF-RFC8342 - 'Network Management Datastore Architecture (NMDA)' as shown in this drawing:

cc ds

It consists of four datastores:

  • <running>

  • <operational>

  • <startup>

  • <factory-defaults>

1.1. <running>

The <running> datastore contains the current configuration of the device.
This datastore is writable and accessed through the CoAP path /c via the CoAP methods PUT, DELETE, and iPATCH.

1.2. <operational>

The <operational> datastore contains the <running> datastore and status data such as state and counters.
This datastore is read-only and accessed through the CoAP path /c via the CoAP methods GET and FETCH.

1.3. <startup>

The <startup> datastore is stored persistently in non-volatile memory. It contains configuration data only and has the same structure as the <running> datastore.
It is accessed through the CoAP path /startup-config via the CoAP methods GET, PUT, and DELETE.

1.4. <factory-defaults>

The <factory-defaults> datastore is located in the flash image. It contains configuration data only and has the same structure as the <running> datastore.

The <factory-defaults> datastore cannot be accessed via CoAP and therefore has no CoAP path.
It is stored in the flash image and can only be modified during a firmware update.

If no <startup> datastore is present at boot time, <factory-defaults> is copied to <running> during boot as shown in this drawing:

cc boot

2. Concise Binary Object Representation (CBOR)

CORECONF uses CBOR in all requests and responses.

CBOR is a binary data serialization format that is loosely based on JSON and is defined in RFC 8949.

CBOR is designed for use in constrained environments and the main design goals are:

  • Small code size

  • Small message size

  • Support for conversion to and from JSON

  • Extensibility without the need for version negotiation

The length of each CBOR data item is normally encoded in the item itself. However, byte strings, text strings, arrays, and maps can be encoded with an indefinite length, using a "break" stop code to terminate the item. This is useful if a constrained device needs to start transmitting an item before the total length is known.

The VelocityDRIVE-SP device understands both kinds of encoding but will normally encode arrays and maps as indefinite length items.

CORECONF uses the YANG-to-CBOR mapping to encode request and response payloads, as documented in RFC 9254 - 'CBOR Encoding of Data Modeled with YANG'.

3. CBOR Sequence Format

CORECONF makes use of CBOR sequences in some of the request and response payloads.

A CBOR sequence is simply a concatenation of independent CBOR items and is documented in RFC 8742 - 'Concise Binary Object Representation (CBOR) Sequences'.

4. CBOR Diagnostic Notation

CBOR diagnostic notation is used in CBOR examples as it is readable unlike the binary CBOR format.

Examples of CBOR Diagnostic Notation converted to CBOR HEX Notation using both implicit length and indefinite length notation:

Diag Notation CBOR HEX Notation Remarks
[ "foo", "bar" ]
82           # array(2)
   63        # text(3)
      666F6F # "foo"
   63        # text(3)
      626172 # "bar"

Implicit length array of text strings

[_ "foo", "bar" ]
9F           # array(*)
   63        # text(3)
      666F6F # "foo"
   63        # text(3)
      626172 # "bar"
   FF        # primitive(*)

Indefinite length array of text strings.
Note the use of '[_' instead of '[' and the FF primitive at the end.

{
  1: 42,
  2: "foo"
}
A2           # map(2)
   01        # unsigned(1)
   18 2A     # unsigned(42)
   02        # unsigned(2)
   63        # text(3)
      666F6F # "foo"

Implicit length map

{_
  1: 42,
  2: "foo"
}
BF           # map(*)
   01        # unsigned(1)
   18 2A     # unsigned(42)
   02        # unsigned(2)
   63        # text(3)
      666F6F # "foo"
   FF        # primitive(*)

Indefinite length map.
Note the use of '{_' instead of '{' and the FF primitive at the end.

The examples above are created with this online tool.

The Docker image contains the CBOR diagnostic utilities, which makes it possible to generate the same examples using the command line:

$ dr 'echo "[ \"foo\", \"bar\"]" | diag2pretty.rb'
82           # array(2)
   63        # text(3)
      666f6f # "foo"
   63        # text(3)
      626172 # "bar"
$ dr 'echo "[_ \"foo\", \"bar\"]" | diag2pretty.rb'
9f           # array(*)
   63        # text(3)
      666f6f # "foo"
   63        # text(3)
      626172 # "bar"
   ff        # primitive(*)
$ dr 'echo "{ 1:42, 2: \"foo\"}" | diag2pretty.rb'
bf           # map(*)
   01        # unsigned(1)
   18 2a     # unsigned(42)
   02        # unsigned(2)
   63        # text(3)
      666f6f # "foo"
   ff        # primitive(*)
$ dr 'echo "{_ 1:42, 2: \"foo\"}" | diag2pretty.rb'
a2           # map(2)
   01        # unsigned(1)
   18 2a     # unsigned(42)
   02        # unsigned(2)
   63        # text(3)
      666f6f # "foo"

Use diag2cbor.rb to generate the binary CBOR and save it in a file for later use:

$ dr 'echo "[ \"foo\", \"bar\"]" | diag2cbor.rb > tmp.cbor'

Use cbor2diag.rb to show the content of the binary CBOR file:

 $ dr 'cat tmp.cbor | cbor2diag.rb'
["foo", "bar"]

5. YANG Schema Item iDentifier (SID)

In order to be more compact, CORECONF uses globally unique identifiers instead of text strings, as used in the YANG specification. These identifiers are unsigned 63-bit integers and are called YANG Schema Item iDentifier or just SID.

To ensure that SIDs are globally unique, the SIDs must be allocated via The Internet Assigned Numbers Authority (IANA).

The allocation process and other details like .sid file format are documented in RFC 9595 - 'YANG Schema Item iDentifier (YANG SID)'

SIDs are allocated in ranges for each YANG module and the currently assigned ranges are documented in YANG SIDs.

Note that some of the YANG modules used in VelocityDRIVE-SP have not yet been assigned an official range. It is, therefore, expected that the temporarily assigned SID ranges will change in the future.

How to get the currently assigned SIDs for a specific firmware version of VelocityDRIVE-SP is explained here.

When used as keys in a CBOR map, they are encoded using deltas, except for the outermost map:

{
  1000 : {        // SID 1000
       1 : 100,   // SID 1001
      20 : 101    // SID 1020
  }
}

5.1. .yang and .sid files

The currently assigned SIDs for a single .yang file are stored in the corresponding .sid file.

The naming convention is as follows using ietf-interfaces.yang as an example:

ietf-interfaces.yang -> ietf-interfaces@2018-02-20.sid

The date part of the .sid filename corresponds to the newest revision found in the .yang file.

Example of how to create an initial .sid file for ietf-interfaces.yang using entry point 1500 and size 100:
dr pyang --sid-generate-file 1500:100 ietf-interfaces.yang

This will generate the .sid file ietf-interfaces@2018-02-20.sid, where SIDs are numbered from 1500 and up.

If ietf-interfaces.yang is modified and the revision is changed to e.g. 2025-01-01, then the .sid file must be updated without modifying the existing SID values.

Example of how to update a .sid file when ietf-interfaces.yang has been modified:
dr pyang --sid-update-file ietf-interfaces@2018-02-20.sid ietf-interfaces.yang

Note that the existing .sid file is used as input.

This will generate a new .sid file ietf-interfaces@2025-01-01.sid, where the previous SID values have been retained and the new SID values have been added.

5.2. YANG Catalog

When working with SIDs it is important to know the relationship between the SIDs and the corresponding YANG paths.

Each and every VelocityDRIVE-SP software release has a corresponding YANG catalog, which is a compressed file in tar.gz format that contains all relevant .yang and .sid files.

The filename is the checksum of the content followed by '.tar.gz', e.g.:

4e600dde441af320f35d89194ffd99fc.tar.gz

These YANG catalogs are stored at Microchips Open Source distribution on Amazon AWS and can be downloaded freely by anyone.

For instructions on how to read the checksum used in the filename, see here.

6. Media types

CORECONF uses three different variants of CBOR encoding in the CoAP payload. Each variant is defined as a CoAP Content Type (string) and an ID (numeric range 0-65535):

Content Type ID CoAP Method Reference

application/yang-data+cbor; id=sid

140

GET, PUT

RFC 9254

application/yang-identifiers+cbor-seq

141

FETCH

RFC TBD

application/yang-instances+cbor-seq

142

POST, iPATCH

RFC TBD

Note that ID 141 and 142 have not yet been officially assigned by IANA and might change in the future.

All currently defined CoAP Content-Formats are listed here.

6.1. application/yang-data+cbor; id=sid

The content is a CBOR map, mapping SIDs into instance values:

{
  1000 : {        // SID 1000
       1 : 100,   // SID 1001
      20 : 101    // SID 1020
  },
  2000 : {        // SID 2000
       1 : "foo", // SID 2001
      20 : "bar"  // SID 2020
      22 : 42     // SID 2022
  }
}

6.2. application/yang-identifiers+cbor-seq

The content is a CBOR sequence of instance-identifiers:

1000,                // Item one: SID 1000
[2000, "foo", "bar"] // Item two: SID 2000 with YANG keys "foo" and "bar"

6.3. application/yang-instances+cbor-seq

The content is a CBOR sequence, where each item is a CBOR map carrying an instance-identifier and its associated instance-value:

{
  1000 : 200                    // Item one: SID 1000
},
{
  [2000, "foo", "bar"] : null   // Item two: SID 2000 with keys "foo" and "bar"
},
{
  2000 : {                      // Item three: SID 2000
    1 : "foo",                  //   YANG key  SID 2001
   20 : "bar",                  //   YANG key  SID 2020
   22 : 84                      //   YANG leaf SID 2022
  }
}

7. CoAP methods

The CoAP methods supported by CORECONF are:

CoAP method CoAP
request Content ID
CoAP
response Content ID
Description

GET

n/a

140

Retrieve the datastore resource

POST

142

142

Invoke an RPC or action

PUT

140

n/a

Create or replace a datastore resource

DELETE

n/a

n/a

Delete a datastore resource

FETCH

141

142

Retrieve specific data nodes within a datastore resource

iPATCH

142

n/a

Create, replace and delete data node(s) within a datastore resource

Event streams (notifications) are not currently supported.

7.1. GET

GET is used to retrieve a whole datastore and operates on the <operational> and <startup> datastores.

The c and d query parameters are supported in connection with the <operational> datastore.

The returned success response code is 2.05 Content.

FORMAT:
REQ:  GET <datastore resource>

RES:  2.05 Content (Content-Format: application/yang-data+cbor; id=sid)
      CBOR map of one or more SIDs, instance-values
Example of how to GET the <operational> datastore
REQ:  GET </c>

RES:  2.05 Content (Content-Format: application/yang-data+cbor; id=sid)
See response data
Example of how to GET the <operational> datastore with configuration nodes only
REQ:  GET </c?c=c>

RES:  2.05 Content (Content-Format: application/yang-data+cbor; id=sid)
See response data
Example of how to GET the <startup> datastore
REQ:  GET </startup-config>

RES:  2.05 Content (Content-Format: application/yang-data+cbor; id=sid)
See response data

7.2. POST

POST is used to invoke an RPC or action.

The returned success response code is 2.04 Changed.

FORMAT:
REQ:  POST <datastore resource>
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of instance-identifier, instance-value

RES:  2.04 Changed
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of instance-identifier, instance-value

This example invokes the system-restart RPC (SID 19018) from ietf-system.yang:

REQ:  POST </c>
      (Content-Format: application/yang-instances+cbor-seq)
{_ 19018:
  null
}

RES:  2.04 Changed
      (Content-Format: application/yang-instances+cbor-seq)
{_ 19018:
  null
}

This example invokes the save-config RPC (SID 21007) from mchp-velocitysp-system.yang, to copy the <running> datastore to the <startup> datastore:

REQ:  POST </c>
      (Content-Format: application/yang-instances+cbor-seq)
{_ 21007:
  null
}

RES:  2.04 Changed
      (Content-Format: application/yang-instances+cbor-seq)
{_ 21007:
  null
}

This example invokes the fdb-flush action (SID 30001) from mchp-velocitysp-bridge.yang, to flush the filtering database for VID 100, port 2 entries:

REQ:  POST </c>
      (Content-Format: application/yang-instances+cbor-seq)
{_ [_ 30001, "b0", "c0" ]:
  {_
    2 : 100,
    1 : 2
  }
}

RES:  2.04 Changed
      (Content-Format: application/yang-instances+cbor-seq)
{ 30001:
  null
}

7.3. PUT

PUT is used to create or replace a whole datastore and operates on the <running> and <startup> datastores.

The returned success response code is 2.04 Changed.

FORMAT:
REQ:  PUT <datastore resource>
      (Content-Format: application/yang-data+cbor; id=sid)
      CBOR map of one or more SIDs, instance-values

RES:  2.04 Changed
Example of how to PUT into the <running> datastore
REQ:  PUT </c>
      (Content-Format: application/yang-data+cbor; id=sid)
See request data

RES:  2.04 Changed
Example of how to PUT into the <startup> datastore
REQ:  PUT </startup-config>
      (Content-Format: application/yang-data+cbor; id=sid)
See request data

RES:  2.04 Changed

7.4. DELETE

DELETE is used to delete a whole datastore and operates on the <running> and <startup> datastores.

The returned success response code is 2.02 Deleted.

FORMAT:
REQ:  DELETE <datastore resource>

RES:  2.02 Deleted
Example of how to DELETE the <running> datastore
REQ:  DELETE </c>

RES:  2.02 Deleted
Example of how to DELETE the <startup> datastore
REQ:  DELETE </startup-config>

RES:  2.02 Deleted

7.5. FETCH

FETCH is used to retrieve one or more instance-values, which can be either a container, a list, a leaf or a leaf-list.

FETCH operates on the <operational> datastore and the c and d query parameters are supported.

If the instance in question has one or more lists as parents, then the instance-identifier must include all keys needed to point out the specific instance.

If the instance in question is a list and none of the list’s own keys are included, then a list containing all entries is returned in the response.

If the instance in question is a list and all of the list’s own keys are included, then a single entry is returned in the response.

If the instance in question is not found, then the value null is returned in the response.

FORMAT:
REQ:  FETCH <datastore resource>
      (Content-Format: application/yang-identifiers+cbor-seq)
      CBOR sequence of instance-identifiers

RES:  2.05 Content
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of SID, instance-value
Example of how to FETCH the checksum leaf (SID 29304) from ietf-constrained-yang-library.yang
REQ:  FETCH </c>
      (Content-Format: application/yang-identifiers+cbor-seq)
29304

RES:  2.05 Content
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of SID, instance-value
{_
  29304: h'4E600DDE441AF320F35D89194FFD99FC'
}
Example of how to FETCH the phys-address leaf (SID 2044) of port 1 from ietf-interfaces.yang
REQ:  FETCH </c>
      (Content-Format: application/yang-identifiers+cbor-seq)
[_ 2044, "1" ]

RES:  2.05 Content
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of SID, instance-value
{_
  2044: "12-4C-AE-C0-BC-01"
}
Example of how to FETCH the two leaves above in a single operation
REQ:  FETCH </c>
      (Content-Format: application/yang-identifiers+cbor-seq)
29304,
[_ 2044, "1" ]

RES:  2.05 Content
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of SID, instance-value
{_
  29304: h'4E600DDE441AF320F35D89194FFD99FC'
},
{_
  2044: "12-4C-AE-C0-BC-01"
}
Example of an attempt to FETCH the phys-address leaf (SID 2044) of a non-existing port 100
REQ:  FETCH </c>
      (Content-Format: application/yang-identifiers+cbor-seq)
[_ 2044, "100" ]

RES:  2.05 Content
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of SID, instance-value
{_
  2044: null
}

7.6. iPATCH

iPATCH is used to create, replace, and delete one or more instance-values, which can be either a container, a list, a leaf or a leaf-list.

iPATCH operates on the <running> datastore.

If the instance in question has one or more lists as parents, then the instance-identifier must include all keys needed to point out the specific instance.

If the instance in question is a list and the instance value is non-null, it is not allowed to include any of the list’s own keys in the instance identifier.

If the instance in question is a list and the instance value is null, then it is a delete request, and all of the list’s own keys must be included.

If the instance in question is a list and the instance value is a container, then the new container is either added to the list or replaces the existing instance in the list.

If the instance in question is a list and the instance value is a list, then the new list replaces the old list, i.e. all old entries in the list will be deleted.

FORMAT:
REQ:  iPATCH <datastore resource>
      (Content-Format: application/yang-instances+cbor-seq)
      CBOR sequence of CBOR maps of instance-identifier, instance-value

RES:  2.04 Changed
Example of how to use iPATCH to add a static entry into the filtering database
REQ:  IPATCH </c>
      (Content-Format: application/yang-instances+cbor-seq)

{_
    [_ 7083, "b0", "c0"]: {_
        2: 0,
        1: "00-00-00-00-00-11",
        21: "42",
        3: 0,
        4: [_ {_ 15: 1}]
    }
}

RES:  2.04 Changed
In the example above the instance in question is a list (SID 7083) and the instance value is a container. This will add or replace the instance value in the list.
Example of how to use iPATCH to replace the filtering database with new static entries
REQ:  IPATCH </c>
      (Content-Format: application/yang-instances+cbor-seq)

{_
    [_ 7083, "b0", "c0"]: [_
        {_
            2: 0,
            1: "00-00-00-00-00-11",
            21: "42",
            3: 0,
            4: [_ {_ 15: 1}]
        },
        {_
            2: 0,
            1: "00-00-00-00-00-22",
            21: "42",
            3: 0,
            4: [_ {_ 15: 2}]
        }
    ]
}

RES:  2.04 Changed
In the example above the instance in question is a list (SID 7083) and the instance value is also a list. This will replace the existing list with the new list.
Example of how to use iPATCH to delete a static entry from the filtering database
REQ:  IPATCH </c>
      (Content-Format: application/yang-instances+cbor-seq)

{_
    [_ 7083, "b0", "c0", 0, "42", "00-00-00-00-00-11"]: null
}

RES:  2.04 Changed