diff options
-rw-r--r-- | sbin/route/route.8 | 6 | ||||
-rw-r--r-- | sys/net/rtable.c | 48 | ||||
-rw-r--r-- | sys/net/rtable.h | 4 | ||||
-rw-r--r-- | sys/net/rtsock.c | 47 | ||||
-rw-r--r-- | sys/netinet/in_pcb.c | 7 | ||||
-rw-r--r-- | sys/netinet6/in6_src.c | 7 |
6 files changed, 60 insertions, 59 deletions
diff --git a/sbin/route/route.8 b/sbin/route/route.8 index 25965364033..9904aed693c 100644 --- a/sbin/route/route.8 +++ b/sbin/route/route.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: route.8,v 1.93 2020/10/30 14:30:51 denis Exp $ +.\" $OpenBSD: route.8,v 1.94 2020/11/07 09:51:40 denis Exp $ .\" $NetBSD: route.8,v 1.6 1995/03/18 15:00:13 cgd Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 @@ -30,7 +30,7 @@ .\" .\" @(#)route.8 8.3 (Berkeley) 3/19/94 .\" -.Dd $Mdocdate: October 30 2020 $ +.Dd $Mdocdate: November 7 2020 $ .Dt ROUTE 8 .Os .Sh NAME @@ -234,8 +234,6 @@ The preferred source will not be used when: .It destination is on-link .It -output interface is point-to-point -.It source address is assigned to a disabled interface .El .El diff --git a/sys/net/rtable.c b/sys/net/rtable.c index dd8f33af576..9a9f2a65c31 100644 --- a/sys/net/rtable.c +++ b/sys/net/rtable.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtable.c,v 1.71 2020/11/05 10:46:13 denis Exp $ */ +/* $OpenBSD: rtable.c,v 1.72 2020/11/07 09:51:40 denis Exp $ */ /* * Copyright (c) 2014-2016 Martin Pieuchot @@ -31,10 +31,6 @@ #include <net/rtable.h> #include <net/route.h> -#include <net/if.h> -#include <net/if_dl.h> -#include <net/if_var.h> - /* * Structures used by rtable_get() to retrieve the corresponding * routing table for a given pair of ``af'' and ``rtableid''. @@ -370,46 +366,14 @@ rtable_alloc(unsigned int rtableid, unsigned int alen, unsigned int off) } int -rtable_setsource(unsigned int rtableid, struct sockaddr *src) +rtable_setsource(unsigned int rtableid, int af, struct sockaddr *src) { struct art_root *ar; - if ((ar = rtable_get(rtableid, src->sa_family)) == NULL) + if ((ar = rtable_get(rtableid, af)) == NULL) return (EAFNOSUPPORT); - /* - * Check if source address is assigned to an interface in the - * same rdomain - */ - if (ifa_ifwithaddr(src, rtableid) == NULL) { - /* - * If source address is 0.0.0.0 or :: - * use automatic source selection - */ - switch(src->sa_family) { - case AF_INET: - if(satosin(src)->sin_addr.s_addr == INADDR_ANY) - return (EINVAL); - break; - case AF_INET6: - if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr)) - return (EINVAL); - break; - default: - return (EAFNOSUPPORT); - } - src = NULL; - } - - if (ar->source) { - free(ar->source, M_IFADDR, ar->source->sa_len); - ar->source = NULL; - } - - if (src) { - ar->source = malloc(src->sa_len, M_IFADDR, M_WAITOK|M_ZERO); - memcpy(ar->source, src, src->sa_len); - } + ar->source = src; return (0); } @@ -434,9 +398,7 @@ rtable_clearsource(unsigned int rtableid, struct sockaddr *src) addr = rtable_getsource(rtableid, src->sa_family); if (addr && (addr->sa_len == src->sa_len)) { if (memcmp(src, addr, addr->sa_len) == 0) { - memset(addr->sa_data, 0, addr->sa_len- - sizeof(addr->sa_len)-sizeof(addr->sa_family)); - rtable_setsource(rtableid, addr); + rtable_setsource(rtableid, src->sa_family, NULL); } } } diff --git a/sys/net/rtable.h b/sys/net/rtable.h index 0686d0c75a2..e9dc137918e 100644 --- a/sys/net/rtable.h +++ b/sys/net/rtable.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rtable.h,v 1.25 2020/10/29 21:15:27 denis Exp $ */ +/* $OpenBSD: rtable.h,v 1.26 2020/11/07 09:51:40 denis Exp $ */ /* * Copyright (c) 2014-2016 Martin Pieuchot @@ -39,7 +39,7 @@ unsigned int rtable_l2(unsigned int); unsigned int rtable_loindex(unsigned int); void rtable_l2set(unsigned int, unsigned int, unsigned int); -int rtable_setsource(unsigned int, struct sockaddr *); +int rtable_setsource(unsigned int, int, struct sockaddr *); struct sockaddr *rtable_getsource(unsigned int, int); void rtable_clearsource(unsigned int, struct sockaddr *); struct rtentry *rtable_lookup(unsigned int, struct sockaddr *, diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c index bed2efff028..65214a9dd1d 100644 --- a/sys/net/rtsock.c +++ b/sys/net/rtsock.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtsock.c,v 1.303 2020/10/29 21:15:27 denis Exp $ */ +/* $OpenBSD: rtsock.c,v 1.304 2020/11/07 09:51:40 denis Exp $ */ /* $NetBSD: rtsock.c,v 1.18 1996/03/29 00:32:10 cgd Exp $ */ /* @@ -138,6 +138,8 @@ int sysctl_iflist(int, struct walkarg *); int sysctl_ifnames(struct walkarg *); int sysctl_rtable_rtstat(void *, size_t *, void *); +int rt_setsource(unsigned int, struct sockaddr *); + /* * Locks used to protect struct members * I immutable after creation @@ -860,7 +862,7 @@ route_output(struct mbuf *m, struct socket *so, struct sockaddr *dstaddr, goto fail; } if ((error = - rtable_setsource(tableid, info.rti_info[RTAX_IFA])) != 0) + rt_setsource(tableid, info.rti_info[RTAX_IFA])) != 0) goto fail; } else { error = rtm_output(rtm, &rt, &info, prio, tableid); @@ -2076,9 +2078,13 @@ sysctl_source(int af, u_int tableid, struct walkarg *w) case AF_INET: size = sizeof(struct sockaddr_in); break; +#ifdef INET6 case AF_INET6: size = sizeof(struct sockaddr_in6); break; +#endif + default: + return (0); } w->w_needed += size; if (w->w_where && w->w_needed <= 0) { @@ -2307,6 +2313,43 @@ rtm_validate_proposal(struct rt_addrinfo *info) return 0; } +int +rt_setsource(unsigned int rtableid, struct sockaddr *src) +{ + struct ifaddr *ifa; + /* + * If source address is 0.0.0.0 or :: + * use automatic source selection + */ + switch(src->sa_family) { + case AF_INET: + if(satosin(src)->sin_addr.s_addr == INADDR_ANY) { + rtable_setsource(rtableid, AF_INET, NULL); + return (0); + } + break; +#ifdef INET6 + case AF_INET6: + if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(src)->sin6_addr)) { + rtable_setsource(rtableid, AF_INET6, NULL); + return (0); + } + break; +#endif + default: + return (EAFNOSUPPORT); + } + + /* + * Check if source address is assigned to an interface in the + * same rdomain + */ + if ((ifa = ifa_ifwithaddr(src, rtableid)) == NULL) + return (EINVAL); + + return (rtable_setsource(rtableid, src->sa_family, ifa->ifa_addr)); +} + /* * Definitions of protocols supported in the ROUTE domain. */ diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 213eab813f6..12ed205c858 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.251 2020/11/05 10:46:13 denis Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.252 2020/11/07 09:51:40 denis Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -960,12 +960,11 @@ in_pcbselsrc(struct in_addr **insrc, struct sockaddr_in *sin, /* * Use preferred source address if : * - destination is not onlink - * - output interface is not PtoP * - preferred source addresss is set * - output interface is UP */ - if ((ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO)) && - (ia && !(ia->ia_ifp->if_flags & IFF_POINTOPOINT))) { + if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) && + !(ro->ro_rt->rt_flags & RTF_HOST)) { ip4_source = rtable_getsource(rtableid, AF_INET); if (ip4_source != NULL) { struct ifaddr *ifa; diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c index eefb69cf92d..500feb6e4f1 100644 --- a/sys/netinet6/in6_src.c +++ b/sys/netinet6/in6_src.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_src.c,v 1.83 2020/11/05 10:46:13 denis Exp $ */ +/* $OpenBSD: in6_src.c,v 1.84 2020/11/07 09:51:40 denis Exp $ */ /* $KAME: in6_src.c,v 1.36 2001/02/06 04:08:17 itojun Exp $ */ /* @@ -220,12 +220,11 @@ in6_pcbselsrc(struct in6_addr **in6src, struct sockaddr_in6 *dstsock, /* * Use preferred source address if : * - destination is not onlink - * - output interface is not PtoP * - preferred source addresss is set * - output interface is UP */ - if ((ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO)) && - (ia6 && !(ia6->ia_ifp->if_flags & IFF_POINTOPOINT))) { + if (ro->ro_rt && !(ro->ro_rt->rt_flags & RTF_LLINFO) && + !(ro->ro_rt->rt_flags & RTF_HOST)) { ip6_source = rtable_getsource(rtableid, AF_INET6); if (ip6_source != NULL) { struct ifaddr *ifa; |