Network: Fix default interface selection.

When an interface is not specified for the network module, we parse the
routing table to look for default routes.

We have defined a default route to:
- have a gateway specified, and
- have no destination specified, or have an all-zero destination.

Previous versions of Waybar had the second condition inverted,
causing it to incorrectly pick interfaces are used to route a
subnet/single host.

For example, with the following routing table, we should pick `eth0` to
show information about, not `wg0`.

```
ip -4 route
default via 192.168.252.1 dev eth0 proto dhcp src 192.168.252.200 metric 100
192.168.252.0/24 dev eth0 proto kernel scope link src 192.168.252.200 metric 100
192.168.2.254 via 192.168.1.1 dev wg0 proto static metric 50
192.168.1.0/24 dev wg0 proto static scope link metric 50
192.168.1.0/24 dev wg0 proto kernel scope link src 192.168.1.254 metric 50
```
This commit is contained in:
Greg Darke
2026-03-23 14:33:51 +11:00
parent ab7bfdb297
commit b64265bdf7

View File

@@ -744,16 +744,20 @@ int waybar::modules::Network::handleEvents(struct nl_msg* msg, void* data) {
/* The destination address. /* The destination address.
* Should be either missing, or maybe all 0s. Accept both. * Should be either missing, or maybe all 0s. Accept both.
*/ */
const uint32_t nr_zeroes = (family == AF_INET) ? 4 : 16; auto* dest = (const unsigned char*)RTA_DATA(attr);
unsigned char c = 0; size_t dest_size = RTA_PAYLOAD(attr);
size_t dstlen = RTA_PAYLOAD(attr); for (size_t i = 0; i < dest_size; ++i) {
if (dstlen != nr_zeroes) { if (dest[i] != 0) {
break; has_destination = true;
break;
}
} }
for (uint32_t i = 0; i < dstlen; i += 1) {
c |= *((unsigned char*)RTA_DATA(attr) + i); if (rtm->rtm_dst_len != 0) {
// We have found a destination like 0.0.0.0/24, this is not a
// default gateway route.
has_destination = true;
} }
has_destination = (c == 0);
break; break;
} }
case RTA_OIF: case RTA_OIF: