Skip to content

Fix: dashboard connection interface detection with VPN/policy routing - #2170

Merged
billz merged 2 commits into
RaspAP:masterfrom
Acio:fix/dashboard-connection-interface
Oct 21, 2026
Merged

billz merged 2 commits into
RaspAP:masterfrom
Acio:fix/dashboard-connection-interface

Conversation

@Acio

@Acio Acio commented Oct 19, 2026

Copy link
Copy Markdown
Contributor

Fixes #2169

getConnectionInterface() read a fixed column ($5) of ip -o route get 1.1.1.1. The column layout of that output varies:

route output $5
via gateway 1.1.1.1 via 192.168.40.1 dev wlan0 src ... wlan0 ✔
wg-quick full tunnel 1.1.1.1 dev wg0 table 51820 src ... 51820 ✘
no gateway (e.g. PPP) 1.1.1.1 dev ppp0 src 10.64.1.2 ... 10.64.1.2 ✘

This change:

  • takes the interface from the dev field instead of a fixed column;
  • when that interface is a VPN (wg0, tun0, tailscale0, the same list Sysinfo::getActiveVpnInterface() uses), returns the physical uplink from the main table's default route instead, so the dashboard keeps showing how the device is actually connected; the VPN is already shown separately by the VPN status item.

Testing

On a Pi 5 with RaspAP 3.5.8:

  • No VPN: wlan0 / wireless / IP and SSID shown, same as before.
  • wg-quick full tunnel (routing recreated in a network namespace: default dev wg0 table 51820, ip rule not fwmark 0xca6c table 51820, ip rule table main suppress_prefixlength 0):
    • before: interface 51820, type other (51820), no IP
    • after: interface wlan0, type wireless, IP 192.168.40.213
  • Parsing checked for via / no-via / table variants.

getConnectionInterface() read a fixed column of 'ip -o route get
1.1.1.1'. With a wg-quick full tunnel the output is
"1.1.1.1 dev wg0 table 51820 src ...", so the dashboard looked up an
interface named "51820" and showed no uplink IP, SSID or connection
type. Routes without a gateway (e.g. ppp0) returned the source IP.

Take the interface from the 'dev' field instead, and when it is a VPN
interface (wg0, tun0, tailscale0) return the physical uplink from the
main table's default route; the VPN is already shown separately.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@billz billz left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Acio thanks for the PR. parsing the dev field is the right fix for the $5 column assumption. a couple of observations:

  1. the VPN interface list now lives here and in Sysinfo::getActiveVpnInterface(). Would you mind moving it to a shared constant or helper so the two don't drift?
  2. Probably worth a note in the docblock that the first (lowest metric) default route is used when there are several?

Address review feedback on RaspAP#2170:
- Move the VPN interface list to a Sysinfo::VPN_INTERFACES constant,
  used by both getActiveVpnInterface() and
  Dashboard::getConnectionInterface(), so the two can't drift.
- Document that the first default route of the main table is used
  when there are several; ip lists them by ascending metric, so this
  is the route the kernel prefers.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@Acio

Acio commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Hi Bill, Thanks for the review! Both points are addressed in 048defd:

  1. The VPN interface list is now a single Sysinfo::VPN_INTERFACES constant, used by both Sysinfo::getActiveVpnInterface() and Dashboard::getConnectionInterface(). I left Dashboard::getVpnManaged() as is, since it maps each interface to its management page rather than listing them.
  2. The docblock now notes that the first default route of the main table is used when there are several. ip lists them by ascending metric (checked with routes added in the order 700/50/300; they come back as 50/300/700), so that's the route the kernel prefers.

Re-tested on a Pi 5 through includes/autoload.php, with a live wg-quick full tunnel and in a network namespace with the same policy routing: uplink wlan0 / wireless, VPN wg0.

I also will open a feature request for showing when multiple VPNs are connected, instead of just giving back one. I have multiple VPNs open for different routes when away, and just showing the lowest id while factually correct, is not the total picture :)

@billz
billz merged commit a265617 into RaspAP:master Oct 21, 2026
3 checks passed
@Acio
Acio deleted the fix/dashboard-connection-interface branch October 21, 2026 10:19
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.

[Bug]: Dashboard shows no uplink (IP/SSID/connection type) when a full-tunnel WireGuard VPN is active

2 participants