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:
parent
2eabd5aae0
commit
5eae50d991
|
@ -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);
|
||||
|
|
|
@ -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 *));
|
||||
|
|
|
@ -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? */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue