The Adoption of ucode in OpenWrt
ucode is a minimal general-purpose scripting language which seems like the ECMA scripts. It can be an isolated interpreter encapsulated into a host application or any other systems. Although OpenWrt mainly uses POSIX shell and Lua as its system scripting languages, a new approach was necessary to support the requirements of the new firewall implementation. Specifically, this involved the need to effectively handle JSON data, manage complex data structures like arrays and dictionaries, and integrate seamlessly with OpenWrt’s ubus messaging system.
-
Used for Jinja like templating
-
Used as standalone scripts replacing shell script/lua script
-
Used as script embedded in to C language
ucode for Scripting
ucode programs with .uc extension can be compiled as byte code by providing a set of options.
The ucode command executes ucode instructions or can compile them to bytecode. The below example illustrates the execution of ucode.
-
hello world in ucode
openwrt# ucode -e "print('Hello, World!\n');"
-
hello world with shell in ucode
openwrt# cat << EOF > helloworld.uc
system("echo Hello, World\n");
EOF
openwrt# ucode helloworld.uc
ucode supports template mode with control flow and expression logic statements embedded in Jinja-like markup blocks.
It has a built-in support for parsing the JSON data without needing the external library dependencies.
Examples for ucode scripting and the ucode embedding into C applications can be found in the below links.
-
https://github.com/jow-/ucode/tree/master/examples - examples/directory.
-
https://github.com/jow-/ucode/tree/master/tests/custom - test case sources.
Major Changes Around Ucode in OpenWrt
This article emphasizes more about the ways ucode is utilized in OpenWrt v24.10. The ucode package is integrated from OpenWrt 22.03 and later used as support for Wi-Fi enablement.
The evolution of ucode in OpenWrt was compelled by the need to rewrite the OpenWrt firewall framework using nftables and JSON data structure for UCI configuration.
In OpenWrt 24.10, the firewall4 package is dependent on ucode, and it can be selected as a required package for the firewall4 configuration. It is used to replace Wi-Fi configuration scripts.
define Package/wifi-scripts
SECTION:=utils
CATEGORY:=Base system
DEPENDS:=+netifd +ucode +ucode-mod-nl80211 +ucode-mod-rtnl +ucode-mod-ubus +ucode-mod-uci
TITLE:=Wi-Fi configuration scripts
PKGARCH:=all
endef
define Package/firewall4
SECTION:=net
CATEGORY:=Base system
TITLE:=OpenWrt 4th gen firewall
DEPENDS:= \
+kmod-nft-core +kmod-nft-fib +kmod-nft-offload \
+kmod-nft-nat \
+nftables-json \
+ucode +ucode-mod-fs +ucode-mod-ubus +ucode-mod-uci
EXTRA_DEPENDS:=ucode (>=2022.03.22)
PROVIDES:=uci-firewall
endef
The ucode Makefile from OpenWrt is mentioned below, and the dependencies are described,
https://github.com/jow-/ucode/blob/master/openwrt/ucode/Makefile
Shell Script to ucode for mac80211
In OpenWrt mac80211.uc script file is used to configure the wireless interfaces. The Wi-Fi scripts are rewritten to ucode to replace Wi-Fi detect code which was earlier mac80211.sh.
/lib/wifi/mac80211.uc
is used to generate the /etc/config/wireless
file,
which is a generated configuration file from mac80211.sh initally. In OpenWrt
24.10, ucode has replaced this mac80211.sh with mac80211.uc.
In /sbin/wifi
wifi_config() {
[ -e /tmp/.config_pending ] && return
ucode /usr/share/hostap/wifi-detect.uc
[ ! -f /etc/config/wireless ] && touch /etc/config/wireless
ucode /lib/wifi/mac80211.uc | uci -q batch
}
ucode Support Hostapd
OpenWrt’s hostapd and wpa_supplicant now support, access point and wireless station mode re-implementation via ucode, addressing previous issues with center frequency adjustments, AP shutdown, etc using uloop for event handling. ucode supports for the main ubus object that handles the configuration changes on individual Wi-Fi parameters.
The corresponding hostapd related changes via ucode and the required file changes as the patch mentioned below
package/network/services/hostapd/src/src/ap/ucode.c
package/network/services/hostapd/src/src/ap/ucode.h
package/network/services/hostapd/src/src/utils/ucode.c
package/network/services/hostapd/src/src/utils/ucode.h
package/network/services/hostapd/src/wpa_supplicant/ucode.c
package/network/services/hostapd/src/wpa_supplicant/ucode.h
Ucode Support for rpcd
ucode creates a plugin for the rpcd daemon in OpenWrt that is allowed by the ubus daemon to interact with it. An example ucode plugin script used by rpcd (example-plugin.uc) is available in OpenWrt.
Conclusion
ucode getting into Openwrt’s Wi-Fi scripts, shows its significance. And it becomes mandatory that the knowledge of ucode is must for debugging the Wi-Fi related issues in Openwrt.