summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortuexen <tuexen@FreeBSD.org>2012-01-08 09:56:24 +0000
committertuexen <tuexen@FreeBSD.org>2012-01-08 09:56:24 +0000
commitebc0602463d35d7c9e3a52f25d6f9e806d5120dc (patch)
tree1e92913ac4b44826cabc601aa1a6d11dadb1d279
parent1c75fb6a4d6b5570918d1d2bf6b8b7c8eed7a2d8 (diff)
downloadFreeBSD-src-ebc0602463d35d7c9e3a52f25d6f9e806d5120dc.zip
FreeBSD-src-ebc0602463d35d7c9e3a52f25d6f9e806d5120dc.tar.gz
Add an SCTP sysctl "blackhole", similar to the one for TCP.
If set to 1, no ABORT is sent back in response to an incoming INIT. If set to 2, no ABORT is sent back in response to an out of the blue packet. If set to 0 (the default), ABORTs are sent. Discussed with rrs@. MFC after: 1 month.
-rw-r--r--sys/netinet/sctp_input.c14
-rw-r--r--sys/netinet/sctp_sysctl.c6
-rw-r--r--sys/netinet/sctp_sysctl.h6
-rw-r--r--sys/netinet/sctputil.c11
-rw-r--r--sys/netinet6/sctp6_usrreq.c9
5 files changed, 39 insertions, 7 deletions
diff --git a/sys/netinet/sctp_input.c b/sys/netinet/sctp_input.c
index 6fdcc91..b3f6371 100644
--- a/sys/netinet/sctp_input.c
+++ b/sys/netinet/sctp_input.c
@@ -170,8 +170,9 @@ sctp_handle_init(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
* accepts(). The App just looses and should NOT be in this
* state :-)
*/
- sctp_abort_association(inp, stcb, m, iphlen, sh, NULL,
- vrf_id, port);
+ if (SCTP_BASE_SYSCTL(sctp_blackhole) == 0) {
+ sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ }
goto outnow;
}
if ((stcb != NULL) &&
@@ -5927,8 +5928,13 @@ sctp_skip_csum_4:
if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
goto bad;
}
- if (ch->chunk_type != SCTP_ABORT_ASSOCIATION)
- sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
+ if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
+ ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
+ (ch->chunk_type != SCTP_INIT))) {
+ sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ }
+ }
goto bad;
} else if (stcb == NULL) {
refcount_up = 1;
diff --git a/sys/netinet/sctp_sysctl.c b/sys/netinet/sctp_sysctl.c
index f0d1250..2186832 100644
--- a/sys/netinet/sctp_sysctl.c
+++ b/sys/netinet/sctp_sysctl.c
@@ -117,6 +117,7 @@ sctp_init_sysctls()
SCTP_BASE_SYSCTL(sctp_rttvar_eqret) = SCTPCTL_RTTVAR_EQRET_DEFAULT;
SCTP_BASE_SYSCTL(sctp_steady_step) = SCTPCTL_RTTVAR_STEADYS_DEFAULT;
SCTP_BASE_SYSCTL(sctp_use_dccc_ecn) = SCTPCTL_RTTVAR_DCCCECN_DEFAULT;
+ SCTP_BASE_SYSCTL(sctp_blackhole) = SCTPCTL_BLACKHOLE_DEFAULT;
#if defined(SCTP_LOCAL_TRACE_BUF)
memset(&SCTP_BASE_SYSCTL(sctp_log), 0, sizeof(struct sctp_log));
@@ -665,6 +666,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
RANGECHK(SCTP_BASE_SYSCTL(sctp_mobility_fasthandoff), SCTPCTL_MOBILITY_FASTHANDOFF_MIN, SCTPCTL_MOBILITY_FASTHANDOFF_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_enable_sack_immediately), SCTPCTL_SACK_IMMEDIATELY_ENABLE_MIN, SCTPCTL_SACK_IMMEDIATELY_ENABLE_MAX);
RANGECHK(SCTP_BASE_SYSCTL(sctp_inits_include_nat_friendly), SCTPCTL_NAT_FRIENDLY_INITS_MIN, SCTPCTL_NAT_FRIENDLY_INITS_MAX);
+ RANGECHK(SCTP_BASE_SYSCTL(sctp_blackhole), SCTPCTL_BLACKHOLE_MIN, SCTPCTL_BLACKHOLE_MAX);
#ifdef SCTP_DEBUG
RANGECHK(SCTP_BASE_SYSCTL(sctp_debug_on), SCTPCTL_DEBUG_MIN, SCTPCTL_DEBUG_MAX);
@@ -1123,6 +1125,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, use_dcccecn, CTLTYPE_UINT | CTLFLAG_R
&SCTP_BASE_SYSCTL(sctp_use_dccc_ecn), 0, sysctl_sctp_check, "IU",
SCTPCTL_RTTVAR_DCCCECN_DESC);
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, blackhole, CTLTYPE_UINT | CTLFLAG_RW,
+ &SCTP_BASE_SYSCTL(sctp_blackhole), 0, sysctl_sctp_check, "IU",
+ SCTPCTL_BLACKHOLE_DESC);
+
#ifdef SCTP_DEBUG
SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, debug, CTLTYPE_UINT | CTLFLAG_RW,
&SCTP_BASE_SYSCTL(sctp_debug_on), 0, sysctl_sctp_check, "IU",
diff --git a/sys/netinet/sctp_sysctl.h b/sys/netinet/sctp_sysctl.h
index 64d941d..cbb2826 100644
--- a/sys/netinet/sctp_sysctl.h
+++ b/sys/netinet/sctp_sysctl.h
@@ -114,6 +114,7 @@ struct sctp_sysctl {
uint32_t sctp_vtag_time_wait;
uint32_t sctp_buffer_splitting;
uint32_t sctp_initial_cwnd;
+ uint32_t sctp_blackhole;
#if defined(SCTP_DEBUG)
uint32_t sctp_debug_on;
#endif
@@ -519,6 +520,11 @@ struct sctp_sysctl {
#define SCTPCTL_RTTVAR_DCCCECN_MAX 1
#define SCTPCTL_RTTVAR_DCCCECN_DEFAULT 1 /* 0 means disable feature */
+#define SCTPCTL_BLACKHOLE_DESC "Enable SCTP blackholing"
+#define SCTPCTL_BLACKHOLE_MIN 0
+#define SCTPCTL_BLACKHOLE_MAX 2
+#define SCTPCTL_BLACKHOLE_DEFAULT SCTPCTL_BLACKHOLE_MIN
+
#if defined(SCTP_DEBUG)
/* debug: Configure debug output */
#define SCTPCTL_DEBUG_DESC "Configure debug output"
diff --git a/sys/netinet/sctputil.c b/sys/netinet/sctputil.c
index bfb7620..1ff7126da 100644
--- a/sys/netinet/sctputil.c
+++ b/sys/netinet/sctputil.c
@@ -3801,6 +3801,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
{
struct sctp_chunkhdr *ch, chunk_buf;
unsigned int chk_length;
+ int contains_init_chunk;
SCTP_STAT_INCR_COUNTER32(sctps_outoftheblue);
/* Generate a TO address for future reference */
@@ -3810,6 +3811,7 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
SCTP_CALLED_DIRECTLY_NOCMPSET);
}
}
+ contains_init_chunk = 0;
ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
sizeof(*ch), (uint8_t *) & chunk_buf);
while (ch != NULL) {
@@ -3819,6 +3821,9 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
break;
}
switch (ch->chunk_type) {
+ case SCTP_INIT:
+ contains_init_chunk = 1;
+ break;
case SCTP_COOKIE_ECHO:
/* We hit here only if the assoc is being freed */
return;
@@ -3844,7 +3849,11 @@ sctp_handle_ootb(struct mbuf *m, int iphlen, int offset, struct sctphdr *sh,
ch = (struct sctp_chunkhdr *)sctp_m_getptr(m, offset,
sizeof(*ch), (uint8_t *) & chunk_buf);
}
- sctp_send_abort(m, iphlen, sh, 0, op_err, vrf_id, port);
+ if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
+ ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
+ (contains_init_chunk == 0))) {
+ sctp_send_abort(m, iphlen, sh, 0, op_err, vrf_id, port);
+ }
}
/*
diff --git a/sys/netinet6/sctp6_usrreq.c b/sys/netinet6/sctp6_usrreq.c
index 23d3dea..c100713 100644
--- a/sys/netinet6/sctp6_usrreq.c
+++ b/sys/netinet6/sctp6_usrreq.c
@@ -236,8 +236,13 @@ sctp_skip_csum:
if (ch->chunk_type == SCTP_SHUTDOWN_COMPLETE) {
goto bad;
}
- if (ch->chunk_type != SCTP_ABORT_ASSOCIATION)
- sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ if (ch->chunk_type != SCTP_ABORT_ASSOCIATION) {
+ if ((SCTP_BASE_SYSCTL(sctp_blackhole) == 0) ||
+ ((SCTP_BASE_SYSCTL(sctp_blackhole) == 1) &&
+ (ch->chunk_type != SCTP_INIT))) {
+ sctp_send_abort(m, iphlen, sh, 0, NULL, vrf_id, port);
+ }
+ }
goto bad;
} else if (stcb == NULL) {
refcount_up = 1;
OpenPOWER on IntegriCloud