ipv6: use netlink RTM_GETADDR to properly detect permanent vs temporary IPv6 addresses

getifaddrs() ifa_flags contains interface flags (IFF_UP etc.), NOT address
flags (IFA_F_TEMPORARY). Since IFA_F_TEMPORARY == IFA_F_SECONDARY == 0x01,
and 0x01 in interface flags is IFF_UP, ALL addresses appeared as 'temporary',
making the permanent>temporary priority non-functional.

New netlink-based get_interface_ipv6_addr_nl() reads real IFA_FLAGS from
RTM_GETADDR response, correctly identifying:
- Temporary:     IFA_F_TEMPORARY=1, IFA_F_MANAGETEMPADDR=0
- Stable/mngtmp: IFA_F_TEMPORARY=1, IFA_F_MANAGETEMPADDR=1
- Legacy static: IFA_F_TEMPORARY=0

Verified: wlo1 permanent (3a7a:eff:fef5:9637) now correctly selected
for prefer_stable=1, temporary (1fb5:b7c:7538:dcf4) for prefer_stable=0.
This commit is contained in:
evgeny committed 2026-08-02 11:13:47 +03:00
1 parent f67bc23cd3
commit fdbb5b7bc0
3 files changed
+104 -3

No files matched your search

+6
View File
@@ -189,6 +189,12 @@ uint32_t get_interface_ip_by_index(uint32_t netif_index);
// Returns 0 on success (fills addr_out with 16 bytes), -1 on error or not found
int get_interface_ipv6_by_index(uint32_t netif_index, int temporary, uint8_t* addr_out);
// Get IPv6 address using netlink (Linux-only, accurate IFA_F_* flags)
// prefer_stable=1: prefer permanent/stable (IFA_F_MANAGETEMPADDR) over temporary
// prefer_stable=0: prefer temporary over stable
// Returns 0 on success (fills addr_out with 16 bytes), -1 on error
int get_interface_ipv6_addr_nl(uint32_t netif_index, int prefer_stable, uint8_t* addr_out);
// Determine the interface index for the default route (outgoing traffic)
// Creates a temp UDP socket, connects to a well-known address to force
// kernel routing, then matches the chosen source IP to getifaddrs()