aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander V. Chernikov <melifaro@FreeBSD.org>2023-04-09 13:30:45 +0000
committerAlexander V. Chernikov <melifaro@FreeBSD.org>2023-04-09 13:33:22 +0000
commitcc3793b1c54847e26001f42026778703970fa570 (patch)
treeaad2781475dce6fa3f32a0c5090e8be53494d897
parent351e4592f64b5c752e7967f5ed565c546a5ef9ac (diff)
downloadsrc-cc3793b1c54847e26001f42026778703970fa570.tar.gz
src-cc3793b1c54847e26001f42026778703970fa570.zip
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
-rw-r--r--sys/netlink/route/rt.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/sys/netlink/route/rt.c b/sys/netlink/route/rt.c
index 7e81d59d696b..db535cb676e4 100644
--- a/sys/netlink/route/rt.c
+++ b/sys/netlink/route/rt.c
@@ -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;