Skip to content

server: use configured local address for nexthop when set#3420

Draft
sergei-ilisavskii wants to merge 1 commit into
osrg:masterfrom
sergei-ilisavskii:fix/local-address-override
Draft

server: use configured local address for nexthop when set#3420
sergei-ilisavskii wants to merge 1 commit into
osrg:masterfrom
sergei-ilisavskii:fix/local-address-override

Conversation

@sergei-ilisavskii
Copy link
Copy Markdown
Contributor

@sergei-ilisavskii sergei-ilisavskii commented May 11, 2026

Summary

When Transport.Config.LocalAddress is set to a specific (non-wildcard) address, override Transport.State.LocalAddress with it instead of using the TCP connection's local address. This ensures the configured address is advertised as the BGP nexthop.

This is needed for deployments where the BGP listener binds to an internal address (e.g., VRFs over GENEVE tunnels) but the configured local address is what should be advertised as the nexthop. Without this fix, the TCP connection's local address (the listener's bind address) is used, resulting in incorrect nexthop advertisement.

Background

This issue was originally addressed in #2827 and #2839 (both closed). The fix was applied to downstream forks and evolved with IPv6 improvements, but was inadvertently removed during two upstream refactoring commits:

  • 075aab46 ("convert PeerInfo to use netip instead of net", Aug 2025) removed the override from handleFSMMessage
  • 0c74e9c6 ("server: remove access to fsm.conn in server", Oct 2025) removed the override from toConfig

Approach

The override is applied in server.go:handleFSMMessage() when a session reaches ESTABLISHED, consistent with the original PRs. It uses the standard ReadCopy → modify → Update pattern under fsm.lock to persist the overridden address to pConf before NewPeerInfo is created. All downstream consumers (toConfig, prePolicyFilterpath/nexthop rewrite, watch events) read from Transport.State and automatically get the correct value.

The override only applies when the configured address is valid and non-unspecified (not 0.0.0.0 or ::). IPv6 zone information is stripped since BGP nexthop attributes cannot carry zone info.

Test plan

  • Added TestLocalAddressOverride integration test with 3 sub-tests that establish a real two-server BGP session and verify the overridden address via the ListPeer API:
    • No config address set (TCP address used as-is)
    • Wildcard IPv4 0.0.0.0 (no override)
    • Specific IPv4 with BindInterface set (override applied)
  • go build ./... passes
  • go vet ./pkg/server/... passes
  • go test -race ./pkg/server/... passes
  • Existing tests unaffected

🤖 Generated with Claude Code

@sergei-ilisavskii sergei-ilisavskii marked this pull request as draft May 11, 2026 17:15
@sergei-ilisavskii
Copy link
Copy Markdown
Contributor Author

I need to do additional tests, will come back with results soon

When Transport.Config.LocalAddress is set to a specific (non-wildcard)
address, override Transport.State.LocalAddress with it instead of using
the TCP connection's local address. This ensures the configured address
is advertised as the BGP nexthop.

This is needed for deployments where the BGP listener binds to an
internal address (e.g. VRFs over GENEVE tunnels) but the configured
local address is what should be advertised as the nexthop.

The override is applied in handleFSMMessage() via ReadCopy/Update on
pConf before NewPeerInfo is created, so all downstream consumers
(toConfig, prePolicyFilterpath nexthop rewrite, watch events)
automatically read the correct value.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sergei-ilisavskii sergei-ilisavskii force-pushed the fix/local-address-override branch from 1b65e1b to 88101dd Compare May 28, 2026 13:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant