Module Name: src Committed By: snj Date: Sun Dec 10 09:24:31 UTC 2017
Modified Files: src/sys/netinet [netbsd-8]: ip_input.c src/sys/netinet6 [netbsd-8]: in6_src.c ip6_input.c ip6_output.c Log Message: Pull up following revision(s) (requested by roy in ticket #390): sys/netinet/ip_input.c: 1.363 sys/netinet6/ip6_input.c: 1.184-1.185 sys/netinet6/ip6_output.c: 1.194-1.195 sys/netinet6/in6_src.c: 1.83-1.84 Allow local communication over DETACHED addresses. Allow binding to DETACHED or TENTATIVE addresses as we deny sending upstream from them anyway. Prefer non DETACHED or TENTATIVE addresses. -- Attempt to restore v6 networking. Not 100% certain that these changes are all that is needed, but they're certainly a big part of it (especially the ip6_input.c change.) -- Treat unvalidated addresses as deprecated in rule 3. To generate a diff of this commit: cvs rdiff -u -r1.355.2.1 -r1.355.2.2 src/sys/netinet/ip_input.c cvs rdiff -u -r1.79.6.1 -r1.79.6.2 src/sys/netinet6/in6_src.c cvs rdiff -u -r1.178.2.1 -r1.178.2.2 src/sys/netinet6/ip6_input.c cvs rdiff -u -r1.191.6.2 -r1.191.6.3 src/sys/netinet6/ip6_output.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/ip_input.c diff -u src/sys/netinet/ip_input.c:1.355.2.1 src/sys/netinet/ip_input.c:1.355.2.2 --- src/sys/netinet/ip_input.c:1.355.2.1 Sat Oct 21 19:43:54 2017 +++ src/sys/netinet/ip_input.c Sun Dec 10 09:24:30 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_input.c,v 1.355.2.1 2017/10/21 19:43:54 snj Exp $ */ +/* $NetBSD: ip_input.c,v 1.355.2.2 2017/12/10 09:24:30 snj Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.355.2.1 2017/10/21 19:43:54 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.355.2.2 2017/12/10 09:24:30 snj Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -377,11 +377,14 @@ ip_match_our_address(struct ifnet *ifp, continue; if (checkif && ia->ia_ifp != ifp) continue; - if ((ia->ia_ifp->if_flags & IFF_UP) != 0 && - (ia->ia4_flags & IN_IFF_DETACHED) == 0) - break; - else + if ((ia->ia_ifp->if_flags & IFF_UP) == 0) { (*downmatch)++; + continue; + } + if (ia->ia4_flags & IN_IFF_DETACHED && + (ifp->if_flags & IFF_LOOPBACK) == 0) + continue; + break; } } @@ -398,7 +401,10 @@ ip_match_our_address_broadcast(struct if if (ifa->ifa_addr->sa_family != AF_INET) continue; ia = ifatoia(ifa); - if (ia->ia4_flags & (IN_IFF_NOTREADY | IN_IFF_DETACHED)) + if (ia->ia4_flags & IN_IFF_NOTREADY) + continue; + if (ia->ia4_flags & IN_IFF_DETACHED && + (ifp->if_flags & IFF_LOOPBACK) == 0) continue; if (in_hosteq(ip->ip_dst, ia->ia_broadaddr.sin_addr) || in_hosteq(ip->ip_dst, ia->ia_netbroadcast) || Index: src/sys/netinet6/in6_src.c diff -u src/sys/netinet6/in6_src.c:1.79.6.1 src/sys/netinet6/in6_src.c:1.79.6.2 --- src/sys/netinet6/in6_src.c:1.79.6.1 Thu Aug 31 11:24:03 2017 +++ src/sys/netinet6/in6_src.c Sun Dec 10 09:24:30 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: in6_src.c,v 1.79.6.1 2017/08/31 11:24:03 martin Exp $ */ +/* $NetBSD: in6_src.c,v 1.79.6.2 2017/12/10 09:24:30 snj Exp $ */ /* $KAME: in6_src.c,v 1.159 2005/10/19 01:40:32 t-momose Exp $ */ /* @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.79.6.1 2017/08/31 11:24:03 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.79.6.2 2017/12/10 09:24:30 snj Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -135,6 +135,9 @@ static int walk_addrsel_policy(int (*)(s static int dump_addrsel_policyent(struct in6_addrpolicy *, void *); static struct in6_addrpolicy *match_addrsel_policy(struct sockaddr_in6 *); +#define IFA6_IS_VALIDATED(ia) \ + (((ia)->ia6_flags & (IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) == 0) + /* * Return an IPv6 address, which is the most appropriate for a given * destination and user specified options. @@ -211,10 +214,8 @@ in6_select_best_ia(struct sockaddr_in6 * } /* avoid unusable addresses */ - if ((ia->ia6_flags & - (IN6_IFF_NOTREADY | IN6_IFF_ANYCAST | IN6_IFF_DETACHED))) { - continue; - } + if ((ia->ia6_flags & (IN6_IFF_DUPLICATED | IN6_IFF_ANYCAST))) + continue; if (!ip6_use_deprecated && IFA6_IS_DEPRECATED(ia)) continue; @@ -232,7 +233,7 @@ in6_select_best_ia(struct sockaddr_in6 * } if (ia_best == NULL) - REPLACE(0); + REPLACE(1); /* Rule 2: Prefer appropriate scope */ if (dst_scope < 0) @@ -251,7 +252,12 @@ in6_select_best_ia(struct sockaddr_in6 * /* * Rule 3: Avoid deprecated addresses. Note that the case of * !ip6_use_deprecated is already rejected above. + * Treat unvalidated addresses as deprecated here. */ + if (IFA6_IS_VALIDATED(ia_best) && !IFA6_IS_VALIDATED(ia)) + NEXT(3); + if (!IFA6_IS_VALIDATED(ia_best) && IFA6_IS_VALIDATED(ia)) + REPLACE(3); if (!IFA6_IS_DEPRECATED(ia_best) && IFA6_IS_DEPRECATED(ia)) NEXT(3); if (IFA6_IS_DEPRECATED(ia_best) && !IFA6_IS_DEPRECATED(ia)) Index: src/sys/netinet6/ip6_input.c diff -u src/sys/netinet6/ip6_input.c:1.178.2.1 src/sys/netinet6/ip6_input.c:1.178.2.2 --- src/sys/netinet6/ip6_input.c:1.178.2.1 Sat Oct 21 19:43:54 2017 +++ src/sys/netinet6/ip6_input.c Sun Dec 10 09:24:30 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_input.c,v 1.178.2.1 2017/10/21 19:43:54 snj Exp $ */ +/* $NetBSD: ip6_input.c,v 1.178.2.2 2017/12/10 09:24:30 snj Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.178.2.1 2017/10/21 19:43:54 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.178.2.2 2017/12/10 09:24:30 snj Exp $"); #ifdef _KERNEL_OPT #include "opt_gateway.h" @@ -511,13 +511,33 @@ ip6_input(struct mbuf *m, struct ifnet * #endif rt->rt_ifp->if_type == IFT_LOOP) { struct in6_ifaddr *ia6 = (struct in6_ifaddr *)rt->rt_ifa; + int addrok; + if (ia6->ia6_flags & IN6_IFF_ANYCAST) m->m_flags |= M_ANYCAST6; /* * packets to a tentative, duplicated, or somehow invalid * address must not be accepted. */ - if (!(ia6->ia6_flags & (IN6_IFF_NOTREADY | IN6_IFF_DETACHED))) { + if (ia6->ia6_flags & IN6_IFF_NOTREADY) + addrok = 0; + else if (ia6->ia6_flags & IN6_IFF_DETACHED && + !IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src)) + { + /* Allow internal traffic to DETACHED addresses */ + struct sockaddr_in6 sin6; + int s; + + memset(&sin6, 0, sizeof(sin6)); + sin6.sin6_family = AF_INET6; + sin6.sin6_len = sizeof(sin6); + sin6.sin6_addr = ip6->ip6_src; + s = pserialize_read_enter(); + addrok = (ifa_ifwithaddr(sin6tosa(&sin6)) != NULL); + pserialize_read_exit(s); + } else + addrok = 1; + if (addrok) { /* this address is ready */ ours = 1; deliverifp = ia6->ia_ifp; /* correct? */ Index: src/sys/netinet6/ip6_output.c diff -u src/sys/netinet6/ip6_output.c:1.191.6.2 src/sys/netinet6/ip6_output.c:1.191.6.3 --- src/sys/netinet6/ip6_output.c:1.191.6.2 Sat Oct 21 19:43:54 2017 +++ src/sys/netinet6/ip6_output.c Sun Dec 10 09:24:30 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: ip6_output.c,v 1.191.6.2 2017/10/21 19:43:54 snj Exp $ */ +/* $NetBSD: ip6_output.c,v 1.191.6.3 2017/12/10 09:24:30 snj Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.191.6.2 2017/10/21 19:43:54 snj Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.191.6.3 2017/12/10 09:24:30 snj Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -134,7 +134,7 @@ static int ip6_insert_jumboopt(struct ip static int ip6_splithdr(struct mbuf *, struct ip6_exthdrs *); static int ip6_getpmtu(struct rtentry *, struct ifnet *, u_long *, int *); static int copypktopts(struct ip6_pktopts *, struct ip6_pktopts *, int); -static int ip6_ifaddrvalid(const struct in6_addr *); +static int ip6_ifaddrvalid(const struct in6_addr *, const struct in6_addr *); static int ip6_handle_rthdr(struct ip6_rthdr *, struct ip6_hdr *); #ifdef RFC2292 @@ -605,7 +605,9 @@ ip6_output( /* scope check is done. */ /* Ensure we only send from a valid address. */ - if ((error = ip6_ifaddrvalid(&src0)) != 0) { + if ((ifp->if_flags & IFF_LOOPBACK) == 0 && + (error = ip6_ifaddrvalid(&src0, &dst0)) != 0) + { char ip6buf[INET6_ADDRSTRLEN]; nd6log(LOG_ERR, "refusing to send from invalid address %s (pid %d)\n", @@ -3363,27 +3365,31 @@ ip6_optlen(struct in6pcb *in6p) * if the packet could be dropped without error (protocol dependent). */ static int -ip6_ifaddrvalid(const struct in6_addr *addr) +ip6_ifaddrvalid(const struct in6_addr *src, const struct in6_addr *dst) { struct sockaddr_in6 sin6; int s, error; struct ifaddr *ifa; struct in6_ifaddr *ia6; - if (IN6_IS_ADDR_UNSPECIFIED(addr)) + if (IN6_IS_ADDR_UNSPECIFIED(src)) return 0; memset(&sin6, 0, sizeof(sin6)); sin6.sin6_family = AF_INET6; sin6.sin6_len = sizeof(sin6); - sin6.sin6_addr = *addr; + sin6.sin6_addr = *src; s = pserialize_read_enter(); ifa = ifa_ifwithaddr(sin6tosa(&sin6)); if ((ia6 = ifatoia6(ifa)) == NULL || ia6->ia6_flags & (IN6_IFF_ANYCAST | IN6_IFF_DUPLICATED)) error = -1; - else if (ia6->ia6_flags & (IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) + else if (ia6->ia6_flags & IN6_IFF_TENTATIVE) + error = 1; + else if (ia6->ia6_flags & IN6_IFF_DETACHED && + (sin6.sin6_addr = *dst, ifa_ifwithaddr(sin6tosa(&sin6)) == NULL)) + /* Allow internal traffic to DETACHED addresses */ error = 1; else error = 0;