Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Jun 2011 21:12:36 +0000 (UTC)
From:      Michael Tuexen <tuexen@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r223162 - head/sys/netinet
Message-ID:  <201106162112.p5GLCaQK046041@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: tuexen
Date: Thu Jun 16 21:12:36 2011
New Revision: 223162
URL: http://svn.freebsd.org/changeset/base/223162

Log:
  Add SCTP_DEFAULT_PRINFO socket option.
  Fix the SCTP_DEFAULT_SNDINFO socket option: Don't clear the
  PR SCTP policy when setting sinfo_flags.
  
  MFC after: 1 month.

Modified:
  head/sys/netinet/sctp.h
  head/sys/netinet/sctp_uio.h
  head/sys/netinet/sctp_usrreq.c

Modified: head/sys/netinet/sctp.h
==============================================================================
--- head/sys/netinet/sctp.h	Thu Jun 16 20:58:23 2011	(r223161)
+++ head/sys/netinet/sctp.h	Thu Jun 16 21:12:36 2011	(r223162)
@@ -118,6 +118,7 @@ struct sctp_paramhdr {
 #define SCTP_RECVRCVINFO                0x0000001f
 #define SCTP_RECVNXTINFO                0x00000020
 #define SCTP_DEFAULT_SNDINFO            0x00000021
+#define SCTP_DEFAULT_PRINFO             0x00000022
 
 /*
  * read-only options

Modified: head/sys/netinet/sctp_uio.h
==============================================================================
--- head/sys/netinet/sctp_uio.h	Thu Jun 16 20:58:23 2011	(r223161)
+++ head/sys/netinet/sctp_uio.h	Thu Jun 16 21:12:36 2011	(r223162)
@@ -162,6 +162,12 @@ struct sctp_prinfo {
 	uint32_t pr_value;
 };
 
+struct sctp_default_prinfo {
+	uint16_t pr_policy;
+	uint32_t pr_value;
+	sctp_assoc_t pr_assoc_id;
+};
+
 struct sctp_authinfo {
 	uint16_t auth_keyid;
 };

Modified: head/sys/netinet/sctp_usrreq.c
==============================================================================
--- head/sys/netinet/sctp_usrreq.c	Thu Jun 16 20:58:23 2011	(r223161)
+++ head/sys/netinet/sctp_usrreq.c	Thu Jun 16 21:12:36 2011	(r223162)
@@ -3030,6 +3030,7 @@ flags_out:
 			if (stcb) {
 				info->snd_sid = stcb->asoc.def_send.sinfo_stream;
 				info->snd_flags = stcb->asoc.def_send.sinfo_flags;
+				info->snd_flags &= 0xfff0;
 				info->snd_ppid = stcb->asoc.def_send.sinfo_ppid;
 				info->snd_context = stcb->asoc.def_send.sinfo_context;
 				SCTP_TCB_UNLOCK(stcb);
@@ -3038,6 +3039,7 @@ flags_out:
 					SCTP_INP_RLOCK(inp);
 					info->snd_sid = inp->def_send.sinfo_stream;
 					info->snd_flags = inp->def_send.sinfo_flags;
+					info->snd_flags &= 0xfff0;
 					info->snd_ppid = inp->def_send.sinfo_ppid;
 					info->snd_context = inp->def_send.sinfo_context;
 					SCTP_INP_RUNLOCK(inp);
@@ -3051,6 +3053,33 @@ flags_out:
 			}
 			break;
 		}
+	case SCTP_DEFAULT_PRINFO:
+		{
+			struct sctp_default_prinfo *info;
+
+			SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, *optsize);
+			SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
+
+			if (stcb) {
+				info->pr_policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
+				info->pr_value = stcb->asoc.def_send.sinfo_timetolive;
+				SCTP_TCB_UNLOCK(stcb);
+			} else {
+				if (info->pr_assoc_id == SCTP_FUTURE_ASSOC) {
+					SCTP_INP_RLOCK(inp);
+					info->pr_policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags);
+					info->pr_value = inp->def_send.sinfo_timetolive;
+					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_default_prinfo);
+			}
+			break;
+		}
 	default:
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
 		error = ENOPROTOOPT;
@@ -5043,6 +5072,7 @@ sctp_setopt(struct socket *so, int optna
 	case SCTP_DEFAULT_SNDINFO:
 		{
 			struct sctp_sndinfo *info;
+			uint16_t policy;
 
 			SCTP_CHECK_AND_CAST(info, optval, struct sctp_sndinfo, optsize);
 			SCTP_FIND_STCB(inp, stcb, info->snd_assoc_id);
@@ -5050,7 +5080,9 @@ sctp_setopt(struct socket *so, int optna
 			if (stcb) {
 				if (info->snd_sid < stcb->asoc.streamoutcnt) {
 					stcb->asoc.def_send.sinfo_stream = info->snd_sid;
+					policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
 					stcb->asoc.def_send.sinfo_flags = info->snd_flags;
+					stcb->asoc.def_send.sinfo_flags |= policy;
 					stcb->asoc.def_send.sinfo_ppid = info->snd_ppid;
 					stcb->asoc.def_send.sinfo_context = info->snd_context;
 				} else {
@@ -5063,7 +5095,9 @@ sctp_setopt(struct socket *so, int optna
 				    (info->snd_assoc_id == SCTP_ALL_ASSOC)) {
 					SCTP_INP_WLOCK(inp);
 					inp->def_send.sinfo_stream = info->snd_sid;
+					policy = PR_SCTP_POLICY(inp->def_send.sinfo_flags);
 					inp->def_send.sinfo_flags = info->snd_flags;
+					inp->def_send.sinfo_flags |= policy;
 					inp->def_send.sinfo_ppid = info->snd_ppid;
 					inp->def_send.sinfo_context = info->snd_context;
 					SCTP_INP_WUNLOCK(inp);
@@ -5075,7 +5109,9 @@ sctp_setopt(struct socket *so, int optna
 						SCTP_TCB_LOCK(stcb);
 						if (info->snd_sid < stcb->asoc.streamoutcnt) {
 							stcb->asoc.def_send.sinfo_stream = info->snd_sid;
+							policy = PR_SCTP_POLICY(stcb->asoc.def_send.sinfo_flags);
 							stcb->asoc.def_send.sinfo_flags = info->snd_flags;
+							stcb->asoc.def_send.sinfo_flags |= policy;
 							stcb->asoc.def_send.sinfo_ppid = info->snd_ppid;
 							stcb->asoc.def_send.sinfo_context = info->snd_context;
 						}
@@ -5086,6 +5122,44 @@ sctp_setopt(struct socket *so, int optna
 			}
 			break;
 		}
+	case SCTP_DEFAULT_PRINFO:
+		{
+			struct sctp_default_prinfo *info;
+
+			SCTP_CHECK_AND_CAST(info, optval, struct sctp_default_prinfo, optsize);
+			SCTP_FIND_STCB(inp, stcb, info->pr_assoc_id);
+
+			if (PR_SCTP_INVALID_POLICY(info->pr_policy)) {
+				SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
+				error = EINVAL;
+				break;
+			}
+			if (stcb) {
+				stcb->asoc.def_send.sinfo_flags &= 0xfff0;
+				stcb->asoc.def_send.sinfo_flags |= info->pr_policy;
+				SCTP_TCB_UNLOCK(stcb);
+			} else {
+				if ((info->pr_assoc_id == SCTP_FUTURE_ASSOC) ||
+				    (info->pr_assoc_id == SCTP_ALL_ASSOC)) {
+					SCTP_INP_WLOCK(inp);
+					inp->def_send.sinfo_flags &= 0xfff0;
+					inp->def_send.sinfo_flags |= info->pr_policy;
+					SCTP_INP_WUNLOCK(inp);
+				}
+				if ((info->pr_assoc_id == SCTP_CURRENT_ASSOC) ||
+				    (info->pr_assoc_id == SCTP_ALL_ASSOC)) {
+					SCTP_INP_RLOCK(inp);
+					LIST_FOREACH(stcb, &inp->sctp_asoc_list, sctp_tcblist) {
+						SCTP_TCB_LOCK(stcb);
+						stcb->asoc.def_send.sinfo_flags &= 0xfff0;
+						stcb->asoc.def_send.sinfo_flags |= info->pr_policy;
+						SCTP_TCB_UNLOCK(stcb);
+					}
+					SCTP_INP_RUNLOCK(inp);
+				}
+			}
+			break;
+		}
 	default:
 		SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, ENOPROTOOPT);
 		error = ENOPROTOOPT;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106162112.p5GLCaQK046041>