-// SPDX-License-Identifier: GPL-2.0+
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2022 Felix Fietkau <nbd@nbd.name>
*/
NETWORK_HOST_SUBNET,
NETWORK_HOST_PORT,
NETWORK_HOST_ENDPOINT,
+ NETWORK_HOST_GATEWAY,
__NETWORK_HOST_MAX
};
static const struct blobmsg_policy policy[__NETWORK_HOST_MAX] = {
[NETWORK_HOST_SUBNET] = { "subnet", BLOBMSG_TYPE_ARRAY },
[NETWORK_HOST_PORT] = { "port", BLOBMSG_TYPE_INT32 },
[NETWORK_HOST_ENDPOINT] = { "endpoint", BLOBMSG_TYPE_STRING },
+ [NETWORK_HOST_GATEWAY] = { "gateway", BLOBMSG_TYPE_STRING },
};
struct blob_attr *tb[__NETWORK_HOST_MAX];
struct blob_attr *cur, *ipaddr, *subnet;
struct network_host *host;
struct network_peer *peer;
int ipaddr_len, subnet_len;
- const char *name, *endpoint;
- char *name_buf, *endpoint_buf;
+ const char *name, *endpoint, *gateway;
+ char *name_buf, *endpoint_buf, *gateway_buf;
int rem;
blobmsg_parse(policy, __NETWORK_HOST_MAX, tb, blobmsg_data(attr), blobmsg_len(attr));
else
endpoint = NULL;
+ if ((cur = tb[NETWORK_HOST_GATEWAY]) != NULL)
+ gateway = blobmsg_get_string(cur);
+ else
+ gateway = NULL;
+
if (b64_decode(blobmsg_get_string(tb[NETWORK_HOST_KEY]), key,
sizeof(key)) != sizeof(key))
return;
&name_buf, strlen(name) + 1,
&ipaddr, ipaddr_len,
&subnet, subnet_len,
- &endpoint_buf, endpoint ? strlen(endpoint) + 1 : 0);
+ &endpoint_buf, endpoint ? strlen(endpoint) + 1 : 0,
+ &gateway_buf, gateway ? strlen(endpoint) + 1 : 0);
peer = &host->peer;
if ((cur = tb[NETWORK_HOST_IPADDR]) != NULL && ipaddr_len)
peer->ipaddr = memcpy(ipaddr, cur, ipaddr_len);
peer->port = net->net_config.port;
if (endpoint)
peer->endpoint = strcpy(endpoint_buf, endpoint);
+ if (gateway)
+ host->gateway = strcpy(gateway_buf, gateway);
memcpy(peer->key, key, sizeof(key));
host->node.key = strcpy(name_buf, name);
void network_hosts_update_done(struct network *net)
{
- struct network_host *host, *tmp;
+ struct network_host *local, *host, *tmp;
+ const char *local_name;
- if (!net->net_config.local_host)
+ local = net->net_config.local_host;
+ if (!local)
goto out;
+ local_name = network_host_name(local);
+
if (net->net_config.local_host_changed)
- wg_init_local(net, &net->net_config.local_host->peer);
+ wg_init_local(net, &local->peer);
- avl_for_each_element(&net->hosts, host, node)
- if (host != net->net_config.local_host)
- vlist_add(&net->peers, &host->peer.node, host->peer.key);
+ avl_for_each_element(&net->hosts, host, node) {
+ if (host == local)
+ continue;
+ if (host->gateway && strcmp(host->gateway, local_name) != 0)
+ continue;
+ if (local->gateway && strcmp(local->gateway, network_host_name(host)) != 0)
+ continue;
+ vlist_add(&net->peers, &host->peer.node, host->peer.key);
+ }
out:
vlist_flush(&net->peers);
struct network_host *host;
union network_endpoint *ep;
- if (!net->net_config.keepalive)
+ avl_for_each_element(&net->hosts, host, node)
+ host->peer.state.num_net_queries = 0;
+ net->num_net_queries = 0;
+
+ if (!net->net_config.keepalive || !net->net_config.local_host)
return;
wg_peer_refresh(net);
avl_for_each_element(&net->hosts, host, node) {
struct network_peer *peer = &host->peer;
- if (host == net->net_config.local_host)
+ if (!network_host_is_peer(host))
continue;
if (peer->state.connected)