svn commit: r269527 - in head: lib/libc/net sys/netinet

Michael Tuexen tuexen at FreeBSD.org
Mon Aug 4 20:07:38 UTC 2014


Author: tuexen
Date: Mon Aug  4 20:07:35 2014
New Revision: 269527
URL: http://svnweb.freebsd.org/changeset/base/269527

Log:
  Add support for the SCTP_RECONFIG_SUPPORTED and the corresponding
  sysctl controlling the negotiation of the RE-CONFIG extension.
  
  MFC after: 3 days

Modified:
  head/lib/libc/net/sctp_sys_calls.c
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_input.c
  head/sys/netinet/sctp_output.c
  head/sys/netinet/sctp_pcb.c
  head/sys/netinet/sctp_pcb.h
  head/sys/netinet/sctp_peeloff.c
  head/sys/netinet/sctp_structs.h
  head/sys/netinet/sctp_sysctl.c
  head/sys/netinet/sctp_sysctl.h
  head/sys/netinet/sctp_usrreq.c
  head/sys/netinet/sctputil.c

Modified: head/lib/libc/net/sctp_sys_calls.c
==============================================================================
--- head/lib/libc/net/sctp_sys_calls.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/lib/libc/net/sctp_sys_calls.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -356,6 +356,9 @@ sctp_opt_info(int sd, sctp_assoc_t id, i
 	case SCTP_PR_SUPPORTED:
 		((struct sctp_assoc_value *)arg)->assoc_id = id;
 		break;
+	case SCTP_RECONFIG_SUPPORTED:
+		((struct sctp_assoc_value *)arg)->assoc_id = id;
+		break;
 	case SCTP_NRSACK_SUPPORTED:
 		((struct sctp_assoc_value *)arg)->assoc_id = id;
 		break;

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp.h	Mon Aug  4 20:07:35 2014	(r269527)
@@ -125,6 +125,7 @@ struct sctp_paramhdr {
 #define SCTP_PR_SUPPORTED               0x00000026
 #define SCTP_NRSACK_SUPPORTED           0x00000027
 #define SCTP_PKTDROP_SUPPORTED          0x00000028
+#define SCTP_RECONFIG_SUPPORTED         0x00000029
 
 /*
  * read-only options

Modified: head/sys/netinet/sctp_input.c
==============================================================================
--- head/sys/netinet/sctp_input.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_input.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -2787,6 +2787,7 @@ sctp_handle_cookie_echo(struct mbuf *m, 
 			inp->sctp_cmt_on_off = (*inp_p)->sctp_cmt_on_off;
 			inp->ecn_supported = (*inp_p)->ecn_supported;
 			inp->prsctp_supported = (*inp_p)->prsctp_supported;
+			inp->reconfig_supported = (*inp_p)->reconfig_supported;
 			inp->nrsack_supported = (*inp_p)->nrsack_supported;
 			inp->pktdrop_supported = (*inp_p)->pktdrop_supported;
 			inp->partial_delivery_point = (*inp_p)->partial_delivery_point;
@@ -5389,13 +5390,13 @@ process_control_chunks:
 				*offset = length;
 				return (NULL);
 			}
-			if (stcb->asoc.peer_supports_strreset == 0) {
+			if (stcb->asoc.reconfig_supported == 0) {
 				/*
 				 * hmm, peer should have announced this, but
 				 * we will turn it on since he is sending us
 				 * a stream reset.
 				 */
-				stcb->asoc.peer_supports_strreset = 1;
+				stcb->asoc.reconfig_supported = 1;
 			}
 			if (sctp_handle_stream_reset(stcb, m, *offset, ch)) {
 				/* stop processing */

Modified: head/sys/netinet/sctp_output.c
==============================================================================
--- head/sys/netinet/sctp_output.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_output.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -4820,7 +4820,9 @@ sctp_send_initiate(struct sctp_inpcb *in
 	if (stcb->asoc.pktdrop_supported == 1) {
 		pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
 	}
-	pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
+	if (stcb->asoc.reconfig_supported == 1) {
+		pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
+	}
 	if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
 		pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
 	}
@@ -5926,7 +5928,10 @@ do_a_abort:
 	    ((asoc == NULL) && (inp->pktdrop_supported == 1))) {
 		pr_supported->chunk_types[num_ext++] = SCTP_PACKET_DROPPED;
 	}
-	pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
+	if (((asoc != NULL) && (asoc->reconfig_supported == 1)) ||
+	    ((asoc == NULL) && (inp->reconfig_supported == 1))) {
+		pr_supported->chunk_types[num_ext++] = SCTP_STREAM_RESET;
+	}
 	if (!SCTP_BASE_SYSCTL(sctp_auth_disable)) {
 		pr_supported->chunk_types[num_ext++] = SCTP_AUTHENTICATION;
 	}

Modified: head/sys/netinet/sctp_pcb.c
==============================================================================
--- head/sys/netinet/sctp_pcb.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_pcb.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -2485,6 +2485,7 @@ sctp_inpcb_alloc(struct socket *so, uint
 	inp->sctp_cmt_on_off = SCTP_BASE_SYSCTL(sctp_cmt_on_off);
 	inp->ecn_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_ecn_enable);
 	inp->prsctp_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_pr_enable);
+	inp->reconfig_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_reconfig_enable);
 	inp->nrsack_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_nrsack_enable);
 	inp->pktdrop_supported = (uint8_t) SCTP_BASE_SYSCTL(sctp_pktdrop_enable);
 	/* init the small hash table we use to track asocid <-> tcb */
@@ -6086,6 +6087,7 @@ sctp_load_addresses_from_init(struct sct
 	int got_random = 0, got_hmacs = 0, got_chklist = 0;
 	uint8_t ecn_supported;
 	uint8_t prsctp_supported;
+	uint8_t reconfig_supported;
 	uint8_t nrsack_supported;
 	uint8_t pktdrop_supported;
 
@@ -6116,9 +6118,9 @@ sctp_load_addresses_from_init(struct sct
 	} else {
 		sa = src;
 	}
-	/* Turn off ECN until we get through all params */
 	ecn_supported = 0;
 	prsctp_supported = 0;
+	reconfig_supported = 0;
 	nrsack_supported = 0;
 	pktdrop_supported = 0;
 	TAILQ_FOREACH(net, &stcb->asoc.nets, sctp_next) {
@@ -6458,7 +6460,6 @@ sctp_load_addresses_from_init(struct sct
 				return (-25);
 			}
 			stcb->asoc.peer_supports_asconf = 0;
-			stcb->asoc.peer_supports_strreset = 0;
 			stcb->asoc.peer_supports_auth = 0;
 			pr_supported = (struct sctp_supported_chunk_types_param *)phdr;
 			num_ent = plen - sizeof(struct sctp_paramhdr);
@@ -6478,7 +6479,7 @@ sctp_load_addresses_from_init(struct sct
 					nrsack_supported = 1;
 					break;
 				case SCTP_STREAM_RESET:
-					stcb->asoc.peer_supports_strreset = 1;
+					reconfig_supported = 1;
 					break;
 				case SCTP_AUTHENTICATION:
 					stcb->asoc.peer_supports_auth = 1;
@@ -6620,6 +6621,7 @@ next_param:
 	}
 	stcb->asoc.ecn_supported &= ecn_supported;
 	stcb->asoc.prsctp_supported &= prsctp_supported;
+	stcb->asoc.reconfig_supported &= reconfig_supported;
 	stcb->asoc.nrsack_supported &= nrsack_supported;
 	stcb->asoc.pktdrop_supported &= pktdrop_supported;
 	/* validate authentication required parameters */

Modified: head/sys/netinet/sctp_pcb.h
==============================================================================
--- head/sys/netinet/sctp_pcb.h	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_pcb.h	Mon Aug  4 20:07:35 2014	(r269527)
@@ -408,6 +408,7 @@ struct sctp_inpcb {
 	uint32_t sctp_cmt_on_off;
 	uint8_t ecn_supported;
 	uint8_t prsctp_supported;
+	uint8_t reconfig_supported;
 	uint8_t nrsack_supported;
 	uint8_t pktdrop_supported;
 	struct sctp_nonpad_sndrcvinfo def_send;

Modified: head/sys/netinet/sctp_peeloff.c
==============================================================================
--- head/sys/netinet/sctp_peeloff.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_peeloff.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -120,6 +120,7 @@ sctp_do_peeloff(struct socket *head, str
 	n_inp->sctp_cmt_on_off = inp->sctp_cmt_on_off;
 	n_inp->ecn_supported = inp->ecn_supported;
 	n_inp->prsctp_supported = inp->prsctp_supported;
+	n_inp->reconfig_supported = inp->reconfig_supported;
 	n_inp->nrsack_supported = inp->nrsack_supported;
 	n_inp->pktdrop_supported = inp->pktdrop_supported;
 	n_inp->partial_delivery_point = inp->partial_delivery_point;

Modified: head/sys/netinet/sctp_structs.h
==============================================================================
--- head/sys/netinet/sctp_structs.h	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_structs.h	Mon Aug  4 20:07:35 2014	(r269527)
@@ -1153,6 +1153,7 @@ struct sctp_association {
 	/* Flags whether an extension is supported or not */
 	uint8_t ecn_supported;
 	uint8_t prsctp_supported;
+	uint8_t reconfig_supported;
 	uint8_t nrsack_supported;
 	uint8_t pktdrop_supported;
 
@@ -1163,8 +1164,6 @@ struct sctp_association {
 	uint8_t peer_supports_asconf;
 	/* peer authentication support flag */
 	uint8_t peer_supports_auth;
-	/* stream resets are supported by the peer */
-	uint8_t peer_supports_strreset;
 	uint8_t local_strreset_support;
 
 	uint8_t peer_supports_nat;

Modified: head/sys/netinet/sctp_sysctl.c
==============================================================================
--- head/sys/netinet/sctp_sysctl.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_sysctl.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -55,6 +55,7 @@ sctp_init_sysctls()
 	SCTP_BASE_SYSCTL(sctp_multiple_asconfs) = SCTPCTL_MULTIPLEASCONFS_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_ecn_enable) = SCTPCTL_ECN_ENABLE_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_pr_enable) = SCTPCTL_PR_ENABLE_DEFAULT;
+	SCTP_BASE_SYSCTL(sctp_reconfig_enable) = SCTPCTL_RECONFIG_ENABLE_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_nrsack_enable) = SCTPCTL_NRSACK_ENABLE_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_pktdrop_enable) = SCTPCTL_PKTDROP_ENABLE_DEFAULT;
 	SCTP_BASE_SYSCTL(sctp_strict_sacks) = SCTPCTL_STRICT_SACKS_DEFAULT;
@@ -602,6 +603,7 @@ sysctl_sctp_check(SYSCTL_HANDLER_ARGS)
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_auto_asconf), SCTPCTL_AUTOASCONF_MIN, SCTPCTL_AUTOASCONF_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_ecn_enable), SCTPCTL_ECN_ENABLE_MIN, SCTPCTL_ECN_ENABLE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_pr_enable), SCTPCTL_PR_ENABLE_MIN, SCTPCTL_PR_ENABLE_MAX);
+		RANGECHK(SCTP_BASE_SYSCTL(sctp_reconfig_enable), SCTPCTL_RECONFIG_ENABLE_MIN, SCTPCTL_RECONFIG_ENABLE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_nrsack_enable), SCTPCTL_NRSACK_ENABLE_MIN, SCTPCTL_NRSACK_ENABLE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_pktdrop_enable), SCTPCTL_PKTDROP_ENABLE_MIN, SCTPCTL_PKTDROP_ENABLE_MAX);
 		RANGECHK(SCTP_BASE_SYSCTL(sctp_strict_sacks), SCTPCTL_STRICT_SACKS_MIN, SCTPCTL_STRICT_SACKS_MAX);
@@ -867,6 +869,10 @@ SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUT
     &SCTP_BASE_SYSCTL(sctp_pr_enable), 0, sysctl_sctp_check, "IU",
     SCTPCTL_PR_ENABLE_DESC);
 
+SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, reconfig_enable, CTLTYPE_UINT | CTLFLAG_RW,
+    &SCTP_BASE_SYSCTL(sctp_reconfig_enable), 0, sysctl_sctp_check, "IU",
+    SCTPCTL_RECONFIG_ENABLE_DESC);
+
 SYSCTL_VNET_PROC(_net_inet_sctp, OID_AUTO, nrsack_enable, CTLTYPE_UINT | CTLFLAG_RW,
     &SCTP_BASE_SYSCTL(sctp_nrsack_enable), 0, sysctl_sctp_check, "IU",
     SCTPCTL_NRSACK_ENABLE_DESC);

Modified: head/sys/netinet/sctp_sysctl.h
==============================================================================
--- head/sys/netinet/sctp_sysctl.h	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_sysctl.h	Mon Aug  4 20:07:35 2014	(r269527)
@@ -46,6 +46,7 @@ struct sctp_sysctl {
 	uint32_t sctp_multiple_asconfs;
 	uint32_t sctp_ecn_enable;
 	uint32_t sctp_pr_enable;
+	uint32_t sctp_reconfig_enable;
 	uint32_t sctp_nrsack_enable;
 	uint32_t sctp_pktdrop_enable;
 	uint32_t sctp_fr_max_burst_default;
@@ -161,8 +162,14 @@ struct sctp_sysctl {
 #define SCTPCTL_PR_ENABLE_MAX		1
 #define SCTPCTL_PR_ENABLE_DEFAULT	1
 
+/* reconfig_enable: Enable SCTP RE-CONFIG */
+#define SCTPCTL_RECONFIG_ENABLE_DESC	"Enable SCTP RE-CONFIG"
+#define SCTPCTL_RECONFIG_ENABLE_MIN	0
+#define SCTPCTL_RECONFIG_ENABLE_MAX	1
+#define SCTPCTL_RECONFIG_ENABLE_DEFAULT	1
+
 /* nrsack_enable: Enable NR_SACK */
-#define SCTPCTL_NRSACK_ENABLE_DESC	"Enable NR_SACK"
+#define SCTPCTL_NRSACK_ENABLE_DESC	"Enable SCTP NR-SACK"
 #define SCTPCTL_NRSACK_ENABLE_MIN	0
 #define SCTPCTL_NRSACK_ENABLE_MAX	1
 #define SCTPCTL_NRSACK_ENABLE_DEFAULT	0

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctp_usrreq.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -3348,6 +3348,33 @@ flags_out:
 			}
 			break;
 		}
+	case SCTP_RECONFIG_SUPPORTED:
+		{
+			struct sctp_assoc_value *av;
+
+			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, *optsize);
+			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+
+			if (stcb) {
+				av->assoc_value = stcb->asoc.reconfig_supported;
+				SCTP_TCB_UNLOCK(stcb);
+			} else {
+				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+				    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+				    (av->assoc_id == SCTP_FUTURE_ASSOC)) {
+					SCTP_INP_RLOCK(inp);
+					av->assoc_value = inp->reconfig_supported;
+					SCTP_INP_RUNLOCK(inp);
+				} else {
+					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+					error = EINVAL;
+				}
+			}
+			if (error == 0) {
+				*optsize = sizeof(struct sctp_assoc_value);
+			}
+			break;
+		}
 	case SCTP_NRSACK_SUPPORTED:
 		{
 			struct sctp_assoc_value *av;
@@ -4274,7 +4301,7 @@ sctp_setopt(struct socket *so, int optna
 				error = ENOENT;
 				break;
 			}
-			if (stcb->asoc.peer_supports_strreset == 0) {
+			if (stcb->asoc.reconfig_supported == 0) {
 				/*
 				 * Peer does not support the chunk type.
 				 */
@@ -4341,7 +4368,7 @@ sctp_setopt(struct socket *so, int optna
 				error = ENOENT;
 				break;
 			}
-			if (stcb->asoc.peer_supports_strreset == 0) {
+			if (stcb->asoc.reconfig_supported == 0) {
 				/*
 				 * Peer does not support the chunk type.
 				 */
@@ -4410,7 +4437,7 @@ sctp_setopt(struct socket *so, int optna
 				error = ENOENT;
 				break;
 			}
-			if (stcb->asoc.peer_supports_strreset == 0) {
+			if (stcb->asoc.reconfig_supported == 0) {
 				/*
 				 * Peer does not support the chunk type.
 				 */
@@ -6023,6 +6050,35 @@ sctp_setopt(struct socket *so, int optna
 			}
 			break;
 		}
+	case SCTP_RECONFIG_SUPPORTED:
+		{
+			struct sctp_assoc_value *av;
+
+			SCTP_CHECK_AND_CAST(av, optval, struct sctp_assoc_value, optsize);
+			SCTP_FIND_STCB(inp, stcb, av->assoc_id);
+
+			if (stcb) {
+				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+				error = EINVAL;
+				SCTP_TCB_UNLOCK(stcb);
+			} else {
+				if ((inp->sctp_flags & SCTP_PCB_FLAGS_TCPTYPE) ||
+				    (inp->sctp_flags & SCTP_PCB_FLAGS_IN_TCPPOOL) ||
+				    (av->assoc_id == SCTP_FUTURE_ASSOC)) {
+					SCTP_INP_WLOCK(inp);
+					if (av->assoc_value == 0) {
+						inp->reconfig_supported = 0;
+					} else {
+						inp->reconfig_supported = 1;
+					}
+					SCTP_INP_WUNLOCK(inp);
+				} else {
+					SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+					error = EINVAL;
+				}
+			}
+			break;
+		}
 	case SCTP_NRSACK_SUPPORTED:
 		{
 			struct sctp_assoc_value *av;

Modified: head/sys/netinet/sctputil.c
==============================================================================
--- head/sys/netinet/sctputil.c	Mon Aug  4 19:42:48 2014	(r269526)
+++ head/sys/netinet/sctputil.c	Mon Aug  4 20:07:35 2014	(r269527)
@@ -906,6 +906,7 @@ sctp_init_asoc(struct sctp_inpcb *inp, s
 	asoc->sctp_cmt_on_off = inp->sctp_cmt_on_off;
 	asoc->ecn_supported = inp->ecn_supported;
 	asoc->prsctp_supported = inp->prsctp_supported;
+	asoc->reconfig_supported = inp->reconfig_supported;
 	asoc->nrsack_supported = inp->nrsack_supported;
 	asoc->pktdrop_supported = inp->pktdrop_supported;
 	asoc->sctp_cmt_pf = (uint8_t) 0;
@@ -2631,7 +2632,7 @@ sctp_notify_assoc_change(uint16_t state,
 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_ASCONF;
 				}
 				sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_MULTIBUF;
-				if (stcb->asoc.peer_supports_strreset) {
+				if (stcb->asoc.reconfig_supported) {
 					sac->sac_info[i++] = SCTP_ASSOC_SUPPORTS_RE_CONFIG;
 				}
 				sac->sac_length += i;


More information about the svn-src-all mailing list