Skip to content

FR: tailscale status --routes to show advertised subnet routes #20692

Description

@mminkus

What are you trying to do?

Find out which nodes in a tailnet advertise subnet routes, or act as exit nodes, without leaving the CLI.

I run a tailnet of roughly 50 nodes where a couple dozen are subnet routers fronting branch-office and lab networks, plus a few exit nodes. "Which node advertises the route to X?" and "what does this node actually advertise?" come up constantly, during audits and while debugging routing.

tailscale status is the obvious place to look, but it has no notion of routes: the table shows IP, hostname, owner, OS, and connection status only. The information is present in tailscale status --json as each peer's AllowedIPs, just not surfaced anywhere in the human-readable output.

How should we solve this?

A --routes flag on tailscale status that reuses the existing table, replacing the Status column with a Routes column, and lists only nodes advertising at least one route:

$ tailscale status --routes --header
IP              Hostname          Owner           OS       Routes
--              --------          -----           --       ------
100.64.0.10     branch-router-1   tagged-devices  freebsd  192.0.2.0/24
100.64.0.11     branch-router-2   tagged-devices  linux    198.51.100.0/24 203.0.113.0/24
100.64.0.12     exit-node-1       tagged-devices  linux    0.0.0.0/0 ::/0
100.64.0.13     app-host-proxy    tagged-devices  linux    100.64.0.20/32
100.64.0.14     lab-router        tagged-devices  linux    192.0.2.128/25

A node's advertised routes are its AllowedIPs minus the single-address prefixes covering its own Tailscale IPs.

I have a working patch and will send it as a PR if the approach sounds reasonable. Open questions I'd want a maintainer's opinion on:

  • Is status --routes the right home for this, or would you rather see it under an existing subcommand (something nearer tailscale exit-node list or a tailscale route-style command)?
  • Nodes advertising many prefixes overflow one terminal line; one node on my tailnet advertises 14. My patch space-joins them on a single row. One route per line, or truncation with a count, are both easy alternatives.
  • Should the flag also filter, as mine does, or list every node and leave the Routes column blank for those advertising nothing?

What is the impact of not solving this?

Not blocking, there's a workaround, but it's a poor one for something this routine:

tailscale status --json | jq -r '.Peer[] |
  select(.AllowedIPs | length > 2) | "\(.HostName): \(.AllowedIPs)"'

It needs jq installed, it needs the reader to know that "more than two AllowedIPs" is standing in for "advertises something", and it prints raw
JSON arrays instead of the status table everyone already reads. The count heuristic is also subtly wrong: it mis-handles nodes with only one Tailscale address, and a node advertising another node's /32 is indistinguishable from one advertising nothing.

Anything else?

Happy to iterate on the design before writing more code, per CONTRIBUTING.md.

Metadata

Metadata

Assignees

No one assigned

    Labels

    frFeature request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions