&ipaddr, ipaddr_len,
&subnet, subnet_len,
&endpoint_buf, endpoint ? strlen(endpoint) + 1 : 0,
- &gateway_buf, gateway ? strlen(endpoint) + 1 : 0);
+ &gateway_buf, gateway ? strlen(gateway) + 1 : 0);
host->node.key = strcpy(name_buf, name);
peer = &host->peer;
}
}
static void
-network_hosts_load_dynamic(struct network *net)
+network_hosts_load_dynamic_peers(struct network *net)
{
+ struct network_dynamic_peer *dyn;
struct blob_attr *cur;
int rem;
network_hosts_load_dynamic_file(net, blobmsg_get_string(cur));
blob_buf_free(&b);
+
+ list_for_each_entry(dyn, &net->dynamic_peers, list)
+ vlist_add(&net->peers, &dyn->peer.node, &dyn->peer.key);
+}
+
+static void
+network_host_free_dynamic_peers(struct list_head *list)
+{
+ struct network_dynamic_peer *dyn, *dyn_tmp;
+
+ list_for_each_entry_safe(dyn, dyn_tmp, list, list) {
+ list_del(&dyn->list);
+ free(dyn);
+ }
+}
+
+void network_hosts_reload_dynamic_peers(struct network *net)
+{
+ struct network_peer *peer;
+ LIST_HEAD(old_entries);
+
+ if (!net->config.peer_data)
+ return;
+
+ list_splice_init(&net->dynamic_peers, &old_entries);
+
+ vlist_for_each_element(&net->peers, peer, node)
+ if (peer->dynamic)
+ peer->node.version = net->peers.version - 1;
+
+ network_hosts_load_dynamic_peers(net);
+
+ vlist_flush(&net->peers);
+
+ network_host_free_dynamic_peers(&old_entries);
}
void network_hosts_update_start(struct network *net)
__network_hosts_update_done(struct network *net, bool free_net)
{
struct network_host *local, *host, *tmp;
- struct network_dynamic_peer *dyn, *dyn_tmp;
LIST_HEAD(old_dynamic);
const char *local_name;
vlist_add(&net->peers, &host->peer.node, host->peer.key);
}
- network_hosts_load_dynamic(net);
-
- list_for_each_entry(dyn, &net->dynamic_peers, list)
- vlist_add(&net->peers, &dyn->peer.node, &dyn->peer.key);
+ network_hosts_load_dynamic_peers(net);
out:
vlist_flush(&net->peers);
- list_for_each_entry_safe(dyn, dyn_tmp, &old_dynamic, list) {
- list_del(&dyn->list);
- free(dyn);
- }
+ network_host_free_dynamic_peers(&old_dynamic);
list_for_each_entry_safe(host, tmp, &old_hosts, node.list) {
list_del(&host->node.list);
return __network_hosts_update_done(net, false);
}
+static union network_endpoint *
+network_peer_next_endpoint(struct network_peer *peer)
+{
+ union network_endpoint *ep;
+ int i;
+
+ for (i = 0; i < __ENDPOINT_TYPE_MAX; i++) {
+ int cur = peer->state.next_endpoint_idx;
+
+ if (++peer->state.next_endpoint_idx == __ENDPOINT_TYPE_MAX)
+ peer->state.next_endpoint_idx = 0;
+
+ ep = &peer->state.next_endpoint[cur];
+ if (cur == ENDPOINT_TYPE_STATIC &&
+ (!peer->endpoint ||
+ network_get_endpoint(ep, AF_UNSPEC, peer->endpoint, peer->port,
+ peer->state.connect_attempt++)))
+ continue;
+
+ if (!ep->sa.sa_family)
+ continue;
+
+ return ep;
+ }
+
+ return NULL;
+}
+
+
static void
network_hosts_connect_cb(struct uloop_timeout *t)
{
if (peer->state.connected)
continue;
- ep = &peer->state.next_endpoint;
- if (peer->endpoint &&
- network_get_endpoint(ep, peer->endpoint, peer->port,
- peer->state.connect_attempt++))
- continue;
-
- if (!ep->sa.sa_family)
+ ep = network_peer_next_endpoint(peer);
+ if (!ep)
continue;
- if (memcmp(ep, &peer->state.endpoint, sizeof(*ep)) != 0)
+ if (memcmp(ep, &peer->state.endpoint, sizeof(*ep)) != 0 &&
+ !network_skip_endpoint_route(net, ep))
unetd_ubus_netifd_add_route(net, ep);
wg_peer_connect(net, peer, ep);