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