summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-10-10 14:24:35 +0000
committerJun-ichiro itojun Hagino <itojun@cvs.openbsd.org>2000-10-10 14:24:35 +0000
commit6bf4b0ac08bc472a2f11aa0c7fa5d55f03bc8604 (patch)
tree652d7914c92649d7c2dab7e8a8a621ec5d237eb6
parent9cf3e77903bf3e98ce3533d22f5740b39d1805e1 (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.h6
-rw-r--r--sys/netinet/icmp_var.h6
-rw-r--r--sys/netinet/ip_icmp.c47
-rw-r--r--sys/netinet6/icmp6.c47
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: