diff options
author | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-10-10 14:24:35 +0000 |
---|---|---|
committer | Jun-ichiro itojun Hagino <itojun@cvs.openbsd.org> | 2000-10-10 14:24:35 +0000 |
commit | 6bf4b0ac08bc472a2f11aa0c7fa5d55f03bc8604 (patch) | |
tree | 652d7914c92649d7c2dab7e8a8a621ec5d237eb6 | |
parent | 9cf3e77903bf3e98ce3533d22f5740b39d1805e1 (diff) |
bring in icmp rate limitation code.
make icmp6 rate limitation to latest (uses ppsratecheck only).
(sync with netbsd)
TODO: tcp SYN rate limit?
-rw-r--r-- | sys/netinet/icmp6.h | 6 | ||||
-rw-r--r-- | sys/netinet/icmp_var.h | 6 | ||||
-rw-r--r-- | sys/netinet/ip_icmp.c | 47 | ||||
-rw-r--r-- | sys/netinet6/icmp6.c | 47 |
4 files changed, 57 insertions, 49 deletions
diff --git a/sys/netinet/icmp6.h b/sys/netinet/icmp6.h index a29a55cd0d3..cae0c8dcfa3 100644 --- a/sys/netinet/icmp6.h +++ b/sys/netinet/icmp6.h @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.h,v 1.9 2000/08/19 09:17:36 itojun Exp $ */ +/* $OpenBSD: icmp6.h,v 1.10 2000/10/10 14:24:32 itojun Exp $ */ /* $KAME: icmp6.h,v 1.22 2000/08/03 15:25:16 jinmei Exp $ */ /* @@ -544,7 +544,9 @@ struct icmp6stat { #define ICMPV6CTL_STATS 1 #define ICMPV6CTL_REDIRACCEPT 2 /* accept/process redirects */ #define ICMPV6CTL_REDIRTIMEOUT 3 /* redirect cache time */ +#if 0 /*obsoleted*/ #define ICMPV6CTL_ERRRATELIMIT 5 /* ICMPv6 error rate limitation */ +#endif #define ICMPV6CTL_ND6_PRUNE 6 #define ICMPV6CTL_ND6_DELAY 8 #define ICMPV6CTL_ND6_UMAXTRIES 9 @@ -562,7 +564,7 @@ struct icmp6stat { { "rediraccept", CTLTYPE_INT }, \ { "redirtimeout", CTLTYPE_INT }, \ { 0, 0 }, \ - { "errratelimit", CTLTYPE_INT }, \ + { 0, 0 }, \ { "nd6_prune", CTLTYPE_INT }, \ { 0, 0 }, \ { "nd6_delay", CTLTYPE_INT }, \ diff --git a/sys/netinet/icmp_var.h b/sys/netinet/icmp_var.h index b955a464d28..eb212370741 100644 --- a/sys/netinet/icmp_var.h +++ b/sys/netinet/icmp_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp_var.h,v 1.4 1998/01/06 01:38:35 deraadt Exp $ */ +/* $OpenBSD: icmp_var.h,v 1.5 2000/10/10 14:24:33 itojun Exp $ */ /* $NetBSD: icmp_var.h,v 1.8 1995/03/26 20:32:19 jtc Exp $ */ /* @@ -61,12 +61,14 @@ struct icmpstat { */ #define ICMPCTL_MASKREPL 1 /* allow replies to netmask requests */ #define ICMPCTL_BMCASTECHO 2 /* reply to icmps to broadcast/mcast */ -#define ICMPCTL_MAXID 3 +#define ICMPCTL_ERRPPSLIMIT 3 /* ICMP error pps limitation */ +#define ICMPCTL_MAXID 4 #define ICMPCTL_NAMES { \ { 0, 0 }, \ { "maskrepl", CTLTYPE_INT }, \ { "bmcastecho", CTLTYPE_INT }, \ + { "errppslimit", CTLTYPE_INT }, \ } #ifdef _KERNEL diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index a352aec2e7d..93dc9a315e8 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_icmp.c,v 1.27 2000/10/09 14:39:46 provos Exp $ */ +/* $OpenBSD: ip_icmp.c,v 1.28 2000/10/10 14:24:33 itojun Exp $ */ /* $NetBSD: ip_icmp.c,v 1.19 1996/02/13 23:42:22 christos Exp $ */ /* @@ -86,9 +86,13 @@ int icmpbmcastecho = 0; #ifdef ICMPPRINTFS int icmpprintfs = 0; #endif +int icmperrppslim; +int icmperrpps_count = 0; +struct timeval icmperrppslim_last; void icmp_mtudisc __P((struct icmp *)); void icmp_mtudisc_timeout __P((struct rtentry *, struct rttimer *)); +int icmp_ratelimit __P((const struct in_addr *, const int, const int)); extern struct protosw inetsw[]; @@ -133,8 +137,17 @@ icmp_error(n, type, code, dest, destifp) /* Don't send error in response to a multicast or broadcast packet */ if (n->m_flags & (M_BCAST|M_MCAST)) goto freeit; + + /* + * First, do a rate limitation check. + */ + if (icmp_ratelimit(&oip->ip_src, type, code)) { + /* XXX stat */ + goto freeit; + } + /* - * First, formulate icmp message + * Now, formulate icmp message */ m = m_gethdr(M_DONTWAIT, MT_HEADER); if (m == NULL) @@ -728,6 +741,10 @@ icmp_sysctl(name, namelen, oldp, oldlenp, newp, newlen) return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl)); case ICMPCTL_BMCASTECHO: return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpbmcastecho)); + case ICMPCTL_ERRPPSLIMIT: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &icmperrppslim)); + break; default: return (ENOPROTOOPT); } @@ -853,3 +870,29 @@ icmp_mtudisc_timeout(rt, r) } } } + +/* + * Perform rate limit check. + * Returns 0 if it is okay to send the icmp packet. + * Returns 1 if the router SHOULD NOT send this icmp packet due to rate + * limitation. + * + * XXX per-destination/type check necessary? + */ +int +icmp_ratelimit(dst, type, code) + const struct in_addr *dst; + const int type; /* not used at this moment */ + const int code; /* not used at this moment */ +{ + + /* PPS limit */ + if (!ppsratecheck(&icmperrppslim_last, &icmperrpps_count, + icmperrppslim)) { + /* The packet is subject to rate limit */ + return 1; + } + + /*okay to send*/ + return 0; +} diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c index d0d4dd3982c..25e2086adb2 100644 --- a/sys/netinet6/icmp6.c +++ b/sys/netinet6/icmp6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: icmp6.c,v 1.22 2000/09/16 08:58:18 itojun Exp $ */ +/* $OpenBSD: icmp6.c,v 1.23 2000/10/10 14:24:34 itojun Exp $ */ /* $KAME: icmp6.c,v 1.144 2000/09/15 08:10:45 jinmei Exp $ */ /* @@ -108,10 +108,9 @@ extern u_char ip6_protox[]; struct icmp6stat icmp6stat; extern struct in6pcb rawin6pcb; -extern struct timeval icmp6errratelim; -static struct timeval icmp6errratelim_last; extern int icmp6errppslim; static int icmp6errpps_count = 0; +static struct timeval icmp6errppslim_last; extern int icmp6_nodeinfo; static struct rttimer_queue *icmp6_mtudisc_timeout_q = NULL; extern int pmtu_expire; @@ -1846,9 +1845,6 @@ icmp6_fasttimo() { mld6_fasttimeo(); - - /* reset ICMPv6 pps limit */ - icmp6errpps_count = 0; } static const char * @@ -2365,14 +2361,6 @@ fail: * Returns 1 if the router SHOULD NOT send this icmp6 packet due to rate * limitation. * - * There are two limitations defined: - * - pps limit: ICMPv6 error packet cannot exceed defined packet-per-second. - * we measure it every 0.2 second, since fasttimo works every 0.2 second. - * - rate limit: ICMPv6 error packet cannot appear more than once per - * defined interval. - * In any case, if we perform rate limitation, we'll see jitter in the ICMPv6 - * error packets. - * * XXX per-destination/type check necessary? */ static int @@ -2386,13 +2374,8 @@ icmp6_ratelimit(dst, type, code) ret = 0; /*okay to send*/ /* PPS limit */ - icmp6errpps_count++; - if (icmp6errppslim && icmp6errpps_count > icmp6errppslim / 5) { - /* The packet is subject to pps limit */ - ret++; - } - - if (!ratecheck(&icmp6errratelim_last, &icmp6errratelim)) { + if (!ppsratecheck(&icmp6errppslim_last, &icmp6errpps_count, + icmp6errppslim)) { /* The packet is subject to rate limit */ ret++; } @@ -2483,28 +2466,6 @@ icmp6_sysctl(name, namelen, oldp, oldlenp, newp, newlen) case ICMPV6CTL_STATS: return sysctl_rdstruct(oldp, oldlenp, newp, &icmp6stat, sizeof(icmp6stat)); - case ICMPV6CTL_ERRRATELIMIT: - { - int rate_usec, error, s; - - /* - * The sysctl specifies the rate in usec-between-icmp, - * so we must convert from/to a timeval. - */ - rate_usec = (icmp6errratelim.tv_sec * 1000000) + - icmp6errratelim.tv_usec; - error = sysctl_int(oldp, oldlenp, newp, newlen, &rate_usec); - if (error) - return (error); - if (rate_usec < 0) - return (EINVAL); - s = splsoftnet(); - icmp6errratelim.tv_sec = rate_usec / 1000000; - icmp6errratelim.tv_usec = rate_usec % 1000000; - splx(s); - - return (0); - } case ICMPV6CTL_ND6_PRUNE: return sysctl_int(oldp, oldlenp, newp, newlen, &nd6_prune); case ICMPV6CTL_ND6_DELAY: |