host: add support for defining per-host metadata
authorFelix Fietkau <[email protected]>
Sat, 5 Jul 2025 17:34:50 +0000 (19:34 +0200)
committerFelix Fietkau <[email protected]>
Sat, 5 Jul 2025 17:34:55 +0000 (19:34 +0200)
This can be queried from ubus via network_get

Signed-off-by: Felix Fietkau <[email protected]>
host.c
host.h
ubus.c

diff --git a/host.c b/host.c
index 2bfc5004cd810bbec62ae3b0f990d86fd72b843a..73a1c79dea4c4302eeb8d16cd4e58d267de82e88 100644 (file)
--- a/host.c
+++ b/host.c
@@ -97,6 +97,7 @@ enum {
        NETWORK_HOST_PEX_PORT,
        NETWORK_HOST_ENDPOINT,
        NETWORK_HOST_GATEWAY,
+       NETWORK_HOST_META,
        __NETWORK_HOST_MAX
 };
 
@@ -109,17 +110,18 @@ static const struct blobmsg_policy host_policy[__NETWORK_HOST_MAX] = {
        [NETWORK_HOST_PEX_PORT] = { "peer-exchange-port", BLOBMSG_TYPE_INT32 },
        [NETWORK_HOST_ENDPOINT] = { "endpoint", BLOBMSG_TYPE_STRING },
        [NETWORK_HOST_GATEWAY] = { "gateway", BLOBMSG_TYPE_STRING },
+       [NETWORK_HOST_META] = { "meta", BLOBMSG_TYPE_TABLE },
 };
 
 static void
 network_host_create(struct network *net, struct blob_attr *attr, bool dynamic)
 {
        struct blob_attr *tb[__NETWORK_HOST_MAX];
-       struct blob_attr *cur, *ipaddr, *subnet;
+       struct blob_attr *cur, *ipaddr, *subnet, *meta;
        uint8_t key[CURVE25519_KEY_SIZE];
        struct network_host *host = NULL;
        struct network_peer *peer;
-       int ipaddr_len, subnet_len;
+       int ipaddr_len, subnet_len, meta_len;
        const char *endpoint, *gateway;
        char *endpoint_buf, *gateway_buf;
        int rem;
@@ -139,6 +141,11 @@ network_host_create(struct network *net, struct blob_attr *attr, bool dynamic)
            blobmsg_check_array(tb[NETWORK_HOST_SUBNET], BLOBMSG_TYPE_STRING) < 0)
                subnet_len = 0;
 
+       meta_len = tb[NETWORK_HOST_META] ? blob_pad_len(tb[NETWORK_HOST_META]) : 0;
+       if (meta_len &&
+           blobmsg_check_array(tb[NETWORK_HOST_META], BLOBMSG_TYPE_STRING) < 0)
+               meta_len = 0;
+
        if ((cur = tb[NETWORK_HOST_ENDPOINT]) != NULL)
                endpoint = blobmsg_get_string(cur);
        else
@@ -181,6 +188,7 @@ network_host_create(struct network *net, struct blob_attr *attr, bool dynamic)
                                &name_buf, strlen(name) + 1,
                                &ipaddr, ipaddr_len,
                                &subnet, subnet_len,
+                               &meta, meta_len,
                                &endpoint_buf, endpoint ? strlen(endpoint) + 1 : 0,
                                &gateway_buf, gateway ? strlen(gateway) + 1 : 0);
                host->node.key = strcpy(name_buf, name);
@@ -202,6 +210,8 @@ network_host_create(struct network *net, struct blob_attr *attr, bool dynamic)
                peer->pex_port = net->net_config.pex_port;
        if (endpoint)
                peer->endpoint = strcpy(endpoint_buf, endpoint);
+       if ((cur = tb[NETWORK_HOST_META]) != NULL && meta_len)
+               peer->meta = memcpy(meta, cur, meta_len);
        memcpy(peer->key, key, sizeof(key));
 
        memcpy(&peer->local_addr.network_id,
diff --git a/host.h b/host.h
index c678046909ad9be9f3df9fd76d071f106e0ce0ee..98a7d0102b01291f0e8c7517ff22e74ce55f4451 100644 (file)
--- a/host.h
+++ b/host.h
@@ -20,6 +20,7 @@ struct network_peer {
        const char *endpoint;
        struct blob_attr *ipaddr;
        struct blob_attr *subnet;
+       struct blob_attr *meta;
        int port;
        int pex_port;
        bool dynamic;
diff --git a/ubus.c b/ubus.c
index d1852b5394229c0413d1b50176e9f6a08c51b0ad..95f12c7420db4c3ed86b0df6c1ff7e4c23bc43be 100644 (file)
--- a/ubus.c
+++ b/ubus.c
@@ -68,9 +68,13 @@ __network_dump(struct blob_buf *buf, struct network *net)
        if (local) {
                blobmsg_add_string(buf, "local_host", network_host_name(local));
 
+               peer = &local->peer;
                str = blobmsg_alloc_string_buffer(buf, "local_address", INET6_ADDRSTRLEN);
-               inet_ntop(AF_INET6, &local->peer.local_addr.in6, str, INET6_ADDRSTRLEN);
+               inet_ntop(AF_INET6, &peer->local_addr.in6, str, INET6_ADDRSTRLEN);
                blobmsg_add_string_buffer(buf);
+               if (peer->meta)
+                       blobmsg_add_field(buf, BLOBMSG_TYPE_TABLE, "local_meta",
+                                         blobmsg_data(peer->meta), blobmsg_data_len(peer->meta));
        } else {
                if (net->net_data_len)
                        blobmsg_add_u8(buf, "no_local_host", true);
@@ -107,6 +111,9 @@ __network_dump(struct blob_buf *buf, struct network *net)
                        blobmsg_add_u32(buf, "idle", peer->state.idle);
                        blobmsg_add_u32(buf, "last_handshake_sec", peer->state.last_handshake_diff);
                }
+               if (peer->meta)
+                       blobmsg_add_field(buf, BLOBMSG_TYPE_TABLE, "meta", blobmsg_data(peer->meta),
+                                         blobmsg_data_len(peer->meta));
 
                blobmsg_close_table(buf, p);
        }