OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

1. Introduction to UBUS

ubus (OpenWrt micro bus) is a lightweight inter-process communication (IPC) framework in OpenWrt, based on Unix domain sockets and the JSON-RPC protocol.

It consists of the following components:

· ubusd: the core daemon that manages message routing.

· libubus: a C language library that provides APIs.

· ubus command-line tool: used for debugging and interaction.

· Multi-language bindings: supports C (native), Lua, Shell, JavaScript (such as JerryScript).

The design philosophy of ubus is fundamentally consistent with the DBus of Linux desktop systems, with the distinction being a simplified API and a concise model, which reduces system memory usage, making it suitable for the special environment of embedded Linux operating systems with low memory and low-end CPU performance. The comparison with Linux DBus is shown in the table below:

1. UBUS Framework

The foundation of the ubus implementation is the Unix socket, which is limited to inter-process communication on the same host and cannot cross hosts. The socket is bound to a local file, making it more efficient and reliable than inet sockets used for network communication. The implementation of Unix socket clients and servers is similar to that of network sockets.

The ubus implementation framework encapsulates socket connections and message transmission and processing:

1) ubus provides a socket server: ubusd. Therefore, developers do not need to implement the server side themselves.

2) ubus provides an interface for creating socket clients and offers three ready-to-use clients for users, in addition to the C library, support for shell, Lua, and HTTP has also been added.

3) ubus defines the message format for communication between clients and servers: both the client and server must encapsulate messages in JSON format.

4) ubus abstracts the message handling on the client side into the concepts of “object” and “method”. An object contains multiple methods, and the client needs to register the handling method for specific JSON messages with the server. Both objects and methods have their own names, and the sender only needs to specify the names of the object and method to be called in the message. The implementation framework is illustrated in the diagram below.

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

2. UBUS Principles

The core daemon of the ubus module is ubusd, which is a service management server. It runs at system startup and is responsible for message routing and delivery between processes. Other processes register with the ubusd process for sending and receiving messages. This interface is implemented using Linux file sockets and TLV (Type-Length-Value) for message transmission. Each process registers its path under a specified namespace. Each path can provide multiple function handling processes with various parameters, and the function handling process can return messages after completing the processing.

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

The component in the lower right corner of the image is a Client that requests services from ubusd. The lower left corner is a service provider (which is also a Client relative to ubusd, referred to as Server here, actually relative to the service requester Client).

Once ubusd starts: other applications can communicate with the ubusd process based on the interfaces provided by libubus or use the ubus command-line program.

Below, we will illustrate the workflow of the ubus client using the “ubus call” command as an example to facilitate understanding of the ubus principles.

(1) ubus_connect performs three tasks:

· Constructs the ubus_context structure, which represents the ubus context on the client side, containing the object AVL tree registered by the client, client socket, and msgbuf;

· Establishes the client Unix socket;

· Connects to the server socket;

(2) ubus_lookup_id sends the UBUS_MSG_LOOKUP message to ubusd to find the object ID corresponding to the path; the corresponding handler function in ubusd is ubusd_handle_lookup, which maintains the AVL tree of all registered object paths in ubusd, traversing the path AVL tree for string matching to find the corresponding object, and then sends back the object’s UBUS_ATTR_OBJPATH, UBUS_ATTR_OBJID, UBUS_ATTR_OBJTYPE, etc. information to the ubus cli via ubusd_send_obj, with the message type being UBUS_MSG_DATA.

(3) The callback function for ubus_lookup_id on the ubus cli side is ubus_look_id_cb, where all messages received by the ubus cli are parsed into an ID number in ubus_lookup_id_cb.

(4) ubus_invoke sends the UBUS_MSG_INVOKE message to ubusd, carrying the information UBUS_ATTR_OBJID and UBUS_ATTR_METHOD; the corresponding handler function for UBUS_ATTR_METHOD in ubusd is ubusd_handle_invoke, which finds the registered object based on OBJID and sends the UBUS_MSG_INVOKE message to that client process. The client process executes the corresponding method and sends the execution result back to ubusd.

(5) ubusd sends the execution result of the method back to the ubus cli, and the ubus cli prints the execution result in the callback function receice_call_result_data.

The overall process is illustrated in the diagram below:

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

2. UBUS Communication Methods

1. Point-to-Point (P2P) Method

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

1) For the process providing the service (service provider), the operational flow is as follows:

· Create the ubus_context context

· Define the method handling function

· Register the service object and method

· Enter the event loop to wait for calls

2) For the requesting process (client) obtaining the service, the operational flow is as follows:

· Connect to the ubus context

· Look up the service object ID

· Construct the request parameters

· Initiate a synchronous call

· Parse the response data

2. Subscribe-Notify

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

1) The server (Notifier) operational flow is as follows:

· Create the ubus_context context

· Define the object with notification capabilities

· Implement the notification trigger logic

· Register the object with ubusd

· Actively notify subscribers upon state changes

2) The client (Subscriber) operational flow is as follows:

· Connect to the ubus context

· Look up the target object ID

· Register the notification callback function

· Initiate the subscription request

· Handle the received notifications

3. Event Broadcast

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

1) The event receiver’s operational flow is as follows:

· Create the ubus connection context

· Register the event listener callback

· Subscribe to the specified event topic

· Enter the event loop to wait for notifications

2) The event sender’s operational flow is as follows:

· Create the ubus context

· Construct the event data packet

· Send the event to the specified topic

· Release resources

4. Comparison of Three Modes

Comparison:

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

Usage scenarios:

· Need immediate results? → P2P mode (e.g., ubus call).

· Need to listen for state changes of a specific object? → Subscribe-Notify mode (e.g., ubus listen).

· Need to notify all services of an event? → Event Broadcast mode (e.g., ubus send).

3. Advantages and Disadvantages of UBUS

1. Advantages

1) Lightweight & Efficient

· Low overhead: ubus uses Unix domain sockets (AF_UNIX) for communication, which is more efficient than traditional network sockets.

· JSON data format: Messages are transmitted in JSON format, which is easy to parse and debug.

· Suitable for embedded devices: Ideal for resource-constrained environments like OpenWrt (low CPU, low memory).

2) Supports multiple communication modes

· P2P (Point-to-Point) mode: Suitable for synchronous RPC calls (e.g., querying status).

· Subscribe-Notify mode: Suitable for listening to state changes of specific objects (e.g., network interface events).

· Event Broadcast mode: Suitable for global event notifications (e.g., system configuration changes).

3) Flexible programming language support

· C/C++ (libubus): Natively supported, best performance.

· Shell scripts (ubus call / ubus listen): Convenient for script calls.

· Lua / Python (via bindings): Suitable for advanced application development.

2. Disadvantages

In some scenarios, ubus is not suitable for use:

· ubus has poor support for multithreading; for example, requesting the same service from multiple threads may lead to unpredictable results. [Avoidance method: one thread should only request the same service]

· Recursive calls to ubus are not recommended; for instance, if process A calls service B, and B’s service needs to call service C, then C returns the result to B, and B returns the result to A. If this must be done, care should be taken to avoid reusing global variables during the call process.

OpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC FrameworkOpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC FrameworkOpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC FrameworkOpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC FrameworkOpenWrt Inter-Process Communication Tool: A Comprehensive Analysis of the UBUS Lightweight IPC Framework

Leave a Comment