aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorIvan Skytte Jorgensen <isj-sctp@i1.dk>2006-12-13 19:34:22 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-12-13 19:48:29 -0500
commit6ab792f577012312a760a3a1e679ae8fae012442 (patch)
tree7d60307266f3d81afdf06ec14e646d2f7a1b4ef7 /net
parent882a382c3e0b432fa91672e1c2754cac3f5a6b4f (diff)
[SCTP]: Add support for SCTP_CONTEXT socket option.
Signed-off-by: Ivan Skytte Jorgensen <isj-sctp@i1.dk> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/sctp/associola.c1
-rw-r--r--net/sctp/socket.c84
-rw-r--r--net/sctp/ulpevent.c4
3 files changed, 88 insertions, 1 deletions
diff --git a/net/sctp/associola.c b/net/sctp/associola.c
index ad0057db0f91..5db95caed0a3 100644
--- a/net/sctp/associola.c
+++ b/net/sctp/associola.c
@@ -298,6 +298,7 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a
298 asoc->default_flags = sp->default_flags; 298 asoc->default_flags = sp->default_flags;
299 asoc->default_context = sp->default_context; 299 asoc->default_context = sp->default_context;
300 asoc->default_timetolive = sp->default_timetolive; 300 asoc->default_timetolive = sp->default_timetolive;
301 asoc->default_rcv_context = sp->default_rcv_context;
301 302
302 return asoc; 303 return asoc;
303 304
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index fa29eae83e91..bdd8bd428b64 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -2746,6 +2746,46 @@ static int sctp_setsockopt_adaption_layer(struct sock *sk, char __user *optval,
2746 return 0; 2746 return 0;
2747} 2747}
2748 2748
2749/*
2750 * 7.1.29. Set or Get the default context (SCTP_CONTEXT)
2751 *
2752 * The context field in the sctp_sndrcvinfo structure is normally only
2753 * used when a failed message is retrieved holding the value that was
2754 * sent down on the actual send call. This option allows the setting of
2755 * a default context on an association basis that will be received on
2756 * reading messages from the peer. This is especially helpful in the
2757 * one-2-many model for an application to keep some reference to an
2758 * internal state machine that is processing messages on the
2759 * association. Note that the setting of this value only effects
2760 * received messages from the peer and does not effect the value that is
2761 * saved with outbound messages.
2762 */
2763static int sctp_setsockopt_context(struct sock *sk, char __user *optval,
2764 int optlen)
2765{
2766 struct sctp_assoc_value params;
2767 struct sctp_sock *sp;
2768 struct sctp_association *asoc;
2769
2770 if (optlen != sizeof(struct sctp_assoc_value))
2771 return -EINVAL;
2772 if (copy_from_user(&params, optval, optlen))
2773 return -EFAULT;
2774
2775 sp = sctp_sk(sk);
2776
2777 if (params.assoc_id != 0) {
2778 asoc = sctp_id2assoc(sk, params.assoc_id);
2779 if (!asoc)
2780 return -EINVAL;
2781 asoc->default_rcv_context = params.assoc_value;
2782 } else {
2783 sp->default_rcv_context = params.assoc_value;
2784 }
2785
2786 return 0;
2787}
2788
2749/* API 6.2 setsockopt(), getsockopt() 2789/* API 6.2 setsockopt(), getsockopt()
2750 * 2790 *
2751 * Applications use setsockopt() and getsockopt() to set or retrieve 2791 * Applications use setsockopt() and getsockopt() to set or retrieve
@@ -2857,6 +2897,9 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname,
2857 case SCTP_ADAPTION_LAYER: 2897 case SCTP_ADAPTION_LAYER:
2858 retval = sctp_setsockopt_adaption_layer(sk, optval, optlen); 2898 retval = sctp_setsockopt_adaption_layer(sk, optval, optlen);
2859 break; 2899 break;
2900 case SCTP_CONTEXT:
2901 retval = sctp_setsockopt_context(sk, optval, optlen);
2902 break;
2860 2903
2861 default: 2904 default:
2862 retval = -ENOPROTOOPT; 2905 retval = -ENOPROTOOPT;
@@ -3016,6 +3059,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk)
3016 sp->default_context = 0; 3059 sp->default_context = 0;
3017 sp->default_timetolive = 0; 3060 sp->default_timetolive = 0;
3018 3061
3062 sp->default_rcv_context = 0;
3063
3019 /* Initialize default setup parameters. These parameters 3064 /* Initialize default setup parameters. These parameters
3020 * can be modified with the SCTP_INITMSG socket option or 3065 * can be modified with the SCTP_INITMSG socket option or
3021 * overridden by the SCTP_INIT CMSG. 3066 * overridden by the SCTP_INIT CMSG.
@@ -4421,6 +4466,42 @@ static int sctp_getsockopt_mappedv4(struct sock *sk, int len,
4421} 4466}
4422 4467
4423/* 4468/*
4469 * 7.1.29. Set or Get the default context (SCTP_CONTEXT)
4470 * (chapter and verse is quoted at sctp_setsockopt_context())
4471 */
4472static int sctp_getsockopt_context(struct sock *sk, int len,
4473 char __user *optval, int __user *optlen)
4474{
4475 struct sctp_assoc_value params;
4476 struct sctp_sock *sp;
4477 struct sctp_association *asoc;
4478
4479 if (len != sizeof(struct sctp_assoc_value))
4480 return -EINVAL;
4481
4482 if (copy_from_user(&params, optval, len))
4483 return -EFAULT;
4484
4485 sp = sctp_sk(sk);
4486
4487 if (params.assoc_id != 0) {
4488 asoc = sctp_id2assoc(sk, params.assoc_id);
4489 if (!asoc)
4490 return -EINVAL;
4491 params.assoc_value = asoc->default_rcv_context;
4492 } else {
4493 params.assoc_value = sp->default_rcv_context;
4494 }
4495
4496 if (put_user(len, optlen))
4497 return -EFAULT;
4498 if (copy_to_user(optval, &params, len))
4499 return -EFAULT;
4500
4501 return 0;
4502}
4503
4504/*
4424 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG) 4505 * 7.1.17 Set the maximum fragrmentation size (SCTP_MAXSEG)
4425 * 4506 *
4426 * This socket option specifies the maximum size to put in any outgoing 4507 * This socket option specifies the maximum size to put in any outgoing
@@ -4558,6 +4639,9 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname,
4558 retval = sctp_getsockopt_adaption_layer(sk, len, optval, 4639 retval = sctp_getsockopt_adaption_layer(sk, len, optval,
4559 optlen); 4640 optlen);
4560 break; 4641 break;
4642 case SCTP_CONTEXT:
4643 retval = sctp_getsockopt_context(sk, len, optval, optlen);
4644 break;
4561 default: 4645 default:
4562 retval = -ENOPROTOOPT; 4646 retval = -ENOPROTOOPT;
4563 break; 4647 break;
diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c
index e255a709f1b7..93ac63b055ba 100644
--- a/net/sctp/ulpevent.c
+++ b/net/sctp/ulpevent.c
@@ -849,8 +849,10 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
849 */ 849 */
850 sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc); 850 sinfo.sinfo_assoc_id = sctp_assoc2id(event->asoc);
851 851
852 /* context value that is set via SCTP_CONTEXT socket option. */
853 sinfo.sinfo_context = event->asoc->default_rcv_context;
854
852 /* These fields are not used while receiving. */ 855 /* These fields are not used while receiving. */
853 sinfo.sinfo_context = 0;
854 sinfo.sinfo_timetolive = 0; 856 sinfo.sinfo_timetolive = 0;
855 857
856 put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, 858 put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV,