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