Source-Changes-HG archive

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

[src/trunk]: src/sys/netinet6 do not try NUD unless the gateway is a real nei...



details:   https://anonhg.NetBSD.org/src/rev/fe7f71080810
branches:  trunk
changeset: 485951:fe7f71080810
user:      itojun <itojun%NetBSD.org@localhost>
date:      Tue May 09 11:51:12 2000 +0000

description:
do not try NUD unless the gateway is a real neighbor.
real fix to KAME PR 245 (workaround has been implemented).

diffstat:

 sys/netinet6/icmp6.c |  45 +++++++++++++++-----------
 sys/netinet6/nd6.c   |  85 ++++++++++++++++++++++++++++++++++++---------------
 sys/netinet6/nd6.h   |   6 +-
 3 files changed, 89 insertions(+), 47 deletions(-)

diffs (truncated from 353 to 300 lines):

diff -r ecc923137d81 -r fe7f71080810 sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c      Tue May 09 10:49:26 2000 +0000
+++ b/sys/netinet6/icmp6.c      Tue May 09 11:51:12 2000 +0000
@@ -1,10 +1,10 @@
-/*     $NetBSD: icmp6.c,v 1.28 2000/04/13 14:07:10 itojun Exp $        */
-/*     $KAME: icmp6.c,v 1.75 2000/03/11 09:32:17 itojun Exp $  */
+/*     $NetBSD: icmp6.c,v 1.29 2000/05/09 11:51:12 itojun Exp $        */
+/*     $KAME: icmp6.c,v 1.82 2000/05/05 13:27:14 sumikawa Exp $        */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
  * All rights reserved.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -16,7 +16,7 @@
  * 3. Neither the name of the project nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
- * 
+ *
  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -133,7 +133,7 @@
 
 #ifdef COMPAT_RFC1885
 static struct route_in6 icmp6_reflect_rt;
-#endif 
+#endif
 
 void
 icmp6_init()
@@ -388,7 +388,7 @@
                        /* I mean "source address was incorrect." */
                        code = PRC_PARAMPROB;
                        break;
-#endif 
+#endif
                case ICMP6_DST_UNREACH_NOPORT:
                        code = PRC_UNREACH_PORT;
                        break;
@@ -981,7 +981,7 @@
  */
 #ifndef offsetof               /* XXX */
 #define        offsetof(type, member)  ((size_t)(&((type *)0)->member))
-#endif 
+#endif
 
 static struct mbuf *
 ni6_input(m, off)
@@ -1021,7 +1021,7 @@
                 addrs = ni6_addrs(ni6, m, &ifp);
                 if ((replylen += addrs * sizeof(struct in6_addr)) > MCLBYTES)
                         replylen = MCLBYTES; /* XXX: we'll truncate later */
-                
+               
                 break;
         default:
                 /*
@@ -1050,7 +1050,7 @@
                if (replylen > MCLBYTES)
                         /*
                          * XXX: should we try to allocate more? But MCLBYTES is
-                         * probably much larger than IPV6_MMTU... 
+                         * probably much larger than IPV6_MMTU...
                          */
                        goto bad;
                MCLGET(n, M_DONTWAIT);
@@ -1062,7 +1062,7 @@
 
        /* copy mbuf header and IPv6 + Node Information base headers */
        bcopy(mtod(m, caddr_t), mtod(n, caddr_t), sizeof(struct ip6_hdr));
-       nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1); 
+       nni6 = (struct icmp6_nodeinfo *)(mtod(n, struct ip6_hdr *) + 1);
        bcopy((caddr_t)ni6, (caddr_t)nni6, sizeof(struct icmp6_nodeinfo));
 
        /* qtype dependent procedure */
@@ -1077,7 +1077,7 @@
                 if (hostnamelen > 255) { /* XXX: rare case, but may happen */
                         printf("ni6_input: "
                                "hostname length(%d) is too large for reply\n",
-                               hostnamelen);
+                               (int)hostnamelen);
                         goto bad;
                 }
                 fqdn = (struct ni_reply_fqdn *)(mtod(n, caddr_t) +
@@ -1398,7 +1398,7 @@
 #ifdef COMPAT_RFC1885
        int mtu = IPV6_MMTU;
        struct sockaddr_in6 *sin6 = &icmp6_reflect_rt.ro_dst;
-#endif 
+#endif
 
        /* too short to reflect */
        if (off < sizeof(struct ip6_hdr)) {
@@ -1485,7 +1485,7 @@
                plen -= (m->m_pkthdr.len - mtu);
                m_adj(m, mtu - m->m_pkthdr.len);
        }
-#endif 
+#endif
        /*
         * If the incoming packet was addressed directly to us(i.e. unicast),
         * use dst as the src for the reply.
@@ -1518,7 +1518,7 @@
                if ((ia = in6_ifawithscope(m->m_pkthdr.rcvif, &t)) != 0)
                        src = &IA6_SIN6(ia)->sin6_addr;
 
-       if (src == 0) 
+       if (src == 0)
                goto bad;
 
        ip6->ip6_src = *src;
@@ -1799,6 +1799,7 @@
        size_t maxlen;
        u_char *p;
        struct ifnet *outif = NULL;
+       struct sockaddr_in6 src_sa;
 
        /* if we are not router, we don't send icmp6 redirect */
        if (!ip6_forwarding || ip6_accept_rtadv)
@@ -1815,7 +1816,13 @@
         *  [RFC 2461, sec 8.2]
         */
        sip6 = mtod(m0, struct ip6_hdr *);
-       if (nd6_is_addr_neighbor(&sip6->ip6_src, ifp) == 0)
+       bzero(&src_sa, sizeof(src_sa));
+       src_sa.sin6_family = AF_INET6;
+       src_sa.sin6_len = sizeof(src_sa);
+       src_sa.sin6_addr = sip6->ip6_src;
+       /* we don't currently use sin6_scope_id, but eventually use it */
+       src_sa.sin6_scope_id = in6_addr2scopeid(ifp, &sip6->ip6_src);
+       if (nd6_is_addr_neighbor(&src_sa, ifp) == 0)
                goto fail;
        if (IN6_IS_ADDR_MULTICAST(&sip6->ip6_dst))
                goto fail;      /* what should we do here? */
@@ -2164,14 +2171,14 @@
        rt = rtalloc1(dst, 1);
        if (rt == 0)
                return NULL;
-    
+
        /* If we didn't get a host route, allocate one */
        if ((rt->rt_flags & RTF_HOST) == 0) {
                struct rtentry *nrt;
 
-               error = rtrequest((int) RTM_ADD, dst, 
+               error = rtrequest((int) RTM_ADD, dst,
                    (struct sockaddr *) rt->rt_gateway,
-                   (struct sockaddr *) 0, 
+                   (struct sockaddr *) 0,
                    RTF_GATEWAY | RTF_HOST | RTF_DYNAMIC, &nrt);
                if (error) {
                        rtfree(rt);
@@ -2199,7 +2206,7 @@
 {
        if (rt == NULL)
                panic("icmp6_mtudisc_timeout: bad route to timeout");
-       if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) == 
+       if ((rt->rt_flags & (RTF_DYNAMIC | RTF_HOST)) ==
            (RTF_DYNAMIC | RTF_HOST)) {
                rtrequest((int) RTM_DELETE, (struct sockaddr *)rt_key(rt),
                    rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
diff -r ecc923137d81 -r fe7f71080810 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Tue May 09 10:49:26 2000 +0000
+++ b/sys/netinet6/nd6.c        Tue May 09 11:51:12 2000 +0000
@@ -1,5 +1,5 @@
-/*     $NetBSD: nd6.c,v 1.28 2000/04/27 00:33:47 itojun Exp $  */
-/*     $KAME: nd6.c,v 1.56 2000/04/19 06:17:43 itojun Exp $    */
+/*     $NetBSD: nd6.c,v 1.29 2000/05/09 11:51:12 itojun Exp $  */
+/*     $KAME: nd6.c,v 1.62 2000/05/09 11:35:55 itojun Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -173,15 +173,7 @@
        ND.reachable = ND_COMPUTE_RTIME(ND.basereachable);
        ND.retrans = RETRANS_TIMER;
        ND.receivedra = 0;
-#if 1
-       /* XXX temporary workaround */
-       if (ifp->if_flags & IFF_POINTOPOINT)
-               ND.flags = 0;
-       else
-               ND.flags = ND6_IFF_PERFORMNUD;
-#else
        ND.flags = ND6_IFF_PERFORMNUD;
-#endif
        nd6_setmtu(ifp);
 #undef ND
 }
@@ -748,7 +740,7 @@
  */
 int
 nd6_is_addr_neighbor(addr, ifp)
-       struct in6_addr *addr;
+       struct sockaddr_in6 *addr;
        struct ifnet *ifp;
 {
        register struct ifaddr *ifa;
@@ -757,8 +749,13 @@
 #define IFADDR6(a) ((((struct in6_ifaddr *)(a))->ia_addr).sin6_addr)
 #define IFMASK6(a) ((((struct in6_ifaddr *)(a))->ia_prefixmask).sin6_addr)
 
-       /* A link-local address is always a neighbor. */
-       if (IN6_IS_ADDR_LINKLOCAL(addr))
+       /*
+        * A link-local address is always a neighbor.
+        * XXX: we should use the sin6_scope_id field rather than the embedded
+        * interface index.
+        */
+       if (IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr) &&
+           ntohs(*(u_int16_t *)&addr->sin6_addr.s6_addr[2]) == ifp->if_index)
                return(1);
 
        /*
@@ -773,7 +770,8 @@
                        next: continue;
 
                for (i = 0; i < 4; i++) {
-                       if ((IFADDR6(ifa).s6_addr32[i] ^ addr->s6_addr32[i]) &
+                       if ((IFADDR6(ifa).s6_addr32[i] ^
+                            addr->sin6_addr.s6_addr32[i]) &
                            IFMASK6(ifa).s6_addr32[i])
                                goto next;
                }
@@ -784,7 +782,7 @@
         * Even if the address matches none of our addresses, it might be
         * in the neighbor cache.
         */
-       if (nd6_lookup(addr, 0, ifp))
+       if (nd6_lookup(&addr->sin6_addr, 0, ifp))
                return(1);
 
        return(0);
@@ -1751,6 +1749,7 @@
 {
        register struct mbuf *m = m0;
        register struct rtentry *rt = rt0;
+       struct sockaddr_in6 *gw6 = NULL;
        struct llinfo_nd6 *ln = NULL;
        int error = 0;
        long time_second = time.tv_sec;
@@ -1762,7 +1761,7 @@
         * XXX: we currently do not make neighbor cache on any interface
         * other than ARCnet, Ethernet, FDDI and GIF.
         *
-        * draft-ietf-ngtrans-mech-04.txt says:
+        * draft-ietf-ngtrans-mech-06.txt says:
         * - unidirectional tunnels needs no ND
         */
        switch (ifp->if_type) {
@@ -1775,10 +1774,6 @@
                goto sendpkt;
        }
 
-       if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
-           (nd_ifinfo[ifp->if_index].flags & ND6_IFF_PERFORMNUD) == 0)
-               goto sendpkt;
-
        /*
         * next hop determination. This routine is derived from ether_outpout.
         */
@@ -1793,7 +1788,35 @@
                        } else
                                senderr(EHOSTUNREACH);
                }
+
                if (rt->rt_flags & RTF_GATEWAY) {
+                       gw6 = (struct sockaddr_in6 *)rt->rt_gateway;
+
+                       /*
+                        * We skip link-layer address resolution and NUD
+                        * if the gateway is not a neighbor from ND point
+                        * of view, regardless the value of the value of
+                        * nd_ifinfo.flags.
+                        * The second condition is a bit tricky: we skip
+                        * if the gateway is our own address, which is
+                        * sometimes used to install a route to a p2p link.
+                        */
+                       if (!nd6_is_addr_neighbor(gw6, ifp) ||
+                           in6ifa_ifpwithaddr(ifp, &gw6->sin6_addr)) {
+                               if (rt->rt_flags & RTF_REJECT)
+                                       senderr(EHOSTDOWN);
+
+                               /*
+                                * We allow this kind of tricky route only
+                                * when the outgoing interface is p2p.
+                                * XXX: we may need a more generic rule here.
+                                */
+                               if ((ifp->if_flags & IFF_POINTOPOINT) == 0)
+                                       senderr(EHOSTUNREACH);
+
+                               goto sendpkt;
+                       }
+
                        if (rt->rt_gwroute == 0)
                                goto lookup;



Home | Main Index | Thread Index | Old Index