Module Name: src
Committed By: spz
Date: Tue May 24 18:07:12 UTC 2011
Modified Files:
src/sys/netinet: icmp6.h
src/sys/netinet6: in6.h in6_proto.c ip6_input.c ip6_var.h nd6.h
nd6_rtr.c
src/sys/sys: param.h
src/usr.bin/netstat: inet6.c
Log Message:
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)
To generate a diff of this commit:
cvs rdiff -u -r1.41 -r1.42 src/sys/netinet/icmp6.h
cvs rdiff -u -r1.68 -r1.69 src/sys/netinet6/in6.h
cvs rdiff -u -r1.91 -r1.92 src/sys/netinet6/in6_proto.c
cvs rdiff -u -r1.130 -r1.131 src/sys/netinet6/ip6_input.c
cvs rdiff -u -r1.54 -r1.55 src/sys/netinet6/ip6_var.h
cvs rdiff -u -r1.53 -r1.54 src/sys/netinet6/nd6.h
cvs rdiff -u -r1.80 -r1.81 src/sys/netinet6/nd6_rtr.c
cvs rdiff -u -r1.388 -r1.389 src/sys/sys/param.h
cvs rdiff -u -r1.58 -r1.59 src/usr.bin/netstat/inet6.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/netinet/icmp6.h
diff -u src/sys/netinet/icmp6.h:1.41 src/sys/netinet/icmp6.h:1.42
--- src/sys/netinet/icmp6.h:1.41 Sun May 8 18:42:53 2011
+++ src/sys/netinet/icmp6.h Tue May 24 18:07:11 2011
@@ -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
Index: src/sys/netinet6/in6.h
diff -u src/sys/netinet6/in6.h:1.68 src/sys/netinet6/in6.h:1.69
--- src/sys/netinet6/in6.h:1.68 Fri Sep 11 22:06:29 2009
+++ src/sys/netinet6/in6.h Tue May 24 18:07:11 2011
@@ -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 */
Index: src/sys/netinet6/in6_proto.c
diff -u src/sys/netinet6/in6_proto.c:1.91 src/sys/netinet6/in6_proto.c:1.92
--- src/sys/netinet6/in6_proto.c:1.91 Tue May 3 17:44:30 2011
+++ src/sys/netinet6/in6_proto.c Tue May 24 18:07:11 2011
@@ -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 */
/*
Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.130 src/sys/netinet6/ip6_input.c:1.131
--- src/sys/netinet6/ip6_input.c:1.130 Tue May 3 18:28:45 2011
+++ src/sys/netinet6/ip6_input.c Tue May 24 18:07:11 2011
@@ -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,
Index: src/sys/netinet6/ip6_var.h
diff -u src/sys/netinet6/ip6_var.h:1.54 src/sys/netinet6/ip6_var.h:1.55
--- src/sys/netinet6/ip6_var.h:1.54 Tue May 3 17:44:30 2011
+++ src/sys/netinet6/ip6_var.h Tue May 24 18:07:11 2011
@@ -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;
Index: src/sys/netinet6/nd6.h
diff -u src/sys/netinet6/nd6.h:1.53 src/sys/netinet6/nd6.h:1.54
--- src/sys/netinet6/nd6.h:1.53 Fri Nov 6 20:41:22 2009
+++ src/sys/netinet6/nd6.h Tue May 24 18:07:11 2011
@@ -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];
Index: src/sys/netinet6/nd6_rtr.c
diff -u src/sys/netinet6/nd6_rtr.c:1.80 src/sys/netinet6/nd6_rtr.c:1.81
--- src/sys/netinet6/nd6_rtr.c:1.80 Fri Nov 6 20:41:22 2009
+++ src/sys/netinet6/nd6_rtr.c Tue May 24 18:07:11 2011
@@ -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,
Index: src/sys/sys/param.h
diff -u src/sys/sys/param.h:1.388 src/sys/sys/param.h:1.389
--- src/sys/sys/param.h:1.388 Tue Apr 26 11:32:39 2011
+++ src/sys/sys/param.h Tue May 24 18:07:11 2011
@@ -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__)
Index: src/usr.bin/netstat/inet6.c
diff -u src/usr.bin/netstat/inet6.c:1.58 src/usr.bin/netstat/inet6.c:1.59
--- src/usr.bin/netstat/inet6.c:1.58 Wed May 11 22:21:59 2011
+++ src/usr.bin/netstat/inet6.c Tue May 24 18:07:11 2011
@@ -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";
#else
-__RCSID("$NetBSD: inet6.c,v 1.58 2011/05/11 22:21:59 dyoung Exp $");
+__RCSID("$NetBSD: inet6.c,v 1.59 2011/05/24 18:07:11 spz Exp $");
#endif
#endif /* not lint */
@@ -1196,6 +1196,7 @@
p(ICMP6_STAT_BADNA, "\t%llu bad neighbor advertisement message%s\n");
p(ICMP6_STAT_BADRS, "\t%llu bad router solicitation message%s\n");
p(ICMP6_STAT_BADRA, "\t%llu bad router advertisement message%s\n");
+ p(ICMP6_STAT_DROPPED_RAROUTE, "\t%llu router advertisement route%s dropped\n");
p(ICMP6_STAT_BADREDIRECT, "\t%llu bad redirect message%s\n");
p(ICMP6_STAT_PMTUCHG, "\t%llu path MTU change%s\n");
#undef p