netlink: improve source ifa selection algorithm when adding routes.

Use route destination sockaddr when the gateway is eiter AF_LINK or
 has the different family (IPv4 over IPv6). This change ensures
 the nexthop IFA has the same family as the destination.

Reported by:	Dmitriy Smirnov <fox@sage.su>
Tested by:	Dmitriy Smirnov <fox@sage.su>
MFC after:	3 days
This commit is contained in:
Alexander V. Chernikov 2023-04-09 13:30:45 +00:00
parent 351e4592f6
commit cc3793b1c5

View File

@ -708,7 +708,19 @@ finalize_nhop(struct nhop_object *nh, const struct sockaddr *dst, int *perror)
}
/* Both nh_ifp and gateway are set */
if (nh->nh_ifa == NULL) {
struct ifaddr *ifa = ifaof_ifpforaddr(&nh->gw_sa, nh->nh_ifp);
const struct sockaddr *gw_sa = &nh->gw_sa;
if (gw_sa->sa_family != dst->sa_family) {
/*
* Use dst as the target for determining the default
* preferred ifa IF
* 1) the gateway is link-level (e.g. direct route)
* 2) the gateway family is different (e.g. IPv4 over IPv6).
*/
gw_sa = dst;
}
struct ifaddr *ifa = ifaof_ifpforaddr(gw_sa, nh->nh_ifp);
if (ifa == NULL) {
NL_LOG(LOG_DEBUG, "Unable to determine ifa, skipping");
*perror = EINVAL;