Skip to content

About

ieee1905 implementation in Rust

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

 
 

Repository files navigation

IEEE1905.1 RDK-B component

🌐 IEEE1905.1 Overview

IEEE 1905.1 is a standard developed by the Institute of Electrical and Electronics Engineers (IEEE) for providing a uniform method for devices to communicate and interoperate within a home network environment. It defines a protocol that enables devices from different manufacturers to seamlessly communicate and share resources, regardless of their underlying technologies.

One of the key components of IEEE 1905 is the Application Layer SAP, which is responsible for managing communication between the higher-level entities (HLEs) and the lower layers of the network stack, and more specifically the IEEE 1905 adaptation layer. In order to identify multiple SAPs between AL and HLE layers, we identify the SAP as the AL_MAC_ADDRESS of the remote entity.

🗺 IEEE1905.1 Roadmap

A short, high-level plan:

  • Topology map.
  • FSM definition and implementation.
  • Adaptation Layer Service Access Point for Easymesh High Level Entities.
  • LLDP implementation.
  • IEEE1905 CMDU parsing and serialization (version 2023)
  • Docker integration for stand-alone.
  • RDK integration.
  • OWRT integration.
  • TR.181 data-model integration using RBUS
  • Link Metric management and topology inegration.
  • Interoperability.
  • IEEE1905 CMDU parsing and serialization (version 2024)
  • Controller Redundancy.
  • Artifact Exchange Service from Controller to Agents.
  • Service binary upgrade.
  • IEEE1905 Layer security capability Message integrity code.
  • IEEE1905 Layer security capability encryption.

Architecture Decisions (ADRs)

This project documents its key architectural decisions using Architecture Decision Records (ADRs). These decisions define the protocol design, topology handling, and integration model with EasyMesh on Linux-based platforms.

Core Architecture

Platform & Networking Model

EasyMesh Integration Model

Topology State Management

Operational & Resilience Concerns

IEEE1905 Service functional requirements

Functional Requirement Description
Activation process SAP will provide the API's necessary to activate the transport service from the EasyMesh Agent and Controller through the AL_SAP
Registration request SAP will provide the API necessary to activate and deactivate the transport service through the SAP and to identify the role ot the applicatoin that requests access to IEEE1905 layer
Registration response SAP will provide the API necessary to provide the response to a registration request to the IEEE1905 service including the result of the registration request and any information necessary to make use of the transport service
Payload transport EasyMesh agent, EasyMesh Controller and any other High Level Entity will use binary payload through SAP as transport using SDUs defined as part ot the AL_SAP definition and AL_SAP API (primitives) for data transmission and reception
Content Agnostic AL_SAP will be agnostic in regards of the content of the SDU's, they will treated as as binary payload through the AL_SAP and at the IEEE1905 layer they will be treated as CMDU's (framing functionality) or as a vector of TLV's (parsing functionality)
CMDU responsability IEEE1905 SAP will provide payload transport service of EasyMesh CMDU's in addition to the CMDU's used internally by the IEEE1905 to maintain the topology map
CMDU validation IEEE1905 will be responsible for the completeness of CMDU's sent and received
SDU/CMDU fragmentation IEEE1905 SAP will provide fragmentation and reassembly service for SDU's and CMDU's
CMDU encryption IEEE1905 will provide encryption service and message integrity validation for CMDU's

🧩 IEEE1905 Software Stack

In current implementations of EasyMesh, the IEEE1905 stack is deeply integrated into both the EasyMesh agents and controller. This tight coupling between the two standards means that the functionalities of IEEE1905, which handles the transport of network information, and EasyMesh, which manages mesh network control, are often intertwined within the same system components.

However, in our implementation, we found it necessary to clearly separate the EasyMesh functionalities from the IEEE1905 stack. This separation allows for more modular design and flexibility, enabling independent development, testing, and maintenance of each protocol. By decoupling EasyMesh from IEEE1905, we ensure that each layer can evolve independently while maintaining interoperability, which is particularly important in complex mesh networking environments. This also allows for clearer distinction between mesh network management (EasyMesh) and control transport services and topology management (IEEE1905), improving the overall system architecture. The IEEE1905 SAP will be used as C++ library compiled as part of application binaries that will be required to use IEEE1905 transport service, and the implementation will follow OOP principles of reusability and modularity.

🔌 IEEE1905 Adaptation Layer MAC Service Access Point

IEEE1905 Adaptation Layer MAC Service Access Point will provide IEEE1905 transport service to applications in the RDK-B stack through a set of service primitives. These primitives have been creted with two goals in mind, registration of consumers that will make use of the IEEE1905 stack, using service-registration-request and service-registration-response APIs and exchange of service data units via service-data-request and service-data-indication, through the AL MAC service access point, refered as SAP in the rest of the document.

AL MAC SAP API's

The IEEE1905_AL_SAP will provide the following API abstraction to use the service:

  1. Registration APIs: it will be used to register the application (EMagent or EMcontroller for instance) to access the SAP, initializing parameters that the application could require from the IEEE1905 service.
    1. AlServiceRegistrationRequest(): This primitive is used to establish the connection to the IEEE1905 service. The application will register to use one of the services currently supported by the IEEE1905 service:
      1. EasyMeshClient: it will use standard IEEE1905 framing, assuming the application is the Controller/Registree.
      2. EasyMeshController: it will use standard IEEE1905 framing, assuming the application is the Controller/Registrar.
    2. AlServiceRegistrationResponse(): This primitive is used by the IEEE1905 service to inform about the result of the registration and to provide the local AlMacAddress in case the application cannot select one.
    3. AlServiceTopologyNotification(): This primitive is used by the IEEE1905 service to keep the cache of the al_mac addresses availabe in the topology map so if the HLE tries to send an SDU to a node which al_mac is not in the cache, IEEE1905 service will generate a primitive error, in a shape of a C++ exception according to C++ standard library.
sequenceDiagram

    activate Agent
    participant Agent as "EasyMeshComponent"
    participant IEEE1905_AL_AGENT as "IEEE1905_AL_SAP"


    Agent ->> IEEE1905_AL_AGENT: AlServiceAccessPointRegistrationRequest(EasyMeshServiceType, Enable/disable)

    IEEE1905_AL_AGENT -->> Agent: AlServiceAccessPointRegistrationResponse(RegistrationResult,AlMacAddressLocal)

    opt
        Note right of Agent: In case of error
        IEEE1905_AL_AGENT -->> Agent: PrimitiveError::ErrorType
    end

    deactivate Agent
Loading
  1. Control plane transport service APIs.

    1. AlServiceDataRequest(): This API is used to request the transmission of a SDU (service data unit) to the IEEE1905 service through the SAP, and the SDU will contain, the IEEE1905 CMDU and the AlMacAddress of the source and destination. In case of SDU processing errors during SAP transfer for transmission, IEEE1905 service will generate a primitive error, in a shape of a C++ exception according to C++ standard library.
    2. AlServiceDataIndication(): This API is used by applications to listen and receive a SDUs (service data unit) from the IEEE1905 service through the SAP, as before for the request,the SDU will contain the IEEE1905 CMDU created by the remote application, plus AlMacAddress source and destination. In case of SDU processing errors during SAP transfer for reception, IEEE1905 service will generate a primitive error, in a shape of a C++ exception according to C++ standard library.
sequenceDiagram

    activate Agent
    participant Agent as "EasyMeshComponent (AL_MAC_X)"
    participant IEEE1905_AL_AGENT as "IEEE1905.1_SAP_OUTBOUND"
    participant IEEE1905_AL_CONTROLLER as "IEEE1905.1_SAP_INBOUND"
    participant Controller as "EasyMeshComponent (AL_MAC_Y)"


    Agent ->> IEEE1905_AL_AGENT: ServiceAccessPoint.Request[SDU (AL_MAC_SOURCE,AL_MAC_DESTINATION, CMDU)]
    opt
        Note right of Agent: In case of Error
        IEEE1905_AL_AGENT -->> Agent: PrimitiveError::ErrorType
    end
    IEEE1905_AL_AGENT ->> IEEE1905_AL_CONTROLLER: Transmit(CMDU)



    IEEE1905_AL_CONTROLLER ->> Controller: ServiceAccessPoint.Indication[SDU (AL_MAC_SOURCE,AL_MAC_DESTINATION, CMDU)]

    opt
        Note left of Controller: In case of Error
        IEEE1905_AL_CONTROLLER -->> Controller: PrimitiveError::ErrorType
    end



    deactivate Agent
Loading

🔁 IEEE1905 Finite State Machines

Finite State machine Diagram (Topology Convergence)

ARCH

Input Event Precondition New Local New Remote Output event
DiscoveryReceived (node_new) — Idle Idle SendTopologyQuery(al_mac)
DiscoveryReceived (Idle) Local == Idle (unchanged) (unchanged) SendTopologyQuery(al_mac)
DiscoveryReceived (conv) Local == ConvergedLocal (unchanged) (unchanged) None
NotificationReceived (conv) Local == ConvergedLocal Idle (unchanged) SendTopologyQuery(al_mac)
NotificationReceived !Local == ConvergedLocal (unchanged) (unchanged) None
QueryReceived (node_new) — Idle ConvergingRemote(now) SendTopologyResponse(al_mac)
QueryReceived (node_present) !Remote == ConvergedLocal (unchanged) ConvergingRemote(now)* SendTopologyResponse(al_mac)
QuerySent !Local == ConvergedLocal ConvergingLocal(now) (unchanged) None
ResponseReceived Local == ConvergingLocal ConvergedLocal (unchanged) Maybe SendTopologyNotification(multic)
ResponseSent Remote= ConvergingRemote (unchanged) ConvergedRemote None

* Only if remote wasn’t already ConvergedRemote.

Finite State machine Diagram (AL_MAC destination table look up)

ARCH

Input Event Precondition New State Output Event
IEEE1905-UP Local == INIT LEARNING None
IEEE1905-DOWN Local == LEARNING INIT None
AP_AUTOCONFIG_SEARCH Local == LEARNING && AL_MAC_PRESENT FORWARDING StartForwarding
TOPOLOGY_DISCOVERY Local == LEARNING && AL_MAC_PRESENT FORWARDING StartForwarding
AL_MAC_REMOVED Local == FORWARDING LEARNING StopForwarding
AL_MAC_PRESENT Local == FORWARDING (unchanged) None

Finite State machine Diagram (CMDU Forwarding)

ARCH

Input Event Precondition New State Output Event
HLE_REGISTRATION_SUCCESS State == INIT Registered None
HLE_REGISTRATION_ERROR State == INIT INIT None
SAP_ENABLE State == Registered Forwarding None
SAP_DISABLE State == Forwarding Registered None
EM_CMDU_INCOMING State == Forwarding && AL_MAC (unchanged) Forward
EM_CMDU_INCOMING State == Forwarding && !AL_MAC (unchanged) Discard
EM_CMDU_FORWARDING State == Forwarding && AL_MAC (unchanged) Forward
EM_CMDU_FORWARDING State == Forwarding && !AL_MAC (unchanged) Discard

🧱 Architecture

ARCH


🧠 Network Topology Services

Network topology refers to the arrangement of various elements (IEEE1905 nodes) in a home network and it defines how nodes are connected and how data flows between them. IEEE1905 has been specified to work in multiple topologies but it is specially used in daisy chain topologies as the one in EasyMesh, where typically each device is connected to two other devices, forming a linear sequence, much like the links in a chain.

Based on the capability of devices to process IEEE1905 CMDU packets we can distinguish two different kind of nodes:

  1. IEEE1905 devices: This kind of devices understand CMDU packets and keep a copy of the topology map that they can exchange with other IEEE1905 devices
    1. Endpoint nodes: The first and last devices in the chain have only one connection each, to their immediate neighbor and they don't require to have bridging capabilities.
    2. Intermediate nodes: Devices with more than one link connected to a IEEE1905 device with bridging capabilities, to relay CMDU packets through interfaces.
  2. NON-IEEE1905 devices: This kind of devices don't understand and process IEEE1905 packets In addition to the previous roles in IEEE1905 will build the topology map, adding information related to NON IEEE1905 devices, these devices will not participate in the exchange of CMDU packets, but based on their bridging capabilities they will be able to rely CMDU packets through their bridges.

Topology build Call Flow


ARCH


The topology construction process in IEEE1905 consists of the following steps:

  1. LLDP discovery: Before CMDU packet exchange, IEEE1905 will trigger LLDP protocol to discover neighbors with bridging capabilities, and include it as part of the topology graph. LLDPDUs use a link-local multicast address being consumed by the platform bridge, such as a Linux bridge or OVS bridge, so in the RDK-B use case they will not reach the IEEE1905 service.

  2. Topology Discovery Advertisement: Each IEEE1905 device periodically broadcasts 1905 Topology Discovery Messages on all its available network interfaces (Wi-Fi, Ethernet, MoCA, PLC). These messages include the AL_MAC address as well as the device's Media Access Control (MAC) address and details about the specific interface over which the message is sent.

  3. Neighbor Discovery: Devices that receive the topology discovery messages recognize the sender as a neighboring IEEE1905 device. The receiving device stores this information, including the AL_MAC address of the sender and the MAC address of the interface on which the message was sent, in its local topology map.

  4. Topology Query and Report: To get a more detailed view of the network, a device will send a Topology Query Message to any of its neighboring devices. The queried device responds with a Topology Response Message, which contains more comprehensive information about the network topology, including all the devices it knows and their interconnections.

  5. Topology Map Update: As devices exchange topology information, each IEEE1905 device updates its local topology map. This map contains information about all known devices in the network, the technologies they are using, the interfaces through which they are connected, and the quality of the paths used to reach them. As result of updates in the topology map, IEEE1905 devices will broadcast Topology Notification to all their neighbors, and their neighbors will retrieve the information using Topology Query/Report messages from teh originator of the modification.

  6. Periodic Refresh: The topology discovery process is continuous, with devices periodically re-broadcasting their presence and updating their topology databases as they receive new information. This ensures that the topology information remains current, even as devices join, leave, or move within the network.

  7. Split Brain scenario protection. The topology graph shall contain no more than one registrar per network based on a tie-breaking policy defined temporary using AL_MAC address last 4 bytes.

  8. 1905 Layer Security Capability. [Future improvement; not currently implemented.] According to EasyMesh specification chapters 13.1, 17.2.67, 17.2.68, 17.2.69, we will provide encryption and message integrity service for the TLV's.


Protection against split brain scenario

The protection against split brain scenraio will work as follow:

  1. When the AL_SAP receives a registration request from the HLE to assume the controller role, the IEEE1905 entity shall verify whether a registrar is already present in the network.
  2. If no registrar is detected, the HLE shall assume the registrar role. In this case, AL_SAP shall:
    2.1 Accept incoming ServiceRequest SDUs containing AP_Autoconfig_Search messages.
    2.2 Transmit outgoing SDUs containing AP_Autoconfig_Response messages.
    2.3 A topology Notification will be generated and as part of the Toplogy convergence flow.
  3. If a registrar is detected, the AL_SAP shall perform the tie-breaking procedure:
    3.1 If the local entity wins, AL_SAP shall accept incoming ServiceRequest SDUs containing AP_Autoconfig_Search messages and transmit outgoing CMDUs containing AP_Autoconfig_Response messages.
    3.2 If the remote entity wins, AL_SAP shall filter all AP_Autoconfig SDUs.
    3.3 In case the topology map changes we will proceed as in point 2.3 to propagate the new role.
  4. If the current registrar becomes unavailable, as determined through topology convergence flow, a new registrar shall be selected as part of the network convergence process, following steps 1 through 3.
  5. If a new registrar is detected through topology-discovery-triggered convergence, registrar selection shall again be performed as part of the network convergence process, following steps 1 through 3.
  6. When the AL_SAP receives a registration request from the HLE to assume the agent role, the IEEE1905 will propagate it as part of the topology convergence flow.

Remark: SDU filtering is currently inactive; the implementation only tracks which entity is acting as the registrar and which entities are acting as enrollees.


ARCH


IEEE1905.1 Forwarding Table

The forwarding table will be used to select the MAC address for source and destination used in the ethernet frames, based on the AL MAC source address and destination, to transport CMDU packets.

Below an example for 2 devices directly connected to our local device.

graph TD;
    Local_AL_MAC_ADDRESS_XX:XX:XX:XX <--> Local_virtual_interface_XX:XX:XX:XX;

    Local_virtual_interface_XX:XX:XX:XX <--> bridge_interface_AA:AA:AA:AA_VLAN100;
    Local_virtual_interface_XX:XX:XX:XX <--> bridge_interface_AA:AA:BB:BB_VLAN101;

    bridge_interface_AA:AA:AA:AA_VLAN100 <--> 802.1Q_local_tag_100;
    802.1Q_local_tag_100 <--> local_physical_interface_AA:AA:AA:AA;
    local_physical_interface_AA:AA:AA:AA --- |COST_DOWN| link_1;
    link_1 ---  |COST_UP| remote_physical_interface_AA:BB:BB:BB;
    remote_physical_interface_AA:BB:BB:BB <--> 802.1Q_remote_tag_100;
    802.1Q_remote_tag_100 <--> BRIDGE_Chassis_ID_XX:XX:YY:YY;
    BRIDGE_Chassis_ID_XX:XX:YY:YY <--> remote_logical_interface_AA:BB:BB:BB_VLAN100;

    remote_logical_interface_AA:BB:BB:BB_VLAN100 <--> Neighbour_AL_MAC_ADDRESS_YY:YY:XX:XX

    bridge_interface_AA:AA:BB:BB_VLAN101 <--> 802.1Q_local_tag_101;
    802.1Q_local_tag_101 <--> local_physical_interface_AA:AA:BB:BB;
    local_physical_interface_AA:AA:BB:BB --- |COST_DOWN| link_2;
    link_2 ---  |COST_UP| remote_physical_interface_AA:BB:BB:CC;
    remote_physical_interface_AA:BB:BB:CC <--> 802.1Q_remote_tag_101;
    802.1Q_remote_tag_101 <--> BRIDGE_Chassis_ID_XX:XX:XX:XX;
    BRIDGE_Chassis_ID_XX:XX:XX:XX <--> remote_logical_interface_MAC_ADDRESS_AA:BB:BB:CC_VLAN101;
    remote_logical_interface_MAC_ADDRESS_AA:BB:BB:CC_VLAN101 <--> Neighbour_AL_MAC_ADDRESS_XX:XX:YY:YY;

Loading

IEEE1905.1 Topology Map

The topology map provides all the information collected through Topology CMDUs exchange

|─TOPOLOGY_MAP:
└──AL_MAC_ADDRESS: AA:AA:AA:A0
    |
    └── INTERFACE_MAC_ADDRESS: (BB:AA:AA:A0)
        |── MEDIA_TYPE: (0x0001)
        |── BRIDGE_FLAG: TRUE
        |── BRIDGE_TUPLE: 0
        └── VLAN: 'UNTAG'
            |
            |── IEEE1905NeighborDeviceList
            |	|── IEEE1905NeighborDevice
            |	|       |── AL_MAC_ADDRESS: (AA:AA:AA:A1)
            |	|       |── INTERFACE_MAC_ADDRESS: (BB:AA:AA:A1)
            |	|	    |── STATE: TOPOLOGY_STATE
            |	|	    |── LAST_SEEN: 10
            |	|	    |── MESSAGE_ID_LAST_PACKET: 12
            |	|		|── LLDP-INFO
            |	|   	|── PATH_METRICS
            |	|	    |	|── RADIO
            |	|	    |	└── PATH_PERFORMANCE
            |	|	    └── LocalInterfaceList
            |	|	    	|── INTERFACE_MAC_ADDRESS: BB:AA:AA:A01
            |	|	    	|	|── MEDIA_TYPE: (0x0001)
            |	|	    	|	|── BRIDGE_FLAG: TRUE
            |	|	    	|	|── BRIDGE_TUPLE: 0
            |	|	    	|	└── NonIEEE1905NeighborList
            |	|	    	|		|── (AA:BB:CC:A0)]
            |	|	    	|		|── (AA:BB:CC:A1)]
            |	|			|		└── (AA:BB:CC:A2)]
            |	|	    	└──INTERFACE_MAC_ADDRESS: BB:AA:AE:A01
            |	|			    |── MEDIA_TYPE: (0x0001)
            |	|			    |── BRIDGE_FLAG: TRUE
            |	|			    |── BRIDGE_TUPLE: 0
            |	|			    └── NonIEEE1905NeighborList
            |	|			    	|── (AA:BF:CC:A0)]
            |	|			    	|── (AA:BF:CC:A1)]
            |	|			    	└── (AA:BF:CC:A2)]
            |	|
            |	└── IEEE1905NeighborDevice
            |	   
            └── NonIEEE1905NeighborList
                |── (AA:BB:CC:A0)]
                |── (AA:BB:CC:A1)]
                └── (AA:BB:CC:A2)]

🛠️ Installation

Prerequisites

  1. Ensure that you have systemd installed on your system.

  2. Ensure you include in your system rustc and cargo version 1.91.1 (MSRV).

  3. Ensure git is installed in your system.

  4. Ensure jq is installed in your system.

  5. Ensure you can run the script with sudo privileges.

  6. Ensure the script is executable.

Logging

Logs produced by the application will be stored into /var/log/rdkb-ieee1905/ and the configuration will be included as part of systemd unit configuration.

Log rotation will be possible as part of the installation script by changing /etc/logrotate.d/rdkb-ieee1905:

   /var/log/rdkb-ieee1905/*.log {
   daily
   rotate 7
   compress
   missingok
   notifempty
   create 0640 rdkbuser rdkbgroup
   postrotate
       systemctl restart rdkb-ieee1905.service > /dev/null
   endscript
}

Install the Application into your machine

All the logic for the installation and activation has been included into the build_and_install script:

    git clone https://github.com/rdkcentral/rdkb-ieee1905.git
    cd rdkb-ieee1905/utils
    ./build_and_install

Managing the Service

You can use this simple systemd unit to launch the ieee1905 service in the background. Set -i/--interface to the forwarding interface used by the platform; IEEE1905 derives the related bridge from this interface during local interface discovery:

cat /lib/systemd/system/ieee1905.service
[Unit]
Description=IEEE1905 topology service
After=network.target

[Service]
Type=notify
ExecStart=/usr/bin/ieee1905 -i eth0

[Install]
WantedBy=multi-user.target

The service uses sd-notify when it is launched by systemd. After the AL-SAP socket is ready to serve registrations and data indications, IEEE1905 sends a READY=1 notification. When the process receives SIGTERM or SIGINT, it sends STOPPING=1 before exiting. If the AL-SAP socket closes internally, the service attempts to restart that socket path without reporting the whole process as stopping.

EasyMesh services can then be launched as dependent systemd units. The EasyMesh unit should start after ieee1905.service, request it as a dependency, and be stopped/restarted with it when the IEEE1905 service lifecycle is managed:

[Unit]
Description=EasyMesh Monitor
Wants=ieee1905.service
After=ieee1905.service
PartOf=ieee1905.service

[Service]
Type=simple
ExecStart=/usr/local/bin/easymesh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Once installed into the systemd service path (/lib/systemd/system), you can enable the service and manage it like so:

systemctl daemon-reload
systemctl enable ieee1905.service
systemctl start ieee1905
systemctl stop ieee1905

Output from the ieee1905 process can be viewed via journalctl:

journalctl -u ieee1905.service
2025 Mar 28 01:09:50 armefi64-rdk-broadband systemd[1]: Started IEEE1905 topology service.
2025 Mar 28 01:09:51 armefi64-rdk-broadband ieee1905[1242]: Tracing initialized!

Service command line arguments

By default, the service runs with the topology CLI disabled, info log level, listening on eth0 interface, and Unix sockets named /tmp/al_control_socket and /tmp/al_data_socket.

Enable topology CLI

By default, topology CLI is disabled and requires topology_ui feature flag. When topology CLI is enabled. Log files are saved to a file and will not appear on standard output.

/usr/bin/ieee1905 -t

Console logger

By default, logs will be printed to stdout. Use following command to disable stdout logging:

/usr/bin/ieee1905 --no-stdout-appender

Enable artifact exchange

By default, artifact exchange is disabled. Enable it with --artifact-exchange <server|client>.

Run the controller-side HTTP artifact exchange service with:

/usr/bin/ieee1905 --artifact-exchange server

Run an agent-side artifact exchange client with:

/usr/bin/ieee1905 --artifact-exchange client

Use server on the controller node that exposes artifacts for agents and receives uploaded agent artifacts. Use client on agent nodes that pull controller-to-agent artifacts such as binaries and push agent-to-controller artifacts such as logs.

For systemd deployments, add the same argument to ExecStart, for example:

ExecStart=/usr/bin/ieee1905 --artifact-exchange server

File logger

By default, file logger is disabled. To enable file logging use following arguments:

/usr/bin/ieee1905 --file-appender ./logs

This will write logs to the folder ./logs.

File logs rotation

File logs will rotate on a daily basis and also have files count and file size limits.

Those limits can be changes with the following arguments:

/usr/bin/ieee1905 \
    --file-appender ./logs \
    --file-appender-files-count 3 \
    --file-appender-max-file-size 10

Change log level

Possible log levels are:

  • tracing - should be used only for deep debugging, enables all logs and dumps all packets
  • debug - provides a general debugging information
  • info - entry points and important events
  • warn - unexpected states that don't affect the logic
  • error - errors can unexpected states
  • off - disables all logging

To enable error logs for all app modules except crates:

/usr/bin/ieee1905 -f ieee1905=error

To enable trace logs for every module and crates:

/usr/bin/ieee1905 -f trace

Logging can be limited to certain modules for example to set trace level for topology manager and suppress all other logs:

/usr/bin/ieee1905 -f ieee1905::topolgy_manager=trace

If needed certain module can be filtered out completely:

/usr/bin/ieee1905 -f ieee1905=trace,ieee1905::ethernet_subject_reception=off

With above all ieee1905 modules will log with trace level and ethernet_subject_reception will not be visible in logs.

If needed to fully disable the logging:

/usr/bin/ieee1905 -f off

OR

RUST_LOG=off /usr/bin/ieee1905
Available modules
ieee1905::rbus
ieee1905::al_sap
ieee1905::cmdu_codec
ieee1905::cmdu_handler
ieee1905::cmdu_message_id_generator
ieee1905::cmdu_observer
ieee1905::cmdu_proxy
ieee1905::cmdu_reassembler
ieee1905::device_edge_manager
ieee1905::ethernet_subject_reception
ieee1905::ethernet_subcjet_transmission
ieee1905::interface_manager
ieee1905::lldpdu_codec
ieee1905::lldpdu_observer
ieee1905::lldpdu_proxy
ieee1905::registration_codec
ieee1905::sdu_codec
ieee1905::tlv_cmdu_codec
ieee1905::tlv_lldpdu_codec
ieee1905::topology_manager

Enable console subscriber

In order to analyze service with tokio-console use:

/usr/bin/ieee1905 -c

Disable LLDP revivers

In order to disable LLDP receiver workers use:

/usr/bin/ieee1905 --no-lldp-receivers

Enable active topology discovery

By default, topology is built by observing the EasyMesh Topology Query and Topology Response exchange instead.

When active mode is enabled, the service drives topology convergence itself: a received Topology Discovery triggers a Topology Query, and a topology change is announced with a Topology Notification.

/usr/bin/ieee1905 --active-mode

Change unix socket

Change unix sockets to ctrl.sock and data.sock

/usr/bin/ieee1905 --sap-control-path /tmp/ctrl.sock --sap-data-path /tmp/data.sock

Change listening interface

Change interface to eth1. IEEE1905 uses this interface to derive the related bridge and filter the local interface list accordingly.

/usr/bin/ieee1905 -i eth1

Enable file output

/usr/bin/ieee1905 -i eth1 --file-appender

Build options

IEEE1905 service can be build with few compile time features:

  • rbus - enable RBUS provider
  • enable_tokio_console - enable tokio-console

By default, RBUS provider is not included in the binary. In order to enable it one has to build with following command:

cargo build --package ieee1905 --release --features=rbus

RBUS-enabled builds require a GNU toolchain. It will be selected by default when building on the target machine. In case it was not selected by default or the binary is cross-compiled, it should be provided manually:

cargo build --package ieee1905 --release --features=rbus --target aarch64-unknown-linux-gnu

By default, tokio-console is not included in the binary. In order to enable it one has to build with following command:

cargo build --package ieee1905 --release --features=enable_tokio_console

All features can be enabled at once without listing all them:

cargo build --package ieee1905 --release --all-features

Will enable all supported features.

Yocto integration

For the best experience, use the meta-lts-mixins layer to upgrade the version of Rust from that included in OpenEmbedded.

   git clone --branch=kirkstone/rust https://git.yoctoproject.org/meta-lts-mixins
   bitbake-layers add-layer meta-lts-mixins

You can use cargo-bitbake to generate a BitBake recipe for this package.

As BitBake/Yocto builds do not have network access during the build cycle, it is a requirement that the entire dependency graph for the package is added to SRC_URI (including optional packages that are not used at runtime).

cargo-bitbake can generate the SRC_URI additions for you.

On Yocto 5 (scarthgap and later), you will also need to supply checksums for each package in the dependency graph.

You can use Yocto's cargo-update-recipe-crates to assist in updating the dependency graph.

Note: Cargo.lock must be up to date (run cargo update) with Cargo.toml, and with the recipe SRC_URI list, or Bitbake will not proceed with building the package.

# Ensure Rust and Cargo are available
inherit cargo

DESCRIPTION = "IEEE 1905 Rust Program"
LICENSE = "Apache-2.0"
LIC_FILES_CHKSUM = "file://LICENSE;md5=b538373fe584898492d2ad3a91014d58"

# Source repository
SRC_URI = "git://git@github.com/rdkcentral/rdkb-ieee1905.git;branch=main;protocol=ssh"
SRCREV = "589eccc05be0201592d169597c254375ef8d516c"

# Source directory
S = "${WORKDIR}/git"

# IMPORTANT!
# RUST_PANIC_STRATEGY="abort" must be in the
# machine or bitbake local.conf for this
# package to build successfully

# Builds under bitbake do not have network
# access, so all dependent rust crates
# must be added as SRC_URI
# You can use cargo-bitbake to create this list
SRC_URI += " \
    crate://crates.io/addr2line/0.24.2 \
    crate://crates.io/adler2/2.0.0 \
    ...
\"

Cross compilation to target Yocto (without bitbake)

There are two considerations when cross-compiling for a Yocto environment.

  1. Architecture

    We are using the 64-bit Arm (arm64/aarch64) SystemReadyArm compliance program environment for verification.

    Most people use x86/Intel architecture devices for development. If you have a native Arm64 development environment, you will have a smoother experience, but the considerations below still apply.

  2. System library versions

    Yocto releases generally use older C Library (GLIBC) versions than used in current desktop distributions.

    While rust has excellent cross compilation support, the Rust compiler will target the same GLIBC version as on the host.

The instructions below assume you are using rustup to manage your Rust environments.

Method 1: Use MUSL target with rustup

By targetting the MUSL C library, we can avoid mismatches between GLIBC versions.

However, you still need an Arm64 C compiler for linking purposes.

On Ubuntu, you can use the pre-packaged Arm64 compiler:

apt install gcc-aarch64-linux-gnu

Then, add a MUSL target with rustup:

rustup target add aarch64-unknown-linux-gnu

You will need to tell cargo to use the arm64 compiler when targetting arm64.

This can be done by adding a target option in $HOME/.cargo/config.toml:

cat "$HOME/.cargo/config.toml"

[target.aarch64-unknown-linux-musl]
linker = "aarch64-linux-gnu-gcc"

Then, you can do a build for the aarch64-unknown-linux-musl target:

cargo build --target=aarch64-unknown-linux-musl

The resulting build will be in target/aarch64-unknown-linux-musl:

$ file target/aarch64-unknown-linux-musl/debug/ieee1905
target/aarch64-unknown-linux-musl/debug/ieee1905: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked

You can also compile a release build by adding --release:

$ cargo build --release --target=aarch64-unknown-linux-musl
$ file target/aarch64-unknown-linux-musl/release/ieee1905
target/aarch64-unknown-linux-musl/release/ieee1905: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked

Please note that binaries cross-compiled against the MUSL target are generally larger than the "native" GLIBC binaries, do not use them for size comparisons.

Method 2: Use cargo-zigbuild

To build for targets with different architecture and C libraries to the host (development) system, you can use cargo-zigbuild.

Please check the cargo-zigbuild homepage for installation instructions, as you will also need the Zig programming language compiler.

Example 1: build a 32-bit ARM binary linked with MUSL (armv7-unknown-linux-musleabihf):

  1. Install Zig and make sure it is available on your PATH:
$ zig version
  1. Install cargo-zigbuild:
$ cargo install --locked cargo-zigbuild
  1. Add the Rust target:
$ rustup target add armv7-unknown-linux-musleabihf
  1. Build the ieee1905 package:
$ cargo zigbuild -p ieee1905 --release --target armv7-unknown-linux-musleabihf
  1. Verify the resulting binary:
$ file target/armv7-unknown-linux-musleabihf/release/ieee1905

Example 2: build a 64-bit ARM binary linked with GLIBC (aarch64-unknown-linux-gnu).

On the TARGET, check what glibc version is installed:

root@armefi64-rdk-extender:~# /lib/libc.so.6
GNU C Library (GNU libc) stable release version 2.35.

Then, run cargo zigbuild while appending the GLIBC version (in this example, 2.35) to the end of the target tuple:

$ cargo zigbuild --release --target=aarch64-unknown-linux-gnu.2.35
$ file target/aarch64-unknown-linux-gnu/debug/ieee1905
target/aarch64-unknown-linux-gnu/debug/ieee1905: ELF 64-bit LSB pie executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, for GNU/Linux 2.0.0, with debug_info, not stripped

You can copy the cross-compiled ieee1905 binary to the target system and use it to replace the version built into the image.


Building docker's test environment

There are available two methods for building and testing the project in docker:

  1. The first method for simulation using single dockerconfig file.

    This is the primary method for building the docker container for simulation process. It requires rebuild of docker container after every rebuild of Rust sources (cargo build)

        docker build -t ieee1905 .
        docker run -it --name ieee1905_node1 ieee1905

    Once your docker image is present you can use just docker start and stop

        docker start -ai ieee1905_node1 
        docker stop ieee1905_node1
     
  2. Secondary method via docker compose.

        docker compose build --no-cache
        docker compose up

At this point two docker containers: - ieee1905_node1 - ieee1905_node2

should be connected to the bridge ieee1905_bridge.

Running the tests

To be able to run the tests on two running docker containers: ieee1905_node1 and ieee1905_node2 - first it is needed to attach to both containers:

    docker exec -it ieee1905_node1 /bin/sh

and analogically connect to ieee1905_node2:

    docker exec -it ieee1905_node2 /bin/sh

then inside these containers run the ieee1905 binary (the option "-t" is to open CLI):

    ./ieee1905 -t

possibly with parameters and arguments.


Running Cargo Tests and Benches

From the repository root:

Run all tests in the workspace:

cargo test

Run tests for a specific package:

cargo test -p ieee1905
cargo test -p ieee1905-tests

Run a specific test target by name filter:

cargo test -p ieee1905 cmdu_reassembler

Run all benches for ieee1905:

cargo bench -p ieee1905

Run a specific bench target:

cargo bench -p ieee1905 --bench cmdu_handler_bench
cargo bench -p ieee1905 --bench cmdu_proxy_bench
cargo bench -p ieee1905 --bench cmdu_reassembler_bench
cargo bench -p ieee1905 --bench codec_parse_bench

Run a specific benchmark case inside a bench target:

cargo bench -p ieee1905 --bench cmdu_handler_bench -- node_present
cargo bench -p ieee1905 --bench codec_parse_bench -- codec_parse_cmdu

Memory usage reports

This repository includes a GitHub Actions workflow (.github/workflows/rust-rss-usage-check.yml) that runs on pull requests targeting develop and posts/updates a sticky PR comment with memory usage statistics (this requires a non-fork PR; on forks the comment step cannot write and will fail unless skipped).

The report is generated on the Ubuntu runner after ieee1905 has been running for 5 seconds and includes /proc/<pid>/status fields such as VmSize, VmRSS, VmHWM, RssAnon, and RssFile.

GNU / glibc

IEEE 1905 GNU artifact exchange footprint

musl

IEEE 1905 musl artifact exchange footprint

📦 Artifact Exchange Service

Artifacts can be transferred automatically between the controller and the agent as an auxiliary service.

This mechanism relies on topology convergence to synchronize the controller's IPv6 address so that agents can discover where to pull artifacts from and where to push artifacts to. The goal is to reuse topology knowledge already maintained by IEEE1905 instead of introducing a separate discovery mechanism.

The artifact exchange server provides an auxiliary HTTP service for transferring operational artifacts between the controller and agents over the IEEE1905 control interface. The controller runs the server side of the service and exposes artifacts prepared under the transmit artifact tree. Agents run the client side, periodically pulling controller-to-agent artifacts such as upgrade binaries and pushing agent-to-controller artifacts such as logs.

The service is discovered through topology convergence and Higher Layer Information metadata, allowing agents to learn the controller artifact exchange URL without a separate discovery protocol. In practice, clients consume the server URL from the Control URL TLV carried in the Higher Layer Response, and that URL includes the controller IPv6 address directly to avoid unnecessary resolution steps. Controller and agent roles are currently exchanged through a vendor proprietary TLV; this can be replaced in the future with a standard TLV such as Supported Role.

On the controller side, the artifact exchange HTTP service is implemented using axum. On the client side, reqwest is used so an AL entity can push artifacts to a remote controller or pull artifacts from it when required.

  1. The server binds to the IEEE1905 virtual/control interface using the link-local IPv6 address derived from the local AL MAC address.
  2. Artifact transfers use HTTP endpoints for listing available artifacts, downloading controller-to-agent artifacts, and uploading agent-to-controller artifacts.
  3. Supported artifact direction is explicit: binaries are sent from controller to agents, while logs are sent from agents to the controller.
  4. Artifact names are filtered by AL MAC prefix so each node only processes artifacts addressed to it.
  5. Successful and failed transfers are moved into quota-aware archive or failure storage to prevent unbounded filesystem growth.

HLE CMDU definition

The Higher Layer Query CMDU is used by an IEEE1905 entity to request Higher Layer Information metadata from a peer. The query itself does not carry additional metadata TLVs; it only identifies the message as a Higher Layer Query and terminates with the End of Message TLV.

HLE Query

The Higher Layer Response CMDU carries the metadata consumed by the requesting peer. In the artifact exchange flow, the response includes the AL MAC address, IEEE1905 profile version, device identification information, and the Control URL used by agents to reach the controller-side artifact exchange service.

HLE Response

Private Link-Local IPv6 EUI-64 for Control Plane Virtual Ethernet

The IEEE1905 control-plane virtual Ethernet interface can be assigned a private link-local IPv6 address derived from the AL MAC address using EUI-64 interface-ID rules. This address is in the fe80::/64 scope and is not routable outside the local home link/network.

  1. Use the AL MAC assigned to the virtual Ethernet interface as the base identifier.
  2. Build the EUI-64 interface ID from the 48-bit MAC: flip the U/L bit in the first octet, then insert ff:fe in the middle.
  3. Combine the resulting 64-bit interface ID with the link-local IPv6 prefix fe80::/64.
  4. Assign the address to the virtual Ethernet interface used by the IEEE1905 control plane.
  5. Validate duplicate-address detection (DAD), route reachability, and namespace placement if isolation is enabled.

Example:

  • AL MAC: 02:42:c0:a8:64:02
  • EUI-64 ID: 0042:c0ff:fea8:6402
  • Link-local /64 prefix: fe80::/64
  • Resulting IPv6: fe80::42:c0ff:fea8:6402/64

Network Isolation (Virtual Ethernet Namespace)

To reduce blast radius and improve security boundaries, the IEEE1905 virtual Ethernet interface can be isolated in a dedicated Linux network namespace.

  1. Create a dedicated namespace for IEEE1905 control-plane traffic.
  2. Move the virtual Ethernet endpoint used by IEEE1905 into that namespace.
  3. Expose only the minimum required links and routes between host and IEEE1905 namespaces.
  4. Apply namespace-scoped firewall rules and permissions to restrict unintended traffic paths.
  5. Monitor namespace and interface state and fail fast if the virtual interface is missing or detached.

Expected benefits:

  • Better separation between IEEE1905 control traffic and unrelated host networking.
  • Lower risk of accidental packet leakage across services.
  • Cleaner policy enforcement for interface access, logging, and debugging.

Operational notes:

  • Startup scripts or systemd units should create or validate the namespace before launching IEEE1905.
  • Recovery logic should recreate or reattach the virtual interface if namespace state is lost.
  • Diagnostics should include namespace-aware checks such as ip netns, interface and link state, and routes.

Binary Upgrade

Binary upgrades should preserve IEEE1905 service continuity and prevent topology instability during restart windows. Upgrade coordination metadata between IEEE1905 entities will be handled through the IEEE1905 Higher Layer Information Protocol using Higher Layer Query Message and Higher Layer Response Message exchanges.

In this model, only the controller requires connectivity to the backend binary repository or service. The controller distributes, via IEEE1905, the upgrade metadata required by extenders, for example image URI, version, integrity or checksum, and policy, so extenders can fetch and apply the correct binaries.

  1. During upgrade or restart, IEEE1905 should gracefully stop transmission workers and release resources in deterministic order.
  2. On startup after upgrade, the service should rebuild local interface state, restart discovery and notification timers, and repopulate topology state through normal convergence.
  3. If role-bearing entities such as agent, controller, or registrar restart, role selection and split-brain protection flow must be re-evaluated using the same tie-break logic.
  4. Upgrade procedures should be backward compatible for topology and CMDU behavior across adjacent binary versions whenever feasible.
  5. During rolling upgrades, Higher Layer Query and Response should be used to detect peer upgrade state and capability and gate feature activation until compatibility is confirmed.

ARCH

Logfile Exchange

Logfile exchange should provide a structured way to move operational logs from agents to the controller for diagnostics, observability, and remote troubleshooting without requiring a separate discovery mechanism. Discovery metadata between IEEE1905 entities will be handled through the IEEE1905 Higher Layer Information Protocol using Higher Layer Query Message and Higher Layer Response Message exchanges.

In this model, the controller exposes the artifact exchange HTTP service and receives uploaded log artifacts from agents.

  1. Logfile exchange should use the logs artifact direction from agent to controller, while preserving artifact naming based on AL MAC, timestamp, and original filename.
  2. Uploaded logs should be stored in the artifact exchange receive tree and moved into archive or failure storage according to transfer and processing outcome.
  3. Log exports should include enough stable context to correlate files with topology state, role, interface, and remote peer identity.
  4. Transfers should tolerate intermittent reachability and retry safely without causing duplicate processing or unbounded storage growth.
  5. Higher Layer Query and Response should be used to verify peer logfile-exchange capability before relying on cross-node log collection workflows.

ARCH

Artifact Types

We will provide two different kinds of artifacts to be exchanged between controller and agents:

  1. logs: platform telemetry artifacts generated by AL entities and extenders for diagnostics, observability, and troubleshooting.
  2. binaries: executable artifacts used to distribute agent upgrades.

Activation

When launching the ieee1905 binary, artifact synchronization must be enabled with the following argument:

--artifact-exchange <ARTIFACT_EXCHANGE>
        Enables artifact exchange server [possible values: server, client]

Use server when the node must expose the artifact exchange HTTP service, and use client when the node must push or pull artifacts from the controller.

Artifact Naming Convention

Each stored artifact filename shall include:

  1. The AL_MAC address of the destination entity (the node the artifact is addressed to).
  2. The creation timestamp of the artifact.
  3. The original artifact name.

Example:

11-22-33-44-55-66__2026-04-29T12-30-00Z__telemetry.log

Artifact Storage Layout

The artifact exchange service will use the following directory structure:

/tmp/artifacts/                                  (artifact exchange service root directory)
├── tx/                                          (artifacts prepared to be transmitted to a remote AL entity)
│   ├── logs/                                    (log artifacts to send)
│   │   └── 11-22-33-44-55-66__2026-04-29T12-30-00Z__telemetry.log
│   └── binaries/                                (binary artifacts to send)
│       └── 11-22-33-44-55-66__2026-04-29T12-30-00Z__easy_mesh_agent
├── rx/                                          (artifacts received from a remote AL entity)
│   ├── logs/                                    (received log artifacts)
│   │   └── aa-bb-cc-dd-ee-ff__2026-04-29T12-31-00Z__telemetry.log
│   └── binaries/                                (received binary artifacts)
│       └── aa-bb-cc-dd-ee-ff__2026-04-29T12-31-00Z__easy_mesh_agent
├── failed/                                      (artifacts whose transmission or reception failed)
│   ├── tx/                                      (artifacts that could not be transmitted successfully)
│   │   ├── logs/                                (log artifacts that failed during transmission)
│   │   │   └── 11-22-33-44-55-66__2026-04-29T12-30-00Z__telemetry.log
│   │   └── binaries/                            (binary artifacts that failed during transmission)
│   │       └── 11-22-33-44-55-66__2026-04-29T12-30-00Z__easy_mesh_agent
│   └── rx/                                      (artifacts that could not be received, validated, or stored successfully)
│       ├── logs/                                (received log artifacts that failed processing)
│       │   └── aa-bb-cc-dd-ee-ff__2026-04-29T12-31-00Z__telemetry.log
│       └── binaries/                            (received binary artifacts that failed processing)
│           └── aa-bb-cc-dd-ee-ff__2026-04-29T12-31-00Z__easy_mesh_agent
└── archive/                                     (artifacts kept as history after successful transmission or reception)
    ├── tx/                                      (artifacts successfully transmitted and retained for traceability)
    │   ├── logs/                                (sent log artifacts archived for history)
    │   │   └── 11-22-33-44-55-66__2026-04-29T12-30-00Z__telemetry.log
    │   └── binaries/                            (sent binary artifacts archived for history)
    │       └── 11-22-33-44-55-66__2026-04-29T12-30-00Z__easy_mesh_agent
    └── rx/                                      (artifacts successfully received and retained for traceability)
        ├── logs/                                (received log artifacts archived for history)
        │   └── aa-bb-cc-dd-ee-ff__2026-04-29T12-31-00Z__telemetry.log
        └── binaries/                            (received binary artifacts archived for history)
            └── aa-bb-cc-dd-ee-ff__2026-04-29T12-31-00Z__easy_mesh_agent

Transport Model

  1. Topology convergence propagates and refreshes the controller IPv6 address.
  2. The controller exposes HTTP endpoints for artifact upload and download.
  3. Agents use reqwest to push local artifacts and to pull remote artifacts.
  4. Successful transfers are moved into archive/, while failed transfers are moved into failed/.

🛡️ IEEE1905 security layer

Security Storage

We can use PKCS#11 to generate, import, and store cryptographic keys in a standard way, following the PKCS#11 API's object model and attribute system.

PKCS#11 defines key objects that can be stored either:

  • Persistently (on a token such as an HSM or secure software module)
  • Temporarily (in a session, discarded after logout or app exit)

Standard Procedure for Storing Keys

  1. Initialize the PKCS#11 library
  2. Get a slot with a token
  3. Open a session
  4. Log in
  5. Prepare the key attributes
  6. Create the key using C_CreateObject or C_GenerateKey
  7. Assign a label or ID to retrieve the key later

Reference Implementation to emulate Hardware Security Module

We will use SoftHSM2 to provide a reference implementation of PKCS#11 for generating and storing keys. In the future, we may integrate with a TPM 2.0 module for hardware-backed protection, reusing the current implementation based on PKCS#11.

Flow of generation and storage for DPP process

    Connects to SoftHSM.
    Generates AES-256 keys (256-bit symmetric key) 1905GTK, 1905PMK
    Stores it in the token, setting a unique identifier for each key:
        CKA_LABEL= 1905GTK, CKA_ID=0x01, CKA_CLASS = CKO_SECRET_KEY.
        CKA_LABEL= 1905PTK, CKA_ID=0x02, CKA_CLASS = CKO_SECRET_KEY.

Flow to retrieve keys from IEEE1905 for encryption/decryption and message integrity verfication.

    Connects to SoftHSM.
    Consumes the known CKA_ID or CKA_LABEL to find the key.
        KA_LABEL= 1905GTK, CKA_ID=0x01, CKA_CLASS = CKO_SECRET_KEY.
        CKA_LABEL= 1905PTK, CKA_ID=0x02, CKA_CLASS = CKO_SECRET_KEY.
    Uses 1905GTK for MIC computation
    Uses 1905PTK for TLV encryption.

Building blocks to use PKCS#11 in Rust

  1. PKCS#11 Rust Binding using cryptoki, acting as wrapper of C APIs.
# Cargo.toml
cryptoki = "0.12"
  1. PKCS#11 Rust Binding:
let pkcs11_module = std::env::var_os("PKCS11_LIB");
let pkcs11 = Pkcs11::new(pkcs11_module
    .as_deref()
    .unwrap_or(OsStr::new("/usr/lib/softhsm/libsofthsm2.so")))?;
  1. Initialization.
pkcs11.initialize(CInitializeArgs::OsThreads)?;
  1. Discover token and start session.
let slot = pkcs11.get_slots_with_token()?[0];
let mut session = pkcs11.open_session(
    slot,
    SessionFlags::RW_SESSION | SessionFlags::SERIAL_SESSION,
    None
)?;
  1. For softHSM we need to use a PIN to authenticate the access to keys.
let pin = std::env::var("PKCS11_USER_PIN")?;
session.login(UserType::User, Some(&AuthPin::new(pin.into())))?;
  1. Generate and/or find keys.
// Generate AES-256 key
let key_template = vec![
    Attribute::Token(true),
    Attribute::Sensitive(true),
    Attribute::Extractable(false),
    Attribute::ValueLen(32),
    Attribute::Encrypt(true),
    Attribute::Decrypt(true),
    Attribute::KeyType(KeyType::AES),
    Attribute::Class(ObjectClass::SECRET_KEY),
    Attribute::Label("my-aes-key".to_string()),
];

let key_handle = session.generate_key(&Mechanism::AesKeyGen, &key_template)?;
  1. Use the keys for encryption decryption and hashing.
let padded = b"VendorTLV"; // 16 bytes
let ciphertext = session.encrypt(key_handle, &Mechanism::AesEcb, padded)?;
  1. Clean up session
session.logout()?;
pkcs11.finalize()?;

🏷️ Release Types

We follow Semantic Versioning (SemVer), using the format MAJOR.MINOR.PATCH:


Patch Release (x.y.Z)

Contains:

  • Bug fixes
  • Security patches
  • Performance improvements
  • Internal changes with no effect on the public API
  • No new features

Example:
0.2.0 → 0.2.1


Minor Release (x.Y.z)

Contains:

  • New features
  • Enhancements to existing functionality
  • Backwards-compatible API additions
  • Deprecations (features marked for removal but still working)
  • May include multiple patch fixes bundled together

Example:
0.2.3 → 0.3.0


Major Release (X.y.z)

Contains:

  • Breaking changes to APIs or behavior
  • Removal of deprecated functionality
  • Large refactors or architectural changes
  • Any change that requires users to modify their code or configs

Example:
0.3.5 → 1.0.0


Summary:

  • Patch → fixes only
  • Minor → new features, backwards compatible
  • Major → breaking changes

Third-Party Licenses

This project includes third-party software under permissive open source licenses such as Apache-2.0, MIT, BSD, ISC, Unicode, and others.

Out of scope

We will leave out of scope any service that will not be of any use in our implementation for EasyMesh in RDK-B or in case of a clash with our architecture.

About

ieee1905 implementation in Rust

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages