update icmp6 too big validation. the change is necessary since pmtud is

mandatory for IPv6 (so we can't just validate by using connected pcb - we need
to allow traffic from unconnected pcb to do pmtud).
- if the traffic is validated by xx_ctlinput, allow up to "hiwat" pmtud
  route entries.
- if the traffic was not validated by xx_ctlinput, allow up to "lowat" pmtud
  route entries (there's upper limit, so bad guys cannot blow up our routing
  table).
sync with kame

XXX need to think again about default hiwat/lowat value.
XXX victim selection to help starvation case
This commit is contained in:
itojun 2000-12-09 01:29:45 +00:00
parent 2eabd5aae0
commit 5eae50d991
8 changed files with 95 additions and 36 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: route.c,v 1.36 2000/03/30 09:45:40 augustss Exp $ */
/* $NetBSD: route.c,v 1.37 2000/12/09 01:29:45 itojun Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -698,6 +698,7 @@ rt_timer_queue_create(timeout)
Bzero(rtq, sizeof *rtq);
rtq->rtq_timeout = timeout;
rtq->rtq_count = 0;
TAILQ_INIT(&rtq->rtq_head);
LIST_INSERT_HEAD(&rttimer_queue_head, rtq, rtq_link);
@ -713,7 +714,6 @@ rt_timer_queue_change(rtq, timeout)
rtq->rtq_timeout = timeout;
}
void
rt_timer_queue_destroy(rtq, destroy)
struct rttimer_queue *rtq;
@ -727,6 +727,10 @@ rt_timer_queue_destroy(rtq, destroy)
if (destroy)
RTTIMER_CALLOUT(r);
pool_put(&rttimer_pool, r);
if (rtq->rtq_count > 0)
rtq->rtq_count--;
else
printf("rt_timer_queue_destroy: rtq_count reached 0\n");
}
LIST_REMOVE(rtq, rtq_link);
@ -736,6 +740,14 @@ rt_timer_queue_destroy(rtq, destroy)
*/
}
unsigned long
rt_timer_count(rtq)
struct rttimer_queue *rtq;
{
return rtq->rtq_count;
}
void
rt_timer_remove_all(rt)
struct rtentry *rt;
@ -746,6 +758,10 @@ rt_timer_remove_all(rt)
LIST_REMOVE(r, rtt_link);
TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
pool_put(&rttimer_pool, r);
if (r->rtt_queue->rtq_count > 0)
r->rtt_queue->rtq_count--;
else
printf("rt_timer_remove_all: rtq_count reached 0\n");
}
}
@ -773,6 +789,10 @@ rt_timer_add(rt, func, queue)
LIST_REMOVE(r, rtt_link);
TAILQ_REMOVE(&r->rtt_queue->rtq_head, r, rtt_next);
pool_put(&rttimer_pool, r);
if (r->rtt_queue->rtq_count > 0)
r->rtt_queue->rtq_count--;
else
printf("rt_timer_add: rtq_count reached 0\n");
break; /* only one per list, so we can quit... */
}
}
@ -788,6 +808,7 @@ rt_timer_add(rt, func, queue)
r->rtt_queue = queue;
LIST_INSERT_HEAD(&rt->rt_timer, r, rtt_link);
TAILQ_INSERT_TAIL(&queue->rtq_head, r, rtt_next);
r->rtt_queue->rtq_count++;
return (0);
}
@ -815,6 +836,10 @@ rt_timer_timer(arg)
TAILQ_REMOVE(&rtq->rtq_head, r, rtt_next);
RTTIMER_CALLOUT(r);
pool_put(&rttimer_pool, r);
if (rtq->rtq_count > 0)
rtq->rtq_count--;
else
printf("rt_timer_timer: rtq_count reached 0\n");
}
}
splx(s);

View File

@ -1,4 +1,4 @@
/* $NetBSD: route.h,v 1.22 2000/05/04 17:33:03 ragge Exp $ */
/* $NetBSD: route.h,v 1.23 2000/12/09 01:29:45 itojun Exp $ */
/*
* Copyright (c) 1980, 1986, 1993
@ -255,6 +255,7 @@ struct rttimer {
struct rttimer_queue {
long rtq_timeout;
unsigned long rtq_count;
TAILQ_HEAD(, rttimer) rtq_head;
LIST_ENTRY(rttimer_queue) rtq_link;
};
@ -297,6 +298,7 @@ struct rttimer_queue *
void rt_timer_queue_change __P((struct rttimer_queue *, long));
void rt_timer_queue_destroy __P((struct rttimer_queue *, int));
void rt_timer_remove_all __P((struct rtentry *));
unsigned long rt_timer_count __P((struct rttimer_queue *));
void rt_timer_timer __P((void *));
void rtable_init __P((void **));
void rtalloc __P((struct route *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.h,v 1.15 2000/10/18 21:14:12 itojun Exp $ */
/* $NetBSD: icmp6.h,v 1.16 2000/12/09 01:29:48 itojun Exp $ */
/* $KAME: icmp6.h,v 1.24 2000/10/18 19:24:24 itojun Exp $ */
/*
@ -557,7 +557,9 @@ struct icmp6stat {
#define ICMPV6CTL_NODEINFO 13
#define ICMPV6CTL_ERRPPSLIMIT 14 /* ICMPv6 error pps limitation */
#define ICMPV6CTL_ND6_MAXNUDHINT 15
#define ICMPV6CTL_MAXID 16
#define ICMPV6CTL_MTUDISC_HIWAT 16
#define ICMPV6CTL_MTUDISC_LOWAT 17
#define ICMPV6CTL_MAXID 18
#define ICMPV6CTL_NAMES { \
{ 0, 0 }, \
@ -576,6 +578,8 @@ struct icmp6stat {
{ "nodeinfo", CTLTYPE_INT }, \
{ "errppslimit", CTLTYPE_INT }, \
{ "nd6_maxnudhint", CTLTYPE_INT }, \
{ "mtudisc_hiwat", CTLTYPE_INT }, \
{ "mtudisc_lowat", CTLTYPE_INT }, \
}
#define RTF_PROBEMTU RTF_PROTO1
@ -598,7 +602,7 @@ void icmp6_redirect_output __P((struct mbuf *, struct rtentry *));
int icmp6_sysctl __P((int *, u_int, void *, size_t *, void *, size_t));
struct ip6ctlparam;
void icmp6_mtudisc_update __P((struct ip6ctlparam *));
void icmp6_mtudisc_update __P((struct ip6ctlparam *, int));
void icmp6_mtudisc_callback_register __P((void (*)(struct in6_addr *)));
/* XXX: is this the right place for these macros? */

View File

@ -1,4 +1,4 @@
/* $NetBSD: tcp_subr.c,v 1.103 2000/10/29 06:33:59 itojun Exp $ */
/* $NetBSD: tcp_subr.c,v 1.104 2000/12/09 01:29:48 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -1179,14 +1179,16 @@ tcp6_ctlinput(cmd, sa, d)
thp = (struct tcphdr *)(mtod(m, caddr_t) + off);
if (cmd == PRC_MSGSIZE) {
int valid = 0;
/*
* Check to see if we have a valid TCP connection
* corresponding to the address in the ICMPv6 message
* payload.
*/
if (!in6_pcblookup_connect(&tcb6, &finaldst,
if (in6_pcblookup_connect(&tcb6, &finaldst,
thp->th_dport, &s, thp->th_sport, 0))
return;
valid++;
/*
* Now that we've validated that we are actually
@ -1194,7 +1196,7 @@ tcp6_ctlinput(cmd, sa, d)
* message, recalculate the new MTU, and create the
* corresponding routing entry.
*/
icmp6_mtudisc_update((struct ip6ctlparam *)d);
icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ah_input.c,v 1.22 2000/10/19 00:40:44 itojun Exp $ */
/* $NetBSD: ah_input.c,v 1.23 2000/12/09 01:29:50 itojun Exp $ */
/* $KAME: ah_input.c,v 1.37 2000/10/19 00:37:50 itojun Exp $ */
/*
@ -1080,31 +1080,30 @@ ah6_ctlinput(cmd, sa, d)
ahp = (struct newah *)(mtod(m, caddr_t) + off);
if (cmd == PRC_MSGSIZE) {
int valid = 0;
/*
* Check to see if we have a valid SA corresponding to
* the address in the ICMP message payload.
*/
sav = key_allocsa(AF_INET6, (caddr_t)&s,
(caddr_t)&finaldst, IPPROTO_AH, ahp->ah_spi);
if (sav == NULL)
return;
if (sav->state != SADB_SASTATE_MATURE &&
sav->state != SADB_SASTATE_DYING) {
if (sav) {
if (sav->state == SADB_SASTATE_MATURE ||
sav->state == SADB_SASTATE_DYING)
valid++;
key_freesav(sav);
return;
}
/* XXX Further validation? */
key_freesav(sav);
/*
* Now that we've validated that we are actually
* communicating with the host indicated in the ICMPv6
* message, recalculate the new MTU, and create the
* corresponding routing entry.
*/
icmp6_mtudisc_update((struct ip6ctlparam *)d);
icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: esp_input.c,v 1.12 2000/10/19 00:40:45 itojun Exp $ */
/* $NetBSD: esp_input.c,v 1.13 2000/12/09 01:29:50 itojun Exp $ */
/* $KAME: esp_input.c,v 1.37 2000/10/19 00:37:50 itojun Exp $ */
/*
@ -983,31 +983,29 @@ esp6_ctlinput(cmd, sa, d)
espp = (struct newesp*)(mtod(m, caddr_t) + off);
if (cmd == PRC_MSGSIZE) {
int valid = 0;
/*
* Check to see if we have a valid SA corresponding to
* the address in the ICMP message payload.
*/
sav = key_allocsa(AF_INET6, (caddr_t)&s,
(caddr_t)&finaldst, IPPROTO_ESP, espp->esp_spi);
if (sav == NULL)
return;
if (sav->state != SADB_SASTATE_MATURE &&
sav->state != SADB_SASTATE_DYING) {
if (sav) {
if (sav->state == SADB_SASTATE_MATURE ||
sav->state == SADB_SASTATE_DYING)
valid++;
key_freesav(sav);
return;
}
/* XXX Further validation? */
key_freesav(sav);
/*
* Now that we've validated that we are actually
* communicating with the host indicated in the ICMPv6
* message, recalculate the new MTU, and create the
* corresponding routing entry.
*/
icmp6_mtudisc_update((struct ip6ctlparam *)d);
icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
return;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: icmp6.c,v 1.47 2000/11/11 00:46:37 itojun Exp $ */
/* $NetBSD: icmp6.c,v 1.48 2000/12/09 01:29:50 itojun Exp $ */
/* $KAME: icmp6.c,v 1.156 2000/10/19 19:21:07 itojun Exp $ */
/*
@ -130,6 +130,10 @@ LIST_HEAD(, icmp6_mtudisc_callback) icmp6_mtudisc_callbacks =
static struct rttimer_queue *icmp6_mtudisc_timeout_q = NULL;
extern int pmtu_expire;
/* XXX do these values make any sense? */
int icmp6_mtudisc_hiwat = 1280;
int icmp6_mtudisc_lowat = 256;
static void icmp6_errcount __P((struct icmp6errstat *, int, int));
static int icmp6_rip6_input __P((struct mbuf **, int));
static int icmp6_ratelimit __P((const struct in6_addr *, const int, const int));
@ -1038,9 +1042,11 @@ icmp6_input(mp, offp, proto)
}
void
icmp6_mtudisc_update(ip6cp)
icmp6_mtudisc_update(ip6cp, validated)
struct ip6ctlparam *ip6cp;
int validated;
{
unsigned long rtcount;
struct icmp6_mtudisc_callback *mc;
struct in6_addr *dst = ip6cp->ip6c_finaldst;
struct icmp6_hdr *icmp6 = ip6cp->ip6c_icmp6;
@ -1049,6 +1055,24 @@ icmp6_mtudisc_update(ip6cp)
struct rtentry *rt = NULL;
struct sockaddr_in6 sin6;
/*
* allow non-validated cases if memory is plenty, to make traffic
* from non-connected pcb happy.
*/
rtcount = rt_timer_count(icmp6_mtudisc_timeout_q);
if (validated) {
if (rtcount > icmp6_mtudisc_hiwat)
return;
else if (rtcount > icmp6_mtudisc_lowat) {
/*
* XXX nuke a victim, install the new one.
*/
}
} else {
if (rtcount > icmp6_mtudisc_lowat)
return;
}
bzero(&sin6, sizeof(sin6));
sin6.sin6_family = PF_INET6;
sin6.sin6_len = sizeof(struct sockaddr_in6);
@ -2791,6 +2815,12 @@ icmp6_sysctl(name, namelen, oldp, oldlenp, newp, newlen)
case ICMPV6CTL_ND6_MAXNUDHINT:
return sysctl_int(oldp, oldlenp, newp, newlen,
&nd6_maxnudhint);
case ICMPV6CTL_MTUDISC_HIWAT:
return sysctl_int(oldp, oldlenp, newp, newlen,
&icmp6_mtudisc_hiwat);
case ICMPV6CTL_MTUDISC_LOWAT:
return sysctl_int(oldp, oldlenp, newp, newlen,
&icmp6_mtudisc_lowat);
default:
return ENOPROTOOPT;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: udp6_usrreq.c,v 1.35 2000/11/06 00:50:13 itojun Exp $ */
/* $NetBSD: udp6_usrreq.c,v 1.36 2000/12/09 01:29:50 itojun Exp $ */
/* $KAME: udp6_usrreq.c,v 1.62 2000/10/19 01:11:05 itojun Exp $ */
/*
@ -539,6 +539,7 @@ udp6_ctlinput(cmd, sa, d)
uhp = (struct udphdr *)(mtod(m, caddr_t) + off);
if (cmd == PRC_MSGSIZE) {
int valid = 0;
/*
* Check to see if we have a valid UDP socket
* corresponding to the address in the ICMPv6 message
@ -546,7 +547,7 @@ udp6_ctlinput(cmd, sa, d)
*/
if (in6_pcblookup_connect(&udb6, &finaldst,
uhp->uh_dport, &s, uhp->uh_sport, 0))
;
valid++;
#if 0
/*
* As the use of sendto(2) is fairly popular,
@ -557,10 +558,8 @@ udp6_ctlinput(cmd, sa, d)
*/
else if (in6_pcblookup_bind(&udb6, &finaldst,
uhp->uh_dport, 0))
;
valid++;
#endif
else
return;
/*
* Now that we've validated that we are actually
@ -568,7 +567,7 @@ udp6_ctlinput(cmd, sa, d)
* message, recalculate the new MTU, and create the
* corresponding routing entry.
*/
icmp6_mtudisc_update((struct ip6ctlparam *)d);
icmp6_mtudisc_update((struct ip6ctlparam *)d, valid);
return;
}