Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/netinet Add ICMP error rate limiting, based on the same ...



details:   https://anonhg.NetBSD.org/src/rev/46e97ff8694b
branches:  trunk
changeset: 482131:46e97ff8694b
user:      thorpej <thorpej%NetBSD.org@localhost>
date:      Tue Feb 15 04:03:49 2000 +0000

description:
Add ICMP error rate limiting, based on the same for ICMP6.

Note, we're reusing the previously unused slot for "MTU discovery" (which
was moved to the "net.inet.ip" branch of the sysctl tree quite some time
ago).

diffstat:

 sys/netinet/icmp_var.h |   7 +++--
 sys/netinet/in_proto.c |   4 ++-
 sys/netinet/ip_icmp.c  |  61 +++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 65 insertions(+), 7 deletions(-)

diffs (144 lines):

diff -r c3bee5b047bd -r 46e97ff8694b sys/netinet/icmp_var.h
--- a/sys/netinet/icmp_var.h    Tue Feb 15 00:42:22 2000 +0000
+++ b/sys/netinet/icmp_var.h    Tue Feb 15 04:03:49 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: icmp_var.h,v 1.13 1999/11/19 10:41:42 bouyer Exp $     */
+/*     $NetBSD: icmp_var.h,v 1.14 2000/02/15 04:03:49 thorpej Exp $    */
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -61,12 +61,13 @@
  * Names for ICMP sysctl objects
  */
 #define        ICMPCTL_MASKREPL        1       /* allow replies to netmask requests */
-#define ICMPCTL_MTUDISC         2       /* allow path MTU discovery */
-#define ICMPCTL_MAXID           3
+#define ICMPCTL_ERRRATELIMIT   2       /* error rate limit */
+#define ICMPCTL_MAXID          3
 
 #define ICMPCTL_NAMES { \
        { 0, 0 }, \
        { "maskrepl", CTLTYPE_INT }, \
+       { "errratelimit", CTLTYPE_INT }, \
 }
 
 #ifdef _KERNEL
diff -r c3bee5b047bd -r 46e97ff8694b sys/netinet/in_proto.c
--- a/sys/netinet/in_proto.c    Tue Feb 15 00:42:22 2000 +0000
+++ b/sys/netinet/in_proto.c    Tue Feb 15 04:03:49 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in_proto.c,v 1.35 2000/02/10 14:44:28 itojun Exp $     */
+/*     $NetBSD: in_proto.c,v 1.36 2000/02/15 04:03:49 thorpej Exp $    */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -275,3 +275,5 @@
 int    tcp_syn_bucket_limit = 3*TCP_SYN_BUCKET_SIZE;
 struct syn_cache_head tcp_syn_cache[TCP_SYN_HASH_SIZE];
 int    tcp_syn_cache_interval = 1;     /* runs timer twice a second */
+
+struct timeval icmperrratelim = { 0, 1000 };   /* 1000usec = 1msec */
diff -r c3bee5b047bd -r 46e97ff8694b sys/netinet/ip_icmp.c
--- a/sys/netinet/ip_icmp.c     Tue Feb 15 00:42:22 2000 +0000
+++ b/sys/netinet/ip_icmp.c     Tue Feb 15 04:03:49 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip_icmp.c,v 1.39 2000/01/25 17:07:56 sommerfeld Exp $  */
+/*     $NetBSD: ip_icmp.c,v 1.40 2000/02/15 04:03:49 thorpej Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -155,9 +155,13 @@
 
 extern struct protosw inetsw[];
 
+extern struct timeval icmperrratelim;
+
 static void icmp_mtudisc __P((struct icmp *));
 static void icmp_mtudisc_timeout __P((struct rtentry *, struct rttimer *));
 
+static int icmp_ratelimit __P((const struct in_addr *, const int, const int));
+
 /*
  * Generate an error packet of type error
  * in response to bad packet ip.
@@ -197,8 +201,17 @@
        /* Don't send error in response to a multicast or broadcast packet */
        if (n->m_flags & (M_BCAST|M_MCAST))
                goto freeit;
+
        /*
-        * First, formulate icmp message
+        * First, do a rate limitation check.
+        */
+       if (icmp_ratelimit(&oip->ip_src, type, code)) {
+               /* XXX stat */
+               goto freeit;
+       }
+
+       /*
+        * Now, formulate icmp message
         */
        m = m_gethdr(M_DONTWAIT, MT_HEADER);
        if (m == NULL)
@@ -786,6 +799,26 @@
        switch (name[0]) {
        case ICMPCTL_MASKREPL:
                return (sysctl_int(oldp, oldlenp, newp, newlen, &icmpmaskrepl));
+       case ICMPCTL_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 = (icmperrratelim.tv_sec * 1000000) +
+                   icmperrratelim.tv_usec;
+               error = sysctl_int(oldp, oldlenp, newp, newlen, &rate_usec);
+               if (error)
+                       return (error);
+               s = splsoftnet();
+               icmperrratelim.tv_sec = rate_usec / 1000000;
+               icmperrratelim.tv_usec = rate_usec % 1000000;
+               splx(s);
+
+               return (0);
+           }
        default:
                return (ENOPROTOOPT);
        }
@@ -918,7 +951,6 @@
        }
 }
 
-
 static void
 icmp_mtudisc_timeout(rt, r)
        struct rtentry *rt;
@@ -936,3 +968,26 @@
                }
        }
 }
+
+/*
+ * 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?
+ */
+static int
+icmp_ratelimit(dst, type, code)
+       const struct in_addr *dst;      /* not used at this moment */
+       const int type;                 /* not used at this moment */
+       const int code;                 /* not used at this moment */
+{
+       static struct timeval icmperrratelim_last;
+
+       /*
+        * ratecheck() returns true if it is okay to send.  We return
+        * true if it is not okay to send.
+        */
+       return (ratecheck(&icmperrratelim_last, &icmperrratelim) == 0);
+}



Home | Main Index | Thread Index | Old Index