Source-Changes-HG archive

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

[src/netbsd-1-6]: src/sys/netinet6 Pull up revision 1.39 via patch (requested...



details:   https://anonhg.NetBSD.org/src/rev/22486b4df1cf
branches:  netbsd-1-6
changeset: 530794:22486b4df1cf
user:      tron <tron%NetBSD.org@localhost>
date:      Thu Oct 02 20:30:08 2003 +0000

description:
Pull up revision 1.39 via patch (requested by itojun in ticket #1491):
sync with latest KAME in6_ifaddr/prefix/default router manipulation.
behavior changes:
- two iocts used by ndp(8) are now obsolete (backward compat provided).
  use sysctl path instead.
- lo0 does not get ::1 automatically.  it will get ::1 when lo0 comes up.

diffstat:

 sys/netinet6/nd6_nbr.c |  194 +++++++++++++++++++++++++++++++-----------------
 1 files changed, 123 insertions(+), 71 deletions(-)

diffs (truncated from 412 to 300 lines):

diff -r 526af770c025 -r 22486b4df1cf sys/netinet6/nd6_nbr.c
--- a/sys/netinet6/nd6_nbr.c    Thu Oct 02 20:29:06 2003 +0000
+++ b/sys/netinet6/nd6_nbr.c    Thu Oct 02 20:30:08 2003 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_nbr.c,v 1.34 2002/03/15 09:36:27 itojun Exp $      */
+/*     $NetBSD: nd6_nbr.c,v 1.34.6.1 2003/10/02 20:30:08 tron Exp $    */
 /*     $KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.34 2002/03/15 09:36:27 itojun Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.34.6.1 2003/10/02 20:30:08 tron Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -62,6 +62,7 @@
 #include <netinet6/ip6_var.h>
 #include <netinet6/nd6.h>
 #include <netinet/icmp6.h>
+#include <netinet6/in6_pcb.h>
 
 #ifdef IPSEC
 #include <netinet6/ipsec.h>
@@ -105,6 +106,7 @@
        struct ifaddr *ifa;
        int lladdrlen = 0;
        int anycast = 0, proxy = 0, tentative = 0;
+       int router = ip6_forwarding;
        int tlladdr;
        union nd_opts ndopts;
        struct sockaddr_dl *proxydl = NULL;
@@ -132,15 +134,15 @@
 
        if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
                /* dst has to be solicited node multicast address. */
-               if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL
-                   /* don't check ifindex portion */
-                   && daddr6.s6_addr32[1] == 0
-                   && daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE
-                   && daddr6.s6_addr8[12] == 0xff) {
+               /* don't check ifindex portion */
+               if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
+                   daddr6.s6_addr32[1] == 0 &&
+                   daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
+                   daddr6.s6_addr8[12] == 0xff) {
                        ; /* good */
                } else {
                        nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
-                               "(wrong ip6 dst)\n"));
+                           "(wrong ip6 dst)\n"));
                        goto bad;
                }
        }
@@ -224,6 +226,7 @@
                        if (ifa) {
                                proxy = 1;
                                proxydl = SDL(rt->rt_gateway);
+                               router = 0;     /* XXX */
                        }
                }
                if (rt)
@@ -244,16 +247,14 @@
                goto freeit;
 
        if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
-               nd6log((LOG_INFO,
-                   "nd6_ns_input: lladdrlen mismatch for %s "
+               nd6log((LOG_INFO, "nd6_ns_input: lladdrlen mismatch for %s "
                    "(if %d, NS packet %d)\n",
-                       ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2));
+                   ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2));
                goto bad;
        }
 
        if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
-               nd6log((LOG_INFO,
-                   "nd6_ns_input: duplicate IP6 address %s\n",
+               nd6log((LOG_INFO, "nd6_ns_input: duplicate IP6 address %s\n",
                    ip6_sprintf(&saddr6)));
                goto freeit;
        }
@@ -296,20 +297,18 @@
                saddr6 = in6addr_linklocal_allnodes;
                saddr6.s6_addr16[1] = htons(ifp->if_index);
                nd6_na_output(ifp, &saddr6, &taddr6,
-                             ((anycast || proxy || !tlladdr)
-                                     ? 0 : ND_NA_FLAG_OVERRIDE)
-                               | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0),
-                             tlladdr, (struct sockaddr *)proxydl);
+                   ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
+                   (router ? ND_NA_FLAG_ROUTER : 0),
+                   tlladdr, (struct sockaddr *)proxydl);
                goto freeit;
        }
 
        nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_NEIGHBOR_SOLICIT, 0);
 
        nd6_na_output(ifp, &saddr6, &taddr6,
-                     ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE)
-                       | (ip6_forwarding ? ND_NA_FLAG_ROUTER : 0)
-                       | ND_NA_FLAG_SOLICITED,
-                     tlladdr, (struct sockaddr *)proxydl);
+           ((anycast || proxy || !tlladdr) ? 0 : ND_NA_FLAG_OVERRIDE) |
+           (router ? ND_NA_FLAG_ROUTER : 0) | ND_NA_FLAG_SOLICITED,
+           tlladdr, (struct sockaddr *)proxydl);
  freeit:
        m_freem(m);
        return;
@@ -341,11 +340,14 @@
        struct mbuf *m;
        struct ip6_hdr *ip6;
        struct nd_neighbor_solicit *nd_ns;
-       struct in6_ifaddr *ia = NULL;
+       struct sockaddr_in6 src_sa, dst_sa;
        struct ip6_moptions im6o;
        int icmp6len;
        int maxlen;
        caddr_t mac;
+       struct route_in6 ro;
+
+       bzero(&ro, sizeof(ro));
        
        if (IN6_IS_ADDR_MULTICAST(taddr6))
                return;
@@ -393,16 +395,22 @@
        /* ip6->ip6_plen will be set later */
        ip6->ip6_nxt = IPPROTO_ICMPV6;
        ip6->ip6_hlim = 255;
+       /* determine the source and destination addresses */
+       bzero(&src_sa, sizeof(src_sa));
+       bzero(&dst_sa, sizeof(dst_sa));
+       src_sa.sin6_family = dst_sa.sin6_family = AF_INET6;
+       src_sa.sin6_len = dst_sa.sin6_len = sizeof(struct sockaddr_in6);
        if (daddr6)
-               ip6->ip6_dst = *daddr6;
+               dst_sa.sin6_addr = *daddr6;
        else {
-               ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
-               ip6->ip6_dst.s6_addr16[1] = htons(ifp->if_index);
-               ip6->ip6_dst.s6_addr32[1] = 0;
-               ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
-               ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3];
-               ip6->ip6_dst.s6_addr8[12] = 0xff;
+               dst_sa.sin6_addr.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
+               dst_sa.sin6_addr.s6_addr16[1] = htons(ifp->if_index);
+               dst_sa.sin6_addr.s6_addr32[1] = 0;
+               dst_sa.sin6_addr.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
+               dst_sa.sin6_addr.s6_addr32[3] = taddr6->s6_addr32[3];
+               dst_sa.sin6_addr.s6_addr8[12] = 0xff;
        }
+       ip6->ip6_dst = dst_sa.sin6_addr;
        if (!dad) {
                /*
                 * RFC2461 7.2.2:
@@ -417,7 +425,7 @@
                 * (saddr6), if:
                 * - saddr6 is given from the caller (by giving "ln"), and
                 * - saddr6 belongs to the outgoing interface.
-                * Otherwise, we perform a scope-wise match.
+                * Otherwise, we perform the source address selection as usual.
                 */
                struct ip6_hdr *hip6;           /* hold ip6 */
                struct in6_addr *saddr6;
@@ -432,22 +440,34 @@
                } else
                        saddr6 = NULL;
                if (saddr6 && in6ifa_ifpwithaddr(ifp, saddr6))
-                       bcopy(saddr6, &ip6->ip6_src, sizeof(*saddr6));
+                       src_sa.sin6_addr = *saddr6;
                else {
-                       ia = in6_ifawithifp(ifp, &ip6->ip6_dst);
-                       if (ia == NULL) {
-                               m_freem(m);
-                               return;
+                       struct in6_addr *src0;
+                       int error;
+
+                       bcopy(&dst_sa, &ro.ro_dst, sizeof(dst_sa));
+                       src0 = in6_selectsrc(&dst_sa, NULL, NULL, &ro, NULL,
+                           &error);
+                       if (src0 == NULL) {
+                               nd6log((LOG_DEBUG,
+                                   "nd6_ns_output: source can't be "
+                                   "determined: dst=%s, error=%d\n",
+                                   ip6_sprintf(&dst_sa.sin6_addr), error));
+                               goto bad;
                        }
-                       ip6->ip6_src = ia->ia_addr.sin6_addr;
+                       src_sa.sin6_addr = *src0;
                }
        } else {
                /*
                 * Source address for DAD packet must always be IPv6
                 * unspecified address. (0::0)
+                * We actually don't have to 0-clear the address (we did it
+                * above), but we do so here explicitly to make the intention
+                * clearer.
                 */
-               bzero(&ip6->ip6_src, sizeof(ip6->ip6_src));
+               bzero(&src_sa.sin6_addr, sizeof(src_sa.sin6_addr));
        }
+       ip6->ip6_src = src_sa.sin6_addr;
        nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
        nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
        nd_ns->nd_ns_code = 0;
@@ -486,31 +506,36 @@
 
        ip6->ip6_plen = htons((u_short)icmp6len);
        nd_ns->nd_ns_cksum = 0;
-       nd_ns->nd_ns_cksum
-               = in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
+       nd_ns->nd_ns_cksum =
+           in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
 
 #ifdef IPSEC
        /* Don't lookup socket */
        (void)ipsec_setsocket(m, NULL);
 #endif
-       ip6_output(m, NULL, NULL, 0, &im6o, NULL);
+       ip6_output(m, NULL, &ro, dad ? IPV6_UNSPECSRC : 0, &im6o, NULL);
        icmp6_ifstat_inc(ifp, ifs6_out_msg);
        icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
        icmp6stat.icp6s_outhist[ND_NEIGHBOR_SOLICIT]++;
 
+       if (ro.ro_rt) {         /* we don't cache this route. */
+               RTFREE(ro.ro_rt);
+       }
        return;
 
-#if 0
   bad:
+       if (ro.ro_rt) {
+               RTFREE(ro.ro_rt);
+       }
        m_freem(m);
        return;
-#endif
 }
 
 /*
  * Neighbor advertisement input handling.
  *
  * Based on RFC 2461
+       long time_second = time.tv_sec;
  * Based on RFC 2462 (duplicated address detection)
  *
  * the following items are not implemented yet:
@@ -576,12 +601,11 @@
                    ip6_sprintf(&taddr6)));
                goto bad;
        }
-       if (IN6_IS_ADDR_MULTICAST(&daddr6))
-               if (is_solicited) {
-                       nd6log((LOG_ERR,
-                           "nd6_na_input: a solicited adv is multicasted\n"));
-                       goto bad;
-               }
+       if (is_solicited && IN6_IS_ADDR_MULTICAST(&daddr6)) {
+               nd6log((LOG_ERR,
+                   "nd6_na_input: a solicited adv is multicasted\n"));
+               goto bad;
+       }
 
        icmp6len -= sizeof(*nd_na);
        nd6_option_init(nd_na + 1, icmp6len, &ndopts);
@@ -623,15 +647,15 @@
        }
 
        if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
-               nd6log((LOG_INFO,
-                   "nd6_na_input: lladdrlen mismatch for %s "
-                   "(if %d, NA packet %d)\n",
-                       ip6_sprintf(&taddr6), ifp->if_addrlen, lladdrlen - 2));
+               nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
+                   "(if %d, NA packet %d)\n", ip6_sprintf(&taddr6),
+                   ifp->if_addrlen, lladdrlen - 2));
                goto bad;
        }
 
        /*
-        * If no neighbor cache entry is found, NA SHOULD silently be discarded.
+        * If no neighbor cache entry is found, NA SHOULD silently be
+        * discarded.
         */
        rt = nd6_lookup(&taddr6, 0, ifp);
        if ((rt == NULL) ||
@@ -788,7 +812,7 @@
        ln->ln_asked = 0;
        if (ln->ln_hold) {
                /*
-                * we assume ifp is not a p2p here, so just set the 2nd
+                * we assume ifp is not a loopback here, so just set the 2nd
                 * argument as the 1st one.
                 */
                nd6_output(ifp, ifp, ln->ln_hold,
@@ -825,11 +849,15 @@
        struct mbuf *m;



Home | Main Index | Thread Index | Old Index