make the routing socket report the right source address in RTM_GET

responses when a source-address selection policy is in use.
This commit is contained in:
dyoung 2006-11-13 19:16:01 +00:00
parent 00aa0b8d95
commit 2ed50f892c
1 changed files with 48 additions and 16 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtsock.c,v 1.90 2006/11/13 05:13:41 dyoung Exp $ */
/* $NetBSD: rtsock.c,v 1.91 2006/11/13 19:16:01 dyoung Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -61,7 +61,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.90 2006/11/13 05:13:41 dyoung Exp $");
__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.91 2006/11/13 19:16:01 dyoung Exp $");
#include "opt_inet.h"
@ -75,6 +75,9 @@ __KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.90 2006/11/13 05:13:41 dyoung Exp $");
#include <sys/protosw.h>
#include <sys/sysctl.h>
#include <sys/kauth.h>
#ifdef RTSOCK_DEBUG
#include <netinet/in.h>
#endif /* RTSOCK_DEBUG */
#include <net/if.h>
#include <net/route.h>
@ -241,6 +244,12 @@ route_output(struct mbuf *m, ...)
if (rt_xaddrs(rtm->rtm_type, (caddr_t)(rtm + 1), len + (caddr_t)rtm, &info))
senderr(EINVAL);
info.rti_flags = rtm->rtm_flags;
#ifdef RTSOCK_DEBUG
if (dst->sa_family == AF_INET) {
printf("%s: extracted dst %s\n", __func__,
inet_ntoa(((const struct sockaddr_in *)dst)->sin_addr));
}
#endif /* RTSOCK_DEBUG */
if (dst == 0 || (dst->sa_family >= AF_MAX))
senderr(EINVAL);
if (gate != 0 && (gate->sa_family >= AF_MAX))
@ -322,19 +331,36 @@ route_output(struct mbuf *m, ...)
gate = rt->rt_gateway;
netmask = rt_mask(rt);
genmask = rt->rt_genmask;
if (rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) {
if ((ifp = rt->rt_ifp) != NULL) {
ifpaddr = TAILQ_FIRST(&ifp->if_addrlist)->ifa_addr;
ifaaddr = rt->rt_ifa->ifa_addr;
if (ifp->if_flags & IFF_POINTOPOINT)
brdaddr = rt->rt_ifa->ifa_dstaddr;
else
brdaddr = 0;
rtm->rtm_index = ifp->if_index;
} else {
ifpaddr = 0;
ifaaddr = 0;
if ((rtm->rtm_addrs & (RTA_IFP | RTA_IFA)) == 0)
;
else if ((ifp = rt->rt_ifp) != NULL) {
const struct ifaddr *rtifa;
ifpaddr = TAILQ_FIRST(&ifp->if_addrlist)->ifa_addr;
/* rtifa used to be simply rt->rt_ifa.
* If rt->rt_ifa != NULL, then
* rt_get_ifa() != NULL. So this
* ought to still be safe. --dyoung
*/
rtifa = rt_get_ifa(rt);
ifaaddr = rtifa->ifa_addr;
#ifdef RTSOCK_DEBUG
if (ifaaddr->sa_family == AF_INET) {
printf("%s: copying out RTAX_IFA %s ",
__func__,
inet_ntoa(((const struct sockaddr_in *)ifaaddr)->sin_addr));
printf("for dst %s ifa_getifa %p ifa_seqno %p\n",
inet_ntoa(((const struct sockaddr_in *)dst)->sin_addr),
(void *)rtifa->ifa_getifa, rtifa->ifa_seqno);
}
#endif /* RTSOCK_DEBUG */
if (ifp->if_flags & IFF_POINTOPOINT)
brdaddr = rtifa->ifa_dstaddr;
else
brdaddr = 0;
rtm->rtm_index = ifp->if_index;
} else {
ifpaddr = 0;
ifaaddr = 0;
}
(void)rt_msg2(rtm->rtm_type, &info, (caddr_t)0,
(struct walkarg *)0, &len);
@ -917,10 +943,16 @@ sysctl_dumpentry(struct radix_node *rn, void *v)
netmask = rt_mask(rt);
genmask = rt->rt_genmask;
if (rt->rt_ifp) {
const struct ifaddr *rtifa;
ifpaddr = TAILQ_FIRST(&rt->rt_ifp->if_addrlist)->ifa_addr;
ifaaddr = rt->rt_ifa->ifa_addr;
/* rtifa used to be simply rt->rt_ifa. If rt->rt_ifa != NULL,
* then rt_get_ifa() != NULL. So this ought to still be safe.
* --dyoung
*/
rtifa = rt_get_ifa(rt);
ifaaddr = rtifa->ifa_addr;
if (rt->rt_ifp->if_flags & IFF_POINTOPOINT)
brdaddr = rt->rt_ifa->ifa_dstaddr;
brdaddr = rtifa->ifa_dstaddr;
}
if ((error = rt_msg2(RTM_GET, &info, 0, w, &size)))
return (error);