From def24fafd1ed69c3179231e88f751dd8bbc0bc0e Mon Sep 17 00:00:00 2001 From: Riccardo Manfrin <3090891+riccardomanfrin@users.noreply.github.com> Date: Fri, 16 Oct 2026 12:00:54 +0200 Subject: [PATCH] Revert "Document HA routing peer selection from v0.81.1 (#1043)" (#1047) This reverts commit 1ab145bf. The HA routing peer selection it documents (netbirdio/netbird #7689 and #8192) is not in any current stable release: v0.81.2 was cut from the release branch without it, and it ships in v0.82.0. Until then the page has to describe what released clients do, including their log messages, and NB_HA_RELAYED_SWITCH_DELAY has no effect on them. The change comes back with the v0.82.0 release. --- src/pages/client/environment-variables.mdx | 1 - .../networks/how-routing-peers-work.mdx | 71 ++++--------------- 2 files changed, 14 insertions(+), 58 deletions(-) diff --git a/src/pages/client/environment-variables.mdx b/src/pages/client/environment-variables.mdx index 9b46aa1b..4cd751f5 100644 --- a/src/pages/client/environment-variables.mdx +++ b/src/pages/client/environment-variables.mdx @@ -35,7 +35,6 @@ To clear all saved service parameters (including env vars), run `sudo netbird se | `NB_DISABLE_CUSTOM_ROUTING` | All | Revert to the routing behavior from before exit node support was added. No exclusion routes or fwmark-based socket routing will be used; all dialers and listeners fall back to plain `net.Dial`/`net.Listen`. Routes with a prefix of /7 or larger (e.g. default routes, 0.0.0.0/0) will be rejected. | | `NB_ROUTE_PROTO_FLAG` | macOS, BSD | Set a custom route flag on routes the client adds to the routing table. Accepted values: `2` (RTF_PROTO2) or `3` (RTF_PROTO3); defaults to RTF_PROTO1. Not used on Linux (Linux uses netlink with its own protocol field). | | `NB_DISABLE_ROUTE_CACHE` | Windows | Disable the 2-second cache on Windows routing table lookups. The client reads the OS routing table (via Win32 API) when adding or removing routes; without the cache, each operation triggers a fresh read. Only needed for debugging route conflicts. | -| `NB_HA_RELAYED_SWITCH_DELAY` | All | How long a relayed routing peer keeps a highly available network before the route moves to an equivalent routing peer with a direct connection. Takes a duration (default `30s`), `0` to switch at once, or `never` to keep a routing peer whose direct connection fell back to relayed for as long as it stays connected. Available from v0.81.1. See [Relayed switch delay](/manage/networks/how-routing-peers-work#relayed-switch-delay). | | `NB_FWMARK_BASE` | Linux | Move the netfilter mark range the client uses (default base `0x1BD00`, covering `0x1BD00`-`0x1BD0FF`). Set this when other software on the host claims bits the NetBird marks use, so its rules act on NetBird traffic. The value is the base of the range, decimal or `0x`-prefixed, and the low byte identifies the individual mark, so it has to be left free: `NB_FWMARK_BASE=0x11000` puts the marks at `0x11000`-`0x110FF`. A value that is zero, larger than 32 bits, or has a bit set in its low byte is rejected with a warning in the log and the default range is used. | Container network plugins, CNIs and other VPNs claim bits of the mark space for themselves. When one of them has a rule matching a bit that a NetBird mark also sets, that rule acts on NetBird traffic, which shows up as traffic being dropped, masqueraded, or routed elsewhere. `NB_FWMARK_BASE` moves the whole NetBird range out of the way. diff --git a/src/pages/manage/networks/how-routing-peers-work.mdx b/src/pages/manage/networks/how-routing-peers-work.mdx index 4d31015d..b6d98164 100644 --- a/src/pages/manage/networks/how-routing-peers-work.mdx +++ b/src/pages/manage/networks/how-routing-peers-work.mdx @@ -98,67 +98,31 @@ The routing peer must have direct network reachability to the resources it serve ## High availability -Multiple routing peers can serve the same network or route. Each peer that uses the network (a user's laptop, for example) picks one of those routing peers and sends all of that network's traffic through it until something makes it switch. The **metric** you assign each routing peer in the dashboard is the main control. - -The choice is made by the peer that uses the network, not by the routing peers, so what follows depends on the NetBird version of that peer. - - -This section describes NetBird v0.81.1 and later. Earlier clients move to another routing peer as soon as their connection falls back to relayed, and for latency differences of 10 ms, which resets connections more often with masquerade on. - +Multiple routing peers can serve the same network or route. Each peer that uses the network (a user's laptop, for example) picks one of those routing peers and sends all of that network's traffic through it until something makes it switch. The **metric** you assign each routing peer in the dashboard is the main control. There are no tunable thresholds. ### How a peer picks a routing peer -A peer compares the routing peers it can use, in this order: +A peer compares the routing peers it is connected to, in this order: -1. **Connection status.** A connected routing peer beats one that is idle with [lazy connections](/manage/peers/lazy-connection). -2. **Metric.** The lowest metric wins, whatever the connection type or latency. -3. **Connection type.** Among equal metrics, a direct (peer-to-peer) connection beats a relayed one. -4. **Latency.** Among equal metrics and the same connection type, the lowest latency wins. +1. **Metric.** The lowest metric wins, whatever the connection type or latency. +2. **Connection type.** Among equal metrics, a direct (peer-to-peer) connection beats a relayed one. +3. **Latency.** Among equal metrics and the same connection type, the lowest latency wins. To prevent flapping, a peer only moves to a routing peer whose latency is at least 10 ms lower than its current one. -Latency is the round-trip time of the direct connection, sampled every few seconds and smoothed, so it keeps following the path while the connection stays up. A relayed connection has no latency measurement. +Latency is measured once, when the connection to a routing peer is set up, and is not re-measured while that connection stays up. ### What makes a peer switch -A peer repeats this comparison whenever a routing peer's connection state or latency changes, when the network's configuration is updated, and every 30 seconds. It switches: +A peer repeats this comparison whenever a routing peer's connection state changes or the network's configuration is updated. In practice it switches when: -- **At once, when its routing peer goes offline.** The peer moves to the next routing peer in the order above. -- **At once, when a routing peer with a lower metric comes back online**, even while that routing peer's connection is still relayed. -- **After the relayed switch delay, when its routing peer is relayed and an equivalent routing peer is direct.** See [Relayed switch delay](#relayed-switch-delay). -- **When another routing peer is clearly closer.** The latency gain has to be at least 20 ms, at least 20% of the current latency, and more than four times the combined measurement noise (jitter) of both paths. A peer also stays at least 30 seconds on a routing peer it moved to for latency, and gives a routing peer whose direct connection just came up up to 30 seconds to get its first latency measurement before comparing. - -### Relayed switch delay - -A direct connection often falls back to relayed for a few seconds and recovers. Since every switch resets connections with masquerade on, a relayed routing peer is kept for a while before the route moves to an equivalent routing peer with a direct connection: - -- **Its direct connection fell back to relayed.** The delay counts from the fallback. If the direct connection comes back within the delay, the route does not move. -- **It came up relayed.** When the routing peers of a network connect at the same time, for example after waking up from idle or when the client reconnects, the relayed connections come up first and the direct ones follow, one routing peer after the other. The delay counts from the moment another routing peer turns direct, and starts over if that routing peer is no longer direct. - -If the routing peer is still relayed when the delay runs out, the route moves to the direct one, so traffic does not stay relayed for longer than the delay. - -The delay is set with the `NB_HA_RELAYED_SWITCH_DELAY` [environment variable](/client/environment-variables) on the peer that uses the network: - -| Value | Behavior | -|---|---| -| unset | The default delay of 30 seconds. | -| a duration, such as `10s` or `2m` | Keep a relayed routing peer for that long. | -| `0` | Switch at once, as clients before v0.81.1 do. | -| `never` | Keep a routing peer whose direct connection fell back to relayed for as long as it stays connected. A routing peer that came up relayed still moves after the default delay. | - -An invalid value is logged as a warning and the default is used. - -```shell -sudo netbird service reconfigure --service-env NB_HA_RELAYED_SWITCH_DELAY=60s -``` - - -When a routing peer fails completely, its direct connection is usually detected as down before its relayed one. For that short window the routing peer looks relayed, so the failover can wait for the relayed switch delay, and traffic to the network is dropped meanwhile. - +- **Its routing peer goes offline.** The peer moves to the next routing peer in the order above, normally within seconds. +- **A routing peer with a lower metric comes back online.** The peer moves back as soon as that routing peer reconnects, even while its connection is still relayed. +- **Its routing peer's connection falls back from direct to relayed.** If another routing peer with the same metric still has a direct connection, the peer moves to it, although nothing went offline. With different metrics this does not happen, because metric outranks connection type. ### What a switch does to open connections -With masquerade on (the default), every switch resets established TCP connections through the network, whatever caused it: a failover, a failback, a fallback to relayed, or a closer routing peer. The new routing peer translates the traffic to a different source address, so applications such as SSH must reconnect. Expect the connection to stall for several seconds before the reset, while the peer notices the change. With masquerade off, connections are not translated and behave differently: see [High availability with masquerade off](/manage/networks/masquerade#high-availability-with-masquerade-off). +With masquerade on (the default), every switch resets established TCP connections through the network, whatever caused it: a failover, a failback, or a fallback to relayed. The new routing peer translates the traffic to a different source address, so applications such as SSH must reconnect. Expect the connection to stall for several seconds before the reset, while the peer notices the change. With masquerade off, connections are not translated and behave differently: see [High availability with masquerade off](/manage/networks/masquerade#high-availability-with-masquerade-off). -If users report dropped connections while no routing peer went offline, look up the reason of each switch in the client log (see [Finding switches in the client log](#finding-switches-in-the-client-log)), and check whether connections stay relayed for longer than the relayed switch delay. [Troubleshooting relayed connections](/help/troubleshooting-relayed-connections) covers why a connection is relayed. +If users report dropped connections while no routing peer went offline, check whether the routing peers share a metric and whether their connections fall back to relayed. [Troubleshooting relayed connections](/help/troubleshooting-relayed-connections) covers why a connection is relayed. ### Primary / failover (different metrics) @@ -168,18 +132,11 @@ Use different metrics when you want every peer on one known routing peer, with t ### Nearest routing peer (equal metrics) -Use equal metrics when routing peers are spread across regions and you want each peer to use the closest one: for example, an EU-based and a US-based routing peer serving the same network, with users on both continents. Each peer picks the lowest-latency routing peer and keeps comparing latency while connected, but only moves for a clear gain, as described above. A direct connection still beats a relayed one whatever the latency, after the relayed switch delay. The trade-off: a fallback to relayed that lasts longer than the delay moves peers to another routing peer and resets their connections. +Use equal metrics when routing peers are spread across regions and you want each peer to use the closest one: for example, an EU-based and a US-based routing peer serving the same network, with users on both continents. Each peer picks the lowest-latency routing peer when it connects, though a direct connection still beats a relayed one whatever the latency. It does not move to another routing peer later just because latency changes, and routing peers within 10 ms of each other are effectively tied. The trade-off: a fallback to relayed can move peers to another routing peer and reset their connections. ### Finding switches in the client log -The client logs routing peer decisions at the default log level: - -- `new chosen route is … for network []` when a network gets its first routing peer. -- `switching routing peer for network [] from to : `, as a warning, on every switch. The reason is one of `current routing peer unavailable`, `connected peer preferred over idle`, `lower route metric`, `direct connection preferred over relayed`, `lower latency`, or `route assigned to a different routing peer`. -- `keeping relayed routing peer …` or `keeping routing peer …` when a better-ranked routing peer is held back, with the rule that holds it: the relayed switch delay, the latency margin, the minimum time on a routing peer, or a missing latency measurement. Repeats of the same decision are logged at the debug level. -- `network [] has not been assigned a routing peer …` when none of its routing peers is available. - -Keys are WireGuard public keys. Switches and the loss of every routing peer are also recorded as `Routing peer changed` and `No routing peer available` events, which show in `netbird status -d` and in debug bundles whatever the log level. For an exit node (a default route), the loss of every routing peer is recorded as `Default route disconnected due to peer unreachability` instead. +The client logs each switch at the default log level as `New chosen route is …`, followed by the chosen routing peer's WireGuard public key and its score. The comparison behind the decision, including the score of the routing peer it kept, is logged only at the debug level. ### Failure domains