diff mbox series

ubus: add command to create devices dynamically

Message ID mailman.35542.1715363479.1280.openwrt-devel@lists.openwrt.org
State New
Headers show
Series ubus: add command to create devices dynamically | expand

Commit Message

gio--- via openwrt-devel May 10, 2024, 5:51 p.m. UTC
The sender domain has a DMARC Reject/Quarantine policy which disallows
sending mailing list messages using the original "From" header.

To mitigate this problem, the original message has been wrapped
automatically by the mailing list software.
From: Gioacchino Mazzurco <gio@polymathes.cc>

Some kind of devices might become available after initial configuration,
and other one like WDS stations or APuP peers can create unpredictably
many linux interfaces like wlan0.peer1 wlan0.peer2...

To use those linux interfaces as a base for other devices on top of those
like 802.1ad devices we need to be able to create them at runtime ofter
thos comes up, so an ubus command have been added for that.

ubus call network add_dynamic_device \
  '{"name":"NewDeviceName", "type":"8021ad", \
    "ifname":"wlan0.peer1", "vid":"47"}'

This will create the device that can be used for one or more interface
with pre-existent commands

ubus call network add_dynamic \
  '{"name":"NewInterfaceName", "proto":"static", "auto":1, \
    "device":"NewDeviceName", \
    "ipaddr":"192.0.2.0", "netmask":"255.255.255.255"}'
ubus call network.interface.NewInterfaceName up

To inspect the newly created device status a pre-existent command can be
used

ubus call network.device status '{"name":"NewDeviceName"}'

Signed-off-by: Gioacchino Mazzurco <gio@polymathes.cc>
---
 ubus.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 52 insertions(+)
diff mbox series

Patch

diff --git a/ubus.c b/ubus.c
index 3d24dc7..a686d4f 100644
--- a/ubus.c
+++ b/ubus.c
@@ -163,6 +163,57 @@  error:
 	return UBUS_STATUS_UNKNOWN_ERROR;
 }
 
+enum {
+	DI_DEV_NAME,
+	DI_DEV_TYPE,
+	__DI_DEV_MAX
+};
+
+static const struct blobmsg_policy dynamic_device_policy[__DI_DEV_MAX] = {
+	[DI_DEV_NAME] = { .name = "name", .type = BLOBMSG_TYPE_STRING },
+	[DI_DEV_TYPE] = { .name = "type", .type = BLOBMSG_TYPE_STRING }
+};
+
+static int
+netifd_add_dynamic_device(
+        struct ubus_context */*ctx*/, struct ubus_object */*obj*/,
+        struct ubus_request_data */*req*/, const char */*method*/,
+        struct blob_attr *msg )
+{
+	struct blob_attr *tb[__DI_DEV_MAX];
+	struct device *device;
+	struct device_type *type;
+	struct blob_attr *config;
+
+	blobmsg_parse( dynamic_device_policy, __DI_DEV_MAX, tb,
+	               blob_data(msg), blob_len(msg) );
+
+	if (!tb[DI_DEV_NAME] || !tb[DI_DEV_TYPE])
+		return UBUS_STATUS_INVALID_ARGUMENT;
+
+	const char *name = blobmsg_get_string(tb[DI_DEV_NAME]);
+	const char *type_name = blobmsg_get_string(tb[DI_DEV_TYPE]);
+
+	type = device_type_get(type_name);
+
+	if (!type)
+		return UBUS_STATUS_INVALID_ARGUMENT;
+
+	config = blob_memdup(msg);
+	if (!config)
+		return UBUS_STATUS_UNKNOWN_ERROR;
+
+	device = device_create(name, type, config);
+	if (!device)
+		goto error_free_config;
+
+	return UBUS_STATUS_OK;
+
+error_free_config:
+	free(config);
+	return UBUS_STATUS_UNKNOWN_ERROR;
+}
+
 enum {
 	NETNS_UPDOWN_JAIL,
 	NETNS_UPDOWN_START,
@@ -209,6 +260,7 @@  static struct ubus_method main_object_methods[] = {
 	UBUS_METHOD("add_host_route", netifd_add_host_route, route_policy),
 	{ .name = "get_proto_handlers", .handler = netifd_get_proto_handlers },
 	UBUS_METHOD("add_dynamic", netifd_add_dynamic, dynamic_policy),
+	UBUS_METHOD("add_dynamic_device", netifd_add_dynamic_device, dynamic_device_policy),
 	UBUS_METHOD("netns_updown", netifd_netns_updown, netns_updown_policy),
 };