svn commit: r231446 - stable/8/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Fri Feb 10 22:10:37 UTC 2012
Author: tuexen
Date: Fri Feb 10 22:10:36 2012
New Revision: 231446
URL: http://svn.freebsd.org/changeset/base/231446
Log:
MFC 223162:
Add SCTP_DEFAULT_PRINFO socket option.
Fix the SCTP_DEFAULT_SNDINFO socket option: Don't clear the
PR SCTP policy when setting sinfo_flags.
Modified:
stable/8/sys/netinet/sctp.h
stable/8/sys/netinet/sctp_uio.h
stable/8/sys/netinet/sctp_usrreq.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/boot/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
stable/8/sys/dev/e1000/ (props changed)
Modified: stable/8/sys/netinet/sctp.h
==============================================================================
--- stable/8/sys/netinet/sctp.h Fri Feb 10 22:07:51 2012 (r231445)
+++ stable/8/sys/netinet/sctp.h Fri Feb 10 22:10:36 2012 (r231446)
@@ -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: stable/8/sys/netinet/sctp_uio.h
==============================================================================
--- stable/8/sys/netinet/sctp_uio.h Fri Feb 10 22:07:51 2012 (r231445)
+++ stable/8/sys/netinet/sctp_uio.h Fri Feb 10 22:10:36 2012 (r231446)
@@ -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: stable/8/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/8/sys/netinet/sctp_usrreq.c Fri Feb 10 22:07:51 2012 (r231445)
+++ stable/8/sys/netinet/sctp_usrreq.c Fri Feb 10 22:10:36 2012 (r231446)
@@ -3021,6 +3021,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);
@@ -3029,6 +3030,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);
@@ -3042,6 +3044,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;
@@ -5015,6 +5044,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);
@@ -5022,7 +5052,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 {
@@ -5035,7 +5067,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);
@@ -5047,7 +5081,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;
}
@@ -5058,6 +5094,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;
More information about the svn-src-stable
mailing list