fix(mesh): peer removal now cleans up its kernel routes
wg_iface.removePeer() previously just did `wg set ... remove` -- the kernel routes setPeer() adds for a peer's AllowedIPs (since wg itself only configures crypto-routing, not kernel routes -- see setPeer's own comment) were never cleaned up, a real TODO flagged in code but never exercised because nothing removed a mesh peer at all. - removePeer() now queries the peer's current AllowedIPs (`wg show <iface> allowed-ips`) BEFORE removing it -- once gone, wg no longer knows what to clean up -- and issues `ip route del` for each. - New DELETE /api/mesh/gateways/:id (models/mesh_gateway.js gained remove()) actually calls removePeer(), so the fix has a real caller; previously there was no removal path anywhere in the mesh feature at all. Refuses to remove the local "(self)" entry. Does not reach out to the remote gateway to remove the reciprocal peer -- that side needs the same action taken independently. - Mesh UI: remove button per non-self peer row, using app.messages.confirm (not native confirm() -- caught by this repo's own no-native-dialogs test, which failed on first pass and is now green). Verified for real with a live WireGuard interface in a container: routes for a peer's AllowedIPs present after setPeer, confirmed gone after removePeer, while the interface's own local route correctly survives.
This commit is contained in:
+14
-1
@@ -109,7 +109,7 @@ function renderGatewaysTable(gateways) {
|
||||
return;
|
||||
}
|
||||
var html = '<table class="table table-striped table-hover mb-0 align-middle"><thead><tr>'
|
||||
+ '<th>Site</th><th>Mesh Index</th><th>Mesh Address</th><th>Endpoint</th><th>Public Key</th><th>Last Seen</th>'
|
||||
+ '<th>Site</th><th>Mesh Index</th><th>Mesh Address</th><th>Endpoint</th><th>Public Key</th><th>Last Seen</th><th class="text-end">Actions</th>'
|
||||
+ '</tr></thead><tbody>';
|
||||
gateways.forEach(function(g){
|
||||
var isSelf = g.siteSlug === '(self)';
|
||||
@@ -120,12 +120,25 @@ function renderGatewaysTable(gateways) {
|
||||
+ '<td><code class="small text-primary">' + esc(g.endpoint || '—') + '</code></td>'
|
||||
+ '<td><code class="small text-truncate d-inline-block" style="max-width:220px;" title="' + esc(g.publicKey) + '">' + esc(g.publicKey) + '</code></td>'
|
||||
+ '<td class="small text-muted">' + (g.lastSeenAt ? new Date(Number(g.lastSeenAt)).toLocaleString() : '—') + '</td>'
|
||||
+ '<td class="text-end">' + (isSelf ? '' :
|
||||
'<button class="btn btn-sm btn-outline-danger" onclick="removeMeshGateway(\'' + esc(g.id) + '\', \'' + esc(g.siteSlug || g.id) + '\')" title="Remove peer"><i class="fa-solid fa-trash"></i></button>')
|
||||
+ '</td>'
|
||||
+ '</tr>';
|
||||
});
|
||||
html += '</tbody></table>';
|
||||
$w.html(html);
|
||||
}
|
||||
|
||||
async function removeMeshGateway(id, label) {
|
||||
var ok = await app.messages.confirm('Remove mesh peer "' + label + '"? This tears down the local WireGuard peer + routes. The other side keeps its half until removed there too.', $('#mesh-gateways-wrap'), 'danger');
|
||||
if (!ok) return;
|
||||
app.api.delete('mesh/gateways/' + id, function(err){
|
||||
if (err) return app.messages.toast('Failed to remove gateway: ' + err.message, 'danger');
|
||||
app.messages.toast('Gateway removed', 'success');
|
||||
loadMeshStatus();
|
||||
});
|
||||
}
|
||||
|
||||
function mintMeshJoinToken() {
|
||||
app.api.post('mesh/join-tokens', {}, function(err, data){
|
||||
if (err) return app.messages.toast('Failed to mint join token: ' + err.message, 'danger');
|
||||
|
||||
Reference in New Issue
Block a user