Skip to content

Announce only running interfaces, in a stable order - #465

Open
alpitol wants to merge 1 commit into
Atostek:masterfrom
alpitol:fix/skip-down-interfaces
Open

alpitol wants to merge 1 commit into
Atostek:masterfrom
alpitol:fix/skip-down-interfaces

Conversation

@alpitol

@alpitol alpitol commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

Problem

The unicast locators in SPDP/SEDP announcements list every local IPv4 address, including those of interfaces that cannot pass traffic. Examples are an idle docker0 bridge or an unplugged NIC.

They are also listed in random order. netdev::get_interfaces() collects interfaces through a HashMap, so the order differs between processes, and even between the metatraffic and user-traffic lists of a single participant.

Fast DDS uses only the first 4 unicast locators by default (max_unicast_locators). On a host with more addresses, whether the reachable address made it into the first 4 was decided by chance at every process start.

One RustDDS process was discovered by the ros2 CLI (Fast DDS) and another was not. A restart could flip which one.

Change

  • Sort the enumerated interfaces by (index, address), so the announced order is deterministic. Loopback and primary NICs normally come first.
  • Do not announce addresses of interfaces that are not running (IFF_RUNNING unset). Loopback is always kept for same-host peers. An explicit only_networks selection is honored as before, even for a non-running interface.

The change is limited to src/network/util.rs and adds a unit test.

Limitation

Interfaces are still read once, at participant creation. An interface that comes up later is not announced until restart. This was already true for interfaces that get their address after startup.

Testing

  • cargo test --lib network::util and cargo clippy --all-targets -- -D warnings pass.
  • On a Linux host with idle docker0 and br-* bridges, the announced locators are 127.0.0.1, followed by the two running NICs in the same order on every call. The bridges are no longer included.

The unicast locators in SPDP/SEDP announcements listed every local IPv4
address, including interfaces that cannot pass traffic (an idle docker0
bridge, an unplugged NIC, Jetson's l4tbr0), in random order because
netdev collects interfaces through a HashMap.

Fast DDS uses only the first 4 unicast locators by default. On a host
with more addresses, whether the reachable address made it into the
first 4 was decided by chance at every process start, so discovery with
Fast DDS peers worked or failed seemingly at random.

- Sort the enumerated interfaces by index and address.
- Do not announce addresses of non-running (IFF_RUNNING unset)
  interfaces. Loopback is always kept for same-host peers, and an
  explicit only_networks selection is honored as before.

Co-authored-by: Copilot <[email protected]>
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