Both RTA_IFP and RTA_GATEWAY can use a sockaddr_dl struct. If either specifies an explicit interface index, it must be honored. If both do, and they are not equal, that is an error. It is also an error if RTA_IFP specifies an index of 0.
Furthermore, if RTA_GATEWAY specifies a sockaddr_dl, it must not be used where an AF_INET or AF_INET6 address is required. --- sys/net/rtsock.c | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) diff --git sys/net/rtsock.c sys/net/rtsock.c index a156674fa6a..0ddab28272a 100644 --- sys/net/rtsock.c +++ sys/net/rtsock.c @@ -1221,6 +1221,7 @@ int rtm_getifa(struct rt_addrinfo *info, unsigned int rtid) { struct ifnet *ifp = NULL; + uint16_t if_index = 0; /* * The "returned" `ifa' is guaranteed to be alive only if @@ -1229,16 +1230,29 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid) NET_ASSERT_LOCKED(); /* - * ifp may be specified by sockaddr_dl; if so, it must be honored. + * ifp and/or gateway may be specified by sockaddr_dl; if so, it must be + * honored. */ if (info->rti_info[RTAX_IFP] != NULL) { - struct sockaddr_dl *sdl; + if_index = satosdl(info->rti_info[RTAX_IFP])->sdl_index; + if (if_index == 0) + return (EINVAL); + } + + if (info->rti_info[RTAX_GATEWAY] != NULL && + info->rti_info[RTAX_GATEWAY]->sa_family == AF_LINK) { + uint16_t gateway_if; - sdl = satosdl(info->rti_info[RTAX_IFP]); - if ((ifp = if_get(sdl->sdl_index)) == NULL) - return (ENXIO); + gateway_if = satosdl(info->rti_info[RTAX_GATEWAY])->sdl_index; + if (if_index == 0) + if_index = gateway_if; + else if (gateway_if != if_index) + return (EINVAL); } + if (if_index != 0 && (ifp = if_get(if_index)) == NULL) + return (ENXIO); + #ifdef IPSEC /* * If the destination is a PF_KEY address, we'll look @@ -1269,7 +1283,8 @@ rtm_getifa(struct rt_addrinfo *info, unsigned int rtid) struct sockaddr *sa; if ((sa = info->rti_info[RTAX_IFA]) == NULL) - if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL) + if ((sa = info->rti_info[RTAX_GATEWAY]) == NULL || + sa->sa_family == AF_LINK) sa = info->rti_info[RTAX_DST]; if (sa != NULL && ifp != NULL) -- 2.26.2