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:
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:
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. |
{ 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. |
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.
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.
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 |
|
application/yang-identifiers+cbor-seq |
141 |
FETCH |
|
application/yang-instances+cbor-seq |
142 |
POST, iPATCH |
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.
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
GET
the <operational> datastoreREQ: GET </c>
RES: 2.05 Content (Content-Format: application/yang-data+cbor; id=sid)
See response data
GET
the <operational> datastore with configuration nodes onlyREQ: GET </c?c=c>
RES: 2.05 Content (Content-Format: application/yang-data+cbor; id=sid)
See response data
GET
the <startup> datastoreREQ: 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.
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.
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
PUT
into the <running> datastoreREQ: PUT </c>
(Content-Format: application/yang-data+cbor; id=sid)
See request data
RES: 2.04 Changed
PUT
into the <startup> datastoreREQ: 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.
REQ: DELETE <datastore resource> RES: 2.02 Deleted
DELETE
the <running> datastoreREQ: DELETE </c>
RES: 2.02 Deleted
DELETE
the <startup> datastoreREQ: 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.
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
FETCH
the checksum
leaf (SID 29304) from ietf-constrained-yang-library.yangREQ: 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' }
FETCH
the phys-address
leaf (SID 2044) of port 1 from ietf-interfaces.yangREQ: 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" }
FETCH
the two leaves above in a single operationREQ: 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" }
FETCH
the phys-address
leaf (SID 2044) of a non-existing port 100REQ: 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.
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
iPATCH
to add a static entry into the filtering databaseREQ: 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. |
iPATCH
to replace the filtering database with new static entriesREQ: 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. |
iPATCH
to delete a static entry from the filtering databaseREQ: 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