From: Felix Fietkau Date: Sun, 15 Feb 2026 08:27:59 +0000 (+0000) Subject: netifd: update to Git HEAD (2026-02-15) X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c504cbd47c6168ebf9717a0a79483aadc3139577;p=thirdparty%2Fopenwrt.git netifd: update to Git HEAD (2026-02-15) Adds ucode proto handler support 51fa9ed6d4d6 interface-ip: fix fortify build error ca33316f8552 proto-ext: extract shared protocol handler code from proto-shell.c 2098f29810e8 proto: add config_load callback to proto_handler aaf5b194b15d proto-ucode: add ucode protocol handler infrastructure 3fc8b83c8b62 proto-ucode: add ucode proto handler scripts c6122254eb70 examples: sync wireless scripts with openwrt Signed-off-by: Felix Fietkau --- diff --git a/package/network/config/netifd/Makefile b/package/network/config/netifd/Makefile index a66f87d38dd..e3a9c145831 100644 --- a/package/network/config/netifd/Makefile +++ b/package/network/config/netifd/Makefile @@ -1,13 +1,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=netifd -PKG_RELEASE:=3 +PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/netifd.git -PKG_SOURCE_DATE:=2025-10-20 -PKG_SOURCE_VERSION:=777f5942fa7d6245f6ad29daa1daecc400344d37 -PKG_MIRROR_HASH:=7fc56f436faa1a5b05a147febed52c6f58c479125a38c9737736b352cd8d4409 +PKG_SOURCE_DATE:=2026-02-15 +PKG_SOURCE_VERSION:=c6122254eb7003377b67a6ad14d284b69725bbee +PKG_MIRROR_HASH:=feb62dba4dfecba1e3e758e5e4e822e9776b4104ee133dccfc3feb7ae6c5182d PKG_MAINTAINER:=Felix Fietkau PKG_LICENSE:=GPL-2.0 diff --git a/package/network/config/netifd/files/lib/netifd/main.uc b/package/network/config/netifd/files/lib/netifd/main.uc index 69677bb159a..56911347a75 100644 --- a/package/network/config/netifd/files/lib/netifd/main.uc +++ b/package/network/config/netifd/files/lib/netifd/main.uc @@ -1,6 +1,6 @@ import * as uci from "uci"; import * as uloop from "uloop"; -import * as ubus from "ubus"; +import * as libubus from "ubus"; import { access, dirname } from "fs"; function ex_handler(e) @@ -9,9 +9,11 @@ function ex_handler(e) } uloop.guard(ex_handler); -ubus.guard(ex_handler); +libubus.guard(ex_handler); +let ubus = netifd.ubus = libubus.connect(); let wireless; +let proto_mod; function uci_ctx() { @@ -26,8 +28,13 @@ function config_init() { let ctx = uci_ctx(); - if (wireless) - wireless.config_init(ctx); + for (let mod in [ wireless, proto_mod ]) { + try { + mod?.config_init(ctx); + } catch (e) { + netifd.log(netifd.L_WARNING, `${e}\n${e.stacktrace[0].context}`); + } + } } function config_start() @@ -77,3 +84,12 @@ if (access(wireless_module, "r")) { } else { netifd.log(netifd.L_WARNING, `Wireless module not found\n`); } + +const proto_module = dirname(sourcepath()) + "/proto.uc"; +if (access(proto_module, "r")) { + try { + proto_mod = loadfile(proto_module)(); + } catch (e) { + netifd.log(netifd.L_WARNING, `Error loading proto module: ${e}\n${e.stacktrace[0].context}\n`); + } +} diff --git a/package/network/config/netifd/files/lib/netifd/proto-ucode.uc b/package/network/config/netifd/files/lib/netifd/proto-ucode.uc new file mode 100644 index 00000000000..7db61cdb2c1 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/proto-ucode.uc @@ -0,0 +1,112 @@ +#!/usr/bin/env ucode + +import * as libubus from "ubus"; + +let script_path = ARGV[0]; +let proto_name = ARGV[1]; +let action = ARGV[2]; +let iface_name = ARGV[3]; +let config_json = ARGV[4]; +let device = ARGV[5]; + +let config; +try { + let blob = json(config_json); + let inner = blob?._ucode_config; + config = inner ? json(inner) : blob; +} catch (e) { + warn(`Failed to parse config JSON: ${e}\n${e.stacktrace[0].context}\n`); + exit(1); +} + +let ubus = libubus.connect(); +if (!ubus) { + warn(`Failed to connect to ubus\n`); + exit(1); +} + +let notify_path = `network.interface.${iface_name}`; + +function proto_notify(data) +{ + return ubus.call(notify_path, "notify_proto", data); +} + +let proto = { + iface: iface_name, + proto: proto_name, + config, + device, + + notify: proto_notify, + + update_link: function(up, data) { + let msg = { action: 0, "link-up": up, ...(data ?? {}) }; + return proto_notify(msg); + }, + + run_command: function(argv, env) { + let msg = { action: 1, command: argv }; + if (env) + msg.env = env; + return proto_notify(msg); + }, + + kill_command: function(signal) { + return proto_notify({ action: 2, signal: signal ?? 15 }); + }, + + error: function(errors) { + return proto_notify({ action: 3, error: errors }); + }, + + block_restart: function() { + return proto_notify({ action: 4 }); + }, + + set_available: function(available) { + return proto_notify({ action: 5, available }); + }, + + add_host_dependency: function(host, ifname) { + let msg = { action: 6 }; + if (host) + msg.host = host; + if (ifname) + msg.ifname = ifname; + return proto_notify(msg); + }, + + setup_failed: function() { + return proto_notify({ action: 7 }); + }, +}; + +let handlers = {}; + +let netifd_stub = { + add_proto: function(handler) { + if (handler?.name) + handlers[handler.name] = handler; + }, +}; + +try { + include(script_path, { netifd: netifd_stub }); +} catch (e) { + warn(`Failed to load proto handler script '${script_path}': ${e}\n${e.stacktrace[0].context}\n`); + exit(1); +} + +let handler = handlers[proto_name]; +if (!handler) { + warn(`No handler found for protocol '${proto_name}'\n`); + exit(1); +} + +if (!handler[action]) { + warn(`Handler '${proto_name}' has no '${action}' function\n`); + exit(1); +} + +handler[action](proto); diff --git a/package/network/config/netifd/files/lib/netifd/proto.uc b/package/network/config/netifd/files/lib/netifd/proto.uc new file mode 100644 index 00000000000..b1a4e2ee126 --- /dev/null +++ b/package/network/config/netifd/files/lib/netifd/proto.uc @@ -0,0 +1,52 @@ +import { sorted_json } from "./utils.uc"; +import { dirname, glob } from "fs"; + +let ctx; + +function proto_config_load(config_fn, section_name) +{ + if (!ctx) + return null; + + let section_data = ctx.get_all("network", section_name); + if (!section_data) + return null; + + let config_obj = { + iface: section_name, + section: section_name, + data: section_data, + uci: ctx, + }; + + let result; + if (config_fn) + result = config_fn(config_obj); + else + result = section_data; + + return sorted_json(result); +} + +netifd.cb.proto_config_load = proto_config_load; + +let base = dirname(sourcepath()); +for (let script in glob(base + "/proto/*.uc")) { + try { + loadfile(script)(); + } catch (e) { + netifd.log(netifd.L_WARNING, + `Error loading proto handler ${script}: ${e}\n${e.stacktrace[0].context}\n`); + } +} + +function config_init(uci) +{ + ctx = uci; + if (!ctx.load("network")) + netifd.log(netifd.L_WARNING, `Failed to load network config\n`); +} + +return { + config_init, +}; diff --git a/package/network/config/netifd/files/lib/netifd/utils.uc b/package/network/config/netifd/files/lib/netifd/utils.uc index 84db69d2fae..b038efc5fc7 100644 --- a/package/network/config/netifd/files/lib/netifd/utils.uc +++ b/package/network/config/netifd/files/lib/netifd/utils.uc @@ -102,6 +102,26 @@ export function parse_attribute_list(data, spec) return ret; }; +export function sorted_json(value) { + let t = type(value); + + if (t == "object") { + let parts = []; + for (let key in sort(keys(value))) + push(parts, sprintf("%J", key) + ":" + sorted_json(value[key])); + return "{" + join(",", parts) + "}"; + } + + if (t == "array") { + let parts = []; + for (let item in value) + push(parts, sorted_json(item)); + return "[" + join(",", parts) + "]"; + } + + return sprintf("%J", value); +}; + export function is_equal(val1, val2) { let t1 = type(val1);