openwrt / openwrt/packages

mwan3: rpcd ucode status handler emits invalid JSON ("age": nan) for online interface, breaking LuCI Status Overview

Open Beginner friendly
#29,653 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Makefile
Stars
4.6k
Forks
4k
Avg merge
3d 12h
Merged PRs (30d)
134

Description

Package Name

mwan3

Maintainer

@feckert (Florian Eckert). The faulty handler was introduced by @champtar in the 2.12.0 ucode rewrite (PR #26848).

OpenWrt Version

SNAPSHOT (mwan3 2.12.1)

OpenWrt Target/Subtarget

mediatek/filogic

Steps to Reproduce

The mwan3 rpcd ucode plugin (/usr/share/rpcd/ucode/mwan3) emits the bare token nan (invalid JSON) for an interface whose mwan3track state files are empty, which corrupts LuCI's batched /ubus Overview request.

  1. Have an mwan3-tracked interface that is online (SCORE=10) but has not had an online↔offline transition during the current tracker session (e.g. a freshly-booted, stably-online WAN). In that state mwan3track has not (re)written the TIME/ONLINE/OFFLINE state files:
# for p in TIME ONLINE OFFLINE SCORE LOST TURN; do printf '%-8s = ' "$p"; cat /var/run/mwan3track/wan/$p 2>/dev/null; echo; done
TIME     =
ONLINE   =
OFFLINE  =
SCORE    = 10
LOST     = 0
TURN     = 1
  1. Call the status method the LuCI Overview uses:
# ubus call mwan3 status '{"section":"interfaces"}' | grep -o '"age": *[a-z0-9.-]*'
"age": nan
"age": nan
"age": 0
"age": 0
  1. nan is not valid JSON. In a browser, open LuCI Status → Overview. LuCI batches every panel's call into one /ubus POST; the unparseable nan makes the whole batch response fail JSON.parse(), so every call in that batch rejects with Error: No related RPC reply. The System/Network/DHCP/WiFi/DDNS/mwan3 panels go blank, Memory/Storage fall back to ?/0 B, and the page is stuck on "REFRESHING".
Actual Behaviour

Root cause. In /usr/share/rpcd/ucode/mwan3:

function get_int(iface, property) {
	return int(get_str(iface, property));
}
function get_x_time(uptime, iface, property) {
	let t = get_int(iface, property);   // int("") / int(null) -> NaN
	if (t > 0) { t = uptime - t; }      // NaN > 0 is false -> t stays NaN
	return t;
}
...
'age':     get_x_time(uptime, ifname, 'TIME'),
'online':  get_x_time(uptime, ifname, 'ONLINE'),
'offline': get_x_time(uptime, ifname, 'OFFLINE'),
'score':   get_int(ifname, 'SCORE'),
'lost':    get_int(ifname, 'LOST'),
'turn':    get_int(ifname, 'TURN'),

readfile() returns null for a missing state file and "" for an empty one. In ucode both int(null) and int("") yield NaN, and the libubox/ubus blobmsg serializer emits NaN as the bare token nan — invalid JSON. Any field flowing through get_int (age/online/offline/score/lost/turn) is affected whenever its state file is empty.

Regression. This worked before mwan3 2.12.0. The previous shell handler (/usr/libexec/rpcd/mwan3, removed in commit 6423781 / PR #26848) defaulted these to 0 and guarded empty files:

get_age() {
	readfile time_p ".../TIME"
	[ -z "${time_p}" ] || { get_uptime time_n; export -n "$1=$((time_n-time_p))"; }
}
get_mwan3_status() {
	local age=0 online=0 offline=0   # safe defaults
	...
	json_add_int age "$age"          # always a valid integer

The shell→ucode port (2.11.19 → 2.12.0) dropped that guard. The bug is still present in master and 2.12.1. This is distinct from the IPv6 null-reference regression in #27145 / PR #27147, which does not touch get_int/get_x_time.

Possible Fix

Restore the old =0 default by guarding get_int (this also covers get_x_time):

function get_int(iface, property) {
	return int(get_str(iface, property)) || 0;   // NaN is falsy in ucode -> 0
}

(Equivalently let v = int(get_str(iface, property)); return (v == v) ? v : 0; since NaN != NaN.) Verified locally: with this guard mwan3 status returns valid JSON ("age": 0) and the LuCI Overview renders correctly again.

Confirmation Checklist
  • The package is maintained in this repository.
  • I understand that issues related to the base OpenWrt repository or LuCI repository will be closed.
  • I am reporting an issue for OpenWrt, not an unsupported fork.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in /usr/share/rpcd/ucode/mwan3, reading get_int() and get_x_time() and reproducing the mwan3 status call for an online interface with empty state files. Done when the status response contains valid JSON values instead of nan and the LuCI Status Overview renders normally; verify with the documented ubus command.

Written by the indexing model from the issue text.

Assessment

Domain
api, networking
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
78/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.