Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys Allow local communication over DETACHED addresses.



details:   https://anonhg.NetBSD.org/src/rev/9b5aba8c87b6
branches:  trunk
changeset: 828038:9b5aba8c87b6
user:      roy <roy%NetBSD.org@localhost>
date:      Fri Nov 24 14:03:25 2017 +0000

description:
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.

diffstat:

 sys/netinet/ip_input.c    |  20 +++++++++++++-------
 sys/netinet6/in6_src.c    |  18 +++++++++++-------
 sys/netinet6/ip6_input.c  |  26 +++++++++++++++++++++++---
 sys/netinet6/ip6_output.c |  22 ++++++++++++++--------
 4 files changed, 61 insertions(+), 25 deletions(-)

diffs (222 lines):

diff -r 6753ad55d518 -r 9b5aba8c87b6 sys/netinet/ip_input.c
--- a/sys/netinet/ip_input.c    Fri Nov 24 14:00:04 2017 +0000
+++ b/sys/netinet/ip_input.c    Fri Nov 24 14:03:25 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_input.c,v 1.362 2017/11/17 07:37:12 ozaki-r Exp $   */
+/*     $NetBSD: ip_input.c,v 1.363 2017/11/24 14:03:25 roy 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.362 2017/11/17 07:37:12 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip_input.c,v 1.363 2017/11/24 14:03:25 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -371,11 +371,14 @@
                                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;
                }
        }
 
@@ -392,7 +395,10 @@
                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) ||
diff -r 6753ad55d518 -r 9b5aba8c87b6 sys/netinet6/in6_src.c
--- a/sys/netinet6/in6_src.c    Fri Nov 24 14:00:04 2017 +0000
+++ b/sys/netinet6/in6_src.c    Fri Nov 24 14:03:25 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_src.c,v 1.82 2017/11/20 09:01:20 ozaki-r Exp $     */
+/*     $NetBSD: in6_src.c,v 1.83 2017/11/24 14:03:25 roy 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.82 2017/11/20 09:01:20 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_src.c,v 1.83 2017/11/24 14:03:25 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -217,10 +217,14 @@
                }
 
                /* 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;
+               /* Prefer validated addresses */
+               if (!(ia->ia6_flags & (IN6_IFF_TENTATIVE | IN6_IFF_DETACHED)) &&
+                   ia_best != NULL &&
+                   ia_best->ia6_flags & (IN6_IFF_TENTATIVE | IN6_IFF_DETACHED))
+                       REPLACE(0);
+
                if (!ip6_use_deprecated && IFA6_IS_DEPRECATED(ia))
                        continue;
 
@@ -238,7 +242,7 @@
                }
 
                if (ia_best == NULL)
-                       REPLACE(0);
+                       REPLACE(1);
 
                /* Rule 2: Prefer appropriate scope */
                if (dst_scope < 0)
diff -r 6753ad55d518 -r 9b5aba8c87b6 sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c  Fri Nov 24 14:00:04 2017 +0000
+++ b/sys/netinet6/ip6_input.c  Fri Nov 24 14:03:25 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_input.c,v 1.183 2017/11/17 07:37:12 ozaki-r Exp $  */
+/*     $NetBSD: ip6_input.c,v 1.184 2017/11/24 14:03:25 roy 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.183 2017/11/17 07:37:12 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.184 2017/11/24 14:03:25 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_gateway.h"
@@ -501,13 +501,33 @@
 #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 = 0;
+               if (addrok) {
                        /* this address is ready */
                        ours = 1;
                        deliverifp = ia6->ia_ifp;       /* correct? */
diff -r 6753ad55d518 -r 9b5aba8c87b6 sys/netinet6/ip6_output.c
--- a/sys/netinet6/ip6_output.c Fri Nov 24 14:00:04 2017 +0000
+++ b/sys/netinet6/ip6_output.c Fri Nov 24 14:03:25 2017 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_output.c,v 1.193 2017/08/02 01:28:03 ozaki-r Exp $ */
+/*     $NetBSD: ip6_output.c,v 1.194 2017/11/24 14:03:25 roy 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.193 2017/08/02 01:28:03 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_output.c,v 1.194 2017/11/24 14:03:25 roy Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -134,7 +134,7 @@
 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 @@
        /* 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 @@
  * 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 &&
+           ifa_ifwithaddr(sin6tosa(&dst)) == NULL)
+               /* Allow internal traffic to DETACHED addresses */
                error = 1;
        else
                error = 0;



Home | Main Index | Thread Index | Old Index