Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src implement upper limit to icmp6 redirects (experimental, turn...
details: https://anonhg.NetBSD.org/src/rev/14b9deabd097
branches: trunk
changeset: 503549:14b9deabd097
user: itojun <itojun%NetBSD.org@localhost>
date: Thu Feb 08 16:07:39 2001 +0000
description:
implement upper limit to icmp6 redirects (experimental, turned off)
negative value to {mtudisc,redirect}_{hi,lo}wat will turn off the limitation.
sync with kame.
diffstat:
lib/libc/gen/sysctl.3 | 3 +-
sys/netinet6/icmp6.c | 120 +++++++++++++++++++++++++++++++++++++++----------
2 files changed, 97 insertions(+), 26 deletions(-)
diffs (230 lines):
diff -r 584617def951 -r 14b9deabd097 lib/libc/gen/sysctl.3
--- a/lib/libc/gen/sysctl.3 Thu Feb 08 15:19:14 2001 +0000
+++ b/lib/libc/gen/sysctl.3 Thu Feb 08 16:07:39 2001 +0000
@@ -1,4 +1,4 @@
-.\" $NetBSD: sysctl.3,v 1.73 2001/02/07 08:59:47 itojun Exp $
+.\" $NetBSD: sysctl.3,v 1.74 2001/02/08 16:07:39 itojun Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -1072,6 +1072,7 @@
.Li icmp6.mtudisc_lowat
is used when we have unverified ICMPv6 too big messages.
Verification is performed by using address/port pairs kept in connected pcbs.
+Negative value disables the upper limit.
.It Li icmp6.nd6_debug
If set to non-zero, kernel IPv6 neighbor discovery code will generate
debugging messages.
diff -r 584617def951 -r 14b9deabd097 sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c Thu Feb 08 15:19:14 2001 +0000
+++ b/sys/netinet6/icmp6.c Thu Feb 08 16:07:39 2001 +0000
@@ -1,5 +1,4 @@
-/* $NetBSD: icmp6.c,v 1.54 2001/02/07 10:56:38 itojun Exp $ */
-/* $KAME: icmp6.c,v 1.191 2001/02/07 08:07:38 itojun Exp $ */
+/* $KAME: icmp6.c,v 1.194 2001/02/08 15:19:12 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -131,8 +130,17 @@
extern int pmtu_expire;
/* XXX do these values make any sense? */
-int icmp6_mtudisc_hiwat = 1280;
-int icmp6_mtudisc_lowat = 256;
+static int icmp6_mtudisc_hiwat = 1280;
+static int icmp6_mtudisc_lowat = 256;
+
+/*
+ * keep track of # of redirect routes.
+ */
+static struct rttimer_queue *icmp6_redirect_timeout_q = NULL;
+
+/* XXX experimental, turned off */
+static int icmp6_redirect_hiwat = -1;
+static int icmp6_redirect_lowat = -1;
static void icmp6_errcount __P((struct icmp6errstat *, int, int));
static int icmp6_rip6_input __P((struct mbuf **, int));
@@ -148,6 +156,7 @@
struct ifnet *, int));
static struct rtentry *icmp6_mtudisc_clone __P((struct sockaddr *));
static void icmp6_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
+static void icmp6_redirect_timeout __P((struct rtentry *, struct rttimer *));
#ifdef COMPAT_RFC1885
static struct route_in6 icmp6_reflect_rt;
@@ -158,6 +167,7 @@
{
mld6_init();
icmp6_mtudisc_timeout_q = rt_timer_queue_create(pmtu_expire);
+ icmp6_redirect_timeout_q = rt_timer_queue_create(icmp6_redirtimeout);
}
static void
@@ -1054,15 +1064,16 @@
*/
rtcount = rt_timer_count(icmp6_mtudisc_timeout_q);
if (validated) {
- if (rtcount > icmp6_mtudisc_hiwat)
+ if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat)
return;
- else if (rtcount > icmp6_mtudisc_lowat) {
+ else if (0 <= icmp6_mtudisc_lowat &&
+ rtcount > icmp6_mtudisc_lowat) {
/*
* XXX nuke a victim, install the new one.
*/
}
} else {
- if (rtcount > icmp6_mtudisc_lowat)
+ if (0 <= icmp6_mtudisc_lowat && rtcount > icmp6_mtudisc_lowat)
return;
}
@@ -1906,6 +1917,7 @@
int plen;
int type, code;
struct ifnet *outif = NULL;
+ struct sockaddr_in6 sa6_src, sa6_dst;
#ifdef COMPAT_RFC1885
int mtu = IPV6_MMTU;
struct sockaddr_in6 *sin6 = &icmp6_reflect_rt.ro_dst;
@@ -1963,12 +1975,24 @@
*/
ip6->ip6_dst = ip6->ip6_src;
- /* XXX hack for link-local addresses */
- if (IN6_IS_ADDR_LINKLOCAL(&ip6->ip6_dst))
- ip6->ip6_dst.s6_addr16[1] =
- htons(m->m_pkthdr.rcvif->if_index);
- if (IN6_IS_ADDR_LINKLOCAL(&t))
- t.s6_addr16[1] = htons(m->m_pkthdr.rcvif->if_index);
+ /*
+ * XXX: make sure to embed scope zone information, using
+ * already embedded IDs or the received interface (if any).
+ * Note that rcvif may be NULL.
+ * TODO: scoped routing case (XXX).
+ */
+ bzero(&sa6_src, sizeof(sa6_src));
+ sa6_src.sin6_family = AF_INET6;
+ sa6_src.sin6_len = sizeof(sa6_src);
+ sa6_src.sin6_addr = ip6->ip6_dst;
+ in6_recoverscope(&sa6_src, &ip6->ip6_dst, m->m_pkthdr.rcvif);
+ in6_embedscope(&ip6->ip6_dst, &sa6_src, NULL, NULL);
+ bzero(&sa6_dst, sizeof(sa6_dst));
+ sa6_dst.sin6_family = AF_INET6;
+ sa6_dst.sin6_len = sizeof(sa6_dst);
+ sa6_dst.sin6_addr = t;
+ in6_recoverscope(&sa6_dst, &t, m->m_pkthdr.rcvif);
+ in6_embedscope(&t, &sa6_dst, NULL, NULL);
#ifdef COMPAT_RFC1885
/*
@@ -1980,6 +2004,7 @@
if (icmp6_reflect_rt.ro_rt == 0 ||
! (IN6_ARE_ADDR_EQUAL(&sin6->sin6_addr, &ip6->ip6_dst))) {
if (icmp6_reflect_rt.ro_rt) {
+ RTFREE(icmp6_reflect_rt.ro_rt);
icmp6_reflect_rt.ro_rt = 0;
}
bzero(sin6, sizeof(*sin6));
@@ -2023,19 +2048,27 @@
src = &t;
}
- if (src == 0)
+ if (src == 0) {
+ int e;
+ struct route_in6 ro;
+
/*
* This case matches to multicasts, our anycast, or unicasts
- * that we do not own. Select a source address which has the
- * same scope.
- * XXX: for (non link-local) multicast addresses, this might
- * not be a good choice.
+ * that we do not own. Select a source address based on the
+ * source address of the erroneous packet.
*/
- if ((ia = in6_ifawithscope(m->m_pkthdr.rcvif, &t)) != 0)
- src = &IA6_SIN6(ia)->sin6_addr;
-
- if (src == 0)
- goto bad;
+ bzero(&ro, sizeof(ro));
+ src = in6_selectsrc(&sa6_src, NULL, NULL, &ro, NULL, &e);
+ if (ro.ro_rt)
+ RTFREE(ro.ro_rt); /* XXX: we could use this */
+ if (src == NULL) {
+ nd6log((LOG_DEBUG,
+ "icmp6_reflect: source can't be determined: "
+ "dst=%s, error=%d\n",
+ ip6_sprintf(&sa6_src.sin6_addr), e));
+ goto bad;
+ }
+ }
ip6->ip6_src = *src;
@@ -2260,6 +2293,24 @@
struct sockaddr_in6 sdst;
struct sockaddr_in6 sgw;
struct sockaddr_in6 ssrc;
+ unsigned long rtcount;
+ struct rtentry *newrt = NULL;
+
+ /*
+ * do not install redirect route, if the number of entries
+ * is too much (> hiwat). note that, the node (= host) will
+ * work just fine even if we do not install redirect route
+ * (there will be additional hops, though).
+ */
+ rtcount = rt_timer_count(icmp6_redirect_timeout_q);
+ if (0 <= icmp6_redirect_hiwat && rtcount > icmp6_redirect_hiwat)
+ return;
+ else if (0 <= icmp6_redirect_lowat &&
+ rtcount > icmp6_redirect_lowat) {
+ /*
+ * XXX nuke a victim, install the new one.
+ */
+ }
bzero(&sdst, sizeof(sdst));
bzero(&sgw, sizeof(sgw));
@@ -2273,8 +2324,13 @@
rtredirect((struct sockaddr *)&sdst, (struct sockaddr *)&sgw,
(struct sockaddr *)NULL, RTF_GATEWAY | RTF_HOST,
(struct sockaddr *)&ssrc,
- (struct rtentry **)NULL
- );
+ &newrt);
+
+ if (newrt) {
+ (void)rt_timer_add(newrt, icmp6_redirect_timeout,
+ icmp6_redirect_timeout_q);
+ rtfree(newrt);
+ }
}
/* finally update cached route in each socket via pfctlinput */
{
@@ -2740,6 +2796,20 @@
}
}
+static void
+icmp6_redirect_timeout(rt, r)
+ struct rtentry *rt;
+ struct rttimer *r;
+{
+ if (rt == NULL)
+ panic("icmp6_redirect_timeout: bad route to timeout");
+ if ((rt->rt_flags & (RTF_GATEWAY | RTF_DYNAMIC | RTF_HOST)) ==
+ (RTF_GATEWAY | RTF_DYNAMIC | RTF_HOST)) {
+ rtrequest((int) RTM_DELETE, (struct sockaddr *)rt_key(rt),
+ rt->rt_gateway, rt_mask(rt), rt->rt_flags, 0);
+ }
+}
+
#include <uvm/uvm_extern.h>
#include <sys/sysctl.h>
Home |
Main Index |
Thread Index |
Old Index