Source-Changes-HG archive

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

[src/trunk]: src RA flood mitigation via a limit on accepted routes:



details:   https://anonhg.NetBSD.org/src/rev/0db8d5b04bf8
branches:  trunk
changeset: 765373:0db8d5b04bf8
user:      spz <spz%NetBSD.org@localhost>
date:      Tue May 24 18:07:11 2011 +0000

description:
RA flood mitigation via a limit on accepted routes:
- introduce a limit for the routes accepted via IPv6 Router Advertisement:
  a common 2 interface client will have 6, the default limit is 100 and
  can be adjusted via sysctl
- report the current number of routes installed via RA via sysctl
- count discarded route additions. Note that one RA message is two routes.
  This is at present only across all interfaces even though per-interface
  would be more useful, since the per-interface structure complies to RFC2466
- bump kernel version due to the previous change
- adjust netstat to use the new value (with netstat -p icmp6)

diffstat:

 sys/netinet/icmp6.h      |   5 +++--
 sys/netinet6/in6.h       |  10 ++++++++--
 sys/netinet6/in6_proto.c |  11 +++++++++--
 sys/netinet6/ip6_input.c |  18 ++++++++++++++++--
 sys/netinet6/ip6_var.h   |   3 ++-
 sys/netinet6/nd6.h       |   3 ++-
 sys/netinet6/nd6_rtr.c   |  33 ++++++++++++++++++++++++++-------
 sys/sys/param.h          |   4 ++--
 usr.bin/netstat/inet6.c  |   5 +++--
 9 files changed, 71 insertions(+), 21 deletions(-)

diffs (truncated from 314 to 300 lines):

diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet/icmp6.h
--- a/sys/netinet/icmp6.h       Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet/icmp6.h       Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: icmp6.h,v 1.41 2011/05/08 18:42:53 spz Exp $   */
+/*     $NetBSD: icmp6.h,v 1.42 2011/05/24 18:07:11 spz Exp $   */
 /*     $KAME: icmp6.h,v 1.84 2003/04/23 10:26:51 itojun Exp $  */
 
 
@@ -569,8 +569,9 @@
 #define        ICMP6_STAT_BADRS        538     /* bad router solicitiation */
 #define        ICMP6_STAT_BADRA        539     /* bad router advertisement */
 #define        ICMP6_STAT_BADREDIRECT  540     /* bad redirect message */
+#define ICMP6_STAT_DROPPED_RAROUTE 541 /* discarded routes from router advertisement */
 
-#define        ICMP6_NSTATS            541
+#define        ICMP6_NSTATS            542
 
 #define        ICMP6_ERRSTAT_DST_UNREACH_NOROUTE       0
 #define        ICMP6_ERRSTAT_DST_UNREACH_ADMIN         1
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet6/in6.h
--- a/sys/netinet6/in6.h        Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet6/in6.h        Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.h,v 1.68 2009/09/11 22:06:29 dyoung Exp $  */
+/*     $NetBSD: in6.h,v 1.69 2011/05/24 18:07:11 spz Exp $     */
 /*     $KAME: in6.h,v 1.83 2001/03/29 02:55:07 jinmei Exp $    */
 
 /*
@@ -575,9 +575,13 @@
 /* 40: reserved */
 #define IPV6CTL_MAXFRAGS       41      /* max fragments */
 #define IPV6CTL_IFQ            42      /* ip6intrq node */
+#define IPV6CTL_RTADV_MAXROUTES 43     /* maximum number of routes */
+                                       /* via router advertisement */
+#define IPV6CTL_RTADV_NUMROUTES 44     /* current number of routes */
+                                       /* via router advertisement */
 /* New entries should be added here from current IPV6CTL_MAXID value. */
 /* to define items, should talk with KAME guys first, for *BSD compatibility */
-#define IPV6CTL_MAXID          43
+#define IPV6CTL_MAXID          45
 
 #define IPV6CTL_NAMES { \
        { 0, 0 }, \
@@ -623,6 +627,8 @@
        { 0, 0 }, \
        { "maxfrags", CTLTYPE_INT }, \
        { "ifq", CTLTYPE_NODE }, \
+       { "rtadv_maxroutes", CTLTYPE_INT }, \
+       { "rtadv_numroutes", CTLTYPE_INT }, \
 }
 
 #endif /* _NETBSD_SOURCE */
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet6/in6_proto.c
--- a/sys/netinet6/in6_proto.c  Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet6/in6_proto.c  Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_proto.c,v 1.91 2011/05/03 17:44:30 dyoung Exp $    */
+/*     $NetBSD: in6_proto.c,v 1.92 2011/05/24 18:07:11 spz Exp $       */
 /*     $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $      */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.91 2011/05/03 17:44:30 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.92 2011/05/24 18:07:11 spz Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -482,6 +482,13 @@
 
 int    ip6_keepfaith = 0;
 time_t ip6_log_time = (time_t)0L;
+int    ip6_rtadv_maxroutes = 100; /* (arbitrary) initial maximum number of
+                                    * routes via rtadv expected to be
+                                    * significantly larger than common use.
+                                    * if you need to count: 3 extra initial
+                                    * routes, plus 1 per interface after the
+                                    * first one, then one per non-linklocal
+                                    * prefix */
 
 /* icmp6 */
 /*
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c  Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet6/ip6_input.c  Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_input.c,v 1.130 2011/05/03 18:28:45 dyoung Exp $   */
+/*     $NetBSD: ip6_input.c,v 1.131 2011/05/24 18:07:11 spz Exp $      */
 /*     $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.130 2011/05/03 18:28:45 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.131 2011/05/24 18:07:11 spz Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -1795,6 +1795,20 @@
                       IPV6CTL_ACCEPT_RTADV, CTL_EOL);
        sysctl_createv(clog, 0, NULL, NULL,
                       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "rtadv_maxroutes",
+                      SYSCTL_DESCR("Maximum number of routes accepted via router advertisements"),
+                      NULL, 0, &ip6_rtadv_maxroutes, 0,
+                      CTL_NET, PF_INET6, IPPROTO_IPV6,
+                      IPV6CTL_RTADV_MAXROUTES, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, NULL,
+                      CTLFLAG_PERMANENT,
+                      CTLTYPE_INT, "rtadv_numroutes",
+                      SYSCTL_DESCR("Current number of routes accepted via router advertisements"),
+                      NULL, 0, &nd6_numroutes, 0,
+                      CTL_NET, PF_INET6, IPPROTO_IPV6,
+                      IPV6CTL_RTADV_NUMROUTES, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, NULL,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
                       CTLTYPE_INT, "keepfaith",
                       SYSCTL_DESCR("Activate faith interface"),
                       NULL, 0, &ip6_keepfaith, 0,
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet6/ip6_var.h
--- a/sys/netinet6/ip6_var.h    Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet6/ip6_var.h    Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_var.h,v 1.54 2011/05/03 17:44:30 dyoung Exp $      */
+/*     $NetBSD: ip6_var.h,v 1.55 2011/05/24 18:07:11 spz Exp $ */
 /*     $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $        */
 
 /*
@@ -281,6 +281,7 @@
 extern int     ip6_sourcecheck;        /* Verify source interface */
 extern int     ip6_sourcecheck_interval; /* Interval between log messages */
 extern int     ip6_accept_rtadv;       /* Acts as a host not a router */
+extern int     ip6_rtadv_maxroutes;    /* maximum number of routes via rtadv */
 extern int     ip6_keepfaith;          /* Firewall Aided Internet Translator */
 extern int     ip6_log_interval;
 extern time_t  ip6_log_time;
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet6/nd6.h
--- a/sys/netinet6/nd6.h        Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet6/nd6.h        Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.h,v 1.53 2009/11/06 20:41:22 dyoung Exp $  */
+/*     $NetBSD: nd6.h,v 1.54 2011/05/24 18:07:11 spz Exp $     */
 /*     $KAME: nd6.h,v 1.95 2002/06/08 11:31:06 itojun Exp $    */
 
 /*
@@ -372,6 +372,7 @@
 extern u_int32_t ip6_temp_preferred_lifetime; /* seconds */
 extern u_int32_t ip6_temp_valid_lifetime; /* seconds */
 extern int ip6_temp_regen_advance; /* seconds */
+extern int nd6_numroutes;
 
 union nd_opts {
        struct nd_opt_hdr *nd_opt_array[8];
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/netinet6/nd6_rtr.c
--- a/sys/netinet6/nd6_rtr.c    Tue May 24 17:45:49 2011 +0000
+++ b/sys/netinet6/nd6_rtr.c    Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6_rtr.c,v 1.80 2009/11/06 20:41:22 dyoung Exp $      */
+/*     $NetBSD: nd6_rtr.c,v 1.81 2011/05/24 18:07:11 spz Exp $ */
 /*     $KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $        */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.80 2009/11/06 20:41:22 dyoung Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.81 2011/05/24 18:07:11 spz Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -95,6 +95,8 @@
 u_int32_t ip6_temp_valid_lifetime = DEF_TEMP_VALID_LIFETIME;
 int ip6_temp_regen_advance = TEMPADDR_REGEN_ADVANCE;
 
+int nd6_numroutes = 0;
+
 /* RTPREF_MEDIUM has to be 0! */
 #define RTPREF_HIGH    1
 #define RTPREF_MEDIUM  0
@@ -104,7 +106,7 @@
 
 /*
  * Receive Router Solicitation Message - just for routers.
- * Router solicitation/advertisement is mostly managed by userland program
+ * Router solicitation/advertisement is mostly managed by a userland program
  * (rtadvd) so here we have no function like nd6_ra_output().
  *
  * Based on RFC 2461
@@ -206,8 +208,8 @@
        struct nd_defrouter *dr;
 
        /*
-        * We only accept RAs only when
-        * the system-wide variable allows the acceptance, and
+        * We only accept RAs when
+        * the system-wide variable allows the acceptance, and the
         * per-interface variable allows RAs on the receiving interface.
         */
        if (!nd6_accepts_rtadv(ndi))
@@ -458,6 +460,7 @@
        if (newrt) {
                nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
                newrt->rt_refcnt--;
+               nd6_numroutes++;
        }
        if (error == 0)
                new->installed = 1;
@@ -561,6 +564,7 @@
                         */
                        oldrt->rt_refcnt++;
                        rtfree(oldrt);
+                       nd6_numroutes--;
                }
        }
 
@@ -778,6 +782,12 @@
                return (NULL);
        }
 
+       if (ip6_rtadv_maxroutes <= nd6_numroutes) {
+               ICMP6_STATINC(ICMP6_STAT_DROPPED_RAROUTE);
+               splx(s);
+               return (NULL);
+       }
+
        n = (struct nd_defrouter *)malloc(sizeof(*n), M_IP6NDP, M_NOWAIT);
        if (n == NULL) {
                splx(s);
@@ -1045,6 +1055,11 @@
                if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0)
                        goto end;
 
+               if (ip6_rtadv_maxroutes <= nd6_numroutes) {
+                       ICMP6_STATINC(ICMP6_STAT_DROPPED_RAROUTE);
+                       goto end;
+               }
+
                error = nd6_prelist_add(new, dr, &newpr);
                if (error != 0 || newpr == NULL) {
                        nd6log((LOG_NOTICE, "prelist_update: "
@@ -1603,8 +1618,10 @@
        error = rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix,
            ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt);
        if (error == 0) {
-               if (rt != NULL) /* this should be non NULL, though */
+               if (rt != NULL) { /* this should be non NULL, though */
                        nd6_rtmsg(RTM_ADD, rt);
+                       nd6_numroutes++;
+               }
                pr->ndpr_stateflags |= NDPRF_ONLINK;
        } else {
                nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a"
@@ -1647,8 +1664,10 @@
                pr->ndpr_stateflags &= ~NDPRF_ONLINK;
 
                /* report the route deletion to the routing socket. */
-               if (rt != NULL)
+               if (rt != NULL) {
                        nd6_rtmsg(RTM_DELETE, rt);
+                       nd6_numroutes--;
+               }
 
                /*
                 * There might be the same prefix on another interface,
diff -r 252587c7fa30 -r 0db8d5b04bf8 sys/sys/param.h
--- a/sys/sys/param.h   Tue May 24 17:45:49 2011 +0000
+++ b/sys/sys/param.h   Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: param.h,v 1.388 2011/04/26 11:32:39 hannken Exp $      */
+/*     $NetBSD: param.h,v 1.389 2011/05/24 18:07:11 spz Exp $  */
 
 /*-
  * Copyright (c) 1982, 1986, 1989, 1993
@@ -63,7 +63,7 @@
  *     2.99.9          (299000900)
  */
 
-#define        __NetBSD_Version__      599005100       /* NetBSD 5.99.51 */
+#define        __NetBSD_Version__      599005200       /* NetBSD 5.99.52 */
 
 #define __NetBSD_Prereq__(M,m,p) (((((M) * 100000000) + \
     (m) * 1000000) + (p) * 100) <= __NetBSD_Version__)
diff -r 252587c7fa30 -r 0db8d5b04bf8 usr.bin/netstat/inet6.c
--- a/usr.bin/netstat/inet6.c   Tue May 24 17:45:49 2011 +0000
+++ b/usr.bin/netstat/inet6.c   Tue May 24 18:07:11 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: inet6.c,v 1.58 2011/05/11 22:21:59 dyoung Exp $        */
+/*     $NetBSD: inet6.c,v 1.59 2011/05/24 18:07:11 spz Exp $   */
 /*     BSDI inet.c,v 2.3 1995/10/24 02:19:29 prb Exp   */
 
 /*
@@ -64,7 +64,7 @@
 #if 0
 static char sccsid[] = "@(#)inet.c     8.4 (Berkeley) 4/20/94";



Home | Main Index | Thread Index | Old Index