From: Horacio Sanson <hsanson@xxxxxxxxxxxxxxxxxx> Modified all relevant structures in all header and source files to replace the deprecated sinfo_timetolive field with the newer sinfo_pr_policy and sinfo_pr_value. Added a new sctp_sinfo_pr_policy enum that contains the different PR policy definitions: SCTP_PR_SCTP_NONE and SCTP_PR_SCTP_TTL. And modified the values of sctp_sinfo_flags so they use the higher byte only and leave the lower byte free for sctp_pr_policy values. --- include/net/sctp/structs.h | 10 ++++++---- include/net/sctp/user.h | 22 +++++++++++++++++----- net/sctp/associola.c | 3 ++- net/sctp/chunk.c | 30 +++++++++++++++++++----------- net/sctp/output.c | 2 +- net/sctp/socket.c | 27 ++++++++++++++------------- net/sctp/ulpevent.c | 3 ++- 7 files changed, 61 insertions(+), 36 deletions(-) diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 9661d7b..2a86944 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -281,8 +281,9 @@ struct sctp_sock { __u16 default_stream; __u32 default_ppid; __u16 default_flags; + __u16 default_pr_policy; __u32 default_context; - __u32 default_timetolive; + __u32 default_pr_value; __u32 default_rcv_context; int max_burst; @@ -626,13 +627,13 @@ struct sctp_datamsg { struct list_head track; /* Reference counting. */ atomic_t refcnt; + /* Policy used to determine how expires_at is interpreted */ + unsigned long expires_policy; /* When is this message no longer interesting to the peer? */ unsigned long expires_at; /* Did the messenge fail to send? */ int send_error; char send_failed; - /* Control whether chunks from this message can be abandoned. */ - char can_abandon; }; struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *, @@ -1759,9 +1760,10 @@ struct sctp_association { /* Default send parameters. */ __u16 default_stream; __u16 default_flags; + __u16 default_pr_policy; __u32 default_ppid; __u32 default_context; - __u32 default_timetolive; + __u32 default_pr_value; /* Default receive parameters */ __u32 default_rcv_context; diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index f205b10..55ecc4a 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -183,9 +183,10 @@ struct sctp_sndrcvinfo { __u16 sinfo_stream; __u16 sinfo_ssn; __u16 sinfo_flags; + __u16 sinfo_pr_policy; __u32 sinfo_ppid; __u32 sinfo_context; - __u32 sinfo_timetolive; + __u32 sinfo_pr_value; __u32 sinfo_tsn; __u32 sinfo_cumtsn; sctp_assoc_t sinfo_assoc_id; @@ -199,12 +200,23 @@ struct sctp_sndrcvinfo { */ enum sctp_sinfo_flags { - SCTP_UNORDERED = 1, /* Send/receive message unordered. */ - SCTP_ADDR_OVER = 2, /* Override the primary destination. */ - SCTP_ABORT=4, /* Send an ABORT message to the peer. */ - SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */ + SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. (0x0200) */ + SCTP_UNORDERED = 0x0400, /* Send/receive message unordered. */ + SCTP_ADDR_OVER = 0x0800, /* Override the primary destination. */ + SCTP_ABORT = 0x1000, /* Send an ABORT message to the peer. */ }; +/* + * sinfo_pr_policy: 16 bits (unsigned integer) + * + * This field may contain the partial reliability used to + * send the message. + */ + +enum sctp_sinfo_pr_policy { + SCTP_PR_SCTP_NONE = 0x0000, /* Reliable transmission */ + SCTP_PR_SCTP_TTL = 0x0001, /* Timed partial reliability */ +}; typedef union { __u8 raw; diff --git a/net/sctp/associola.c b/net/sctp/associola.c index f4b2304..c178139 100644 --- a/net/sctp/associola.c +++ b/net/sctp/associola.c @@ -302,7 +302,8 @@ static struct sctp_association *sctp_association_init(struct sctp_association *a asoc->default_ppid = sp->default_ppid; asoc->default_flags = sp->default_flags; asoc->default_context = sp->default_context; - asoc->default_timetolive = sp->default_timetolive; + asoc->default_pr_policy = sp->default_pr_policy; + asoc->default_pr_value = sp->default_pr_value; asoc->default_rcv_context = sp->default_rcv_context; /* AUTH related initializations */ diff --git a/net/sctp/chunk.c b/net/sctp/chunk.c index 1748ef9..d499962 100644 --- a/net/sctp/chunk.c +++ b/net/sctp/chunk.c @@ -56,7 +56,7 @@ static void sctp_datamsg_init(struct sctp_datamsg *msg) atomic_set(&msg->refcnt, 1); msg->send_failed = 0; msg->send_error = 0; - msg->can_abandon = 0; + msg->expires_policy = SCTP_PR_SCTP_NONE; msg->expires_at = 0; INIT_LIST_HEAD(&msg->chunks); } @@ -170,13 +170,17 @@ struct sctp_datamsg *sctp_datamsg_from_user(struct sctp_association *asoc, /* Note: Calculate this outside of the loop, so that all fragments * have the same expiration. */ - if (sinfo->sinfo_timetolive) { - /* sinfo_timetolive is in milliseconds */ - msg->expires_at = jiffies + - msecs_to_jiffies(sinfo->sinfo_timetolive); - msg->can_abandon = 1; - SCTP_DEBUG_PRINTK("%s: msg:%p expires_at: %ld jiffies:%ld\n", - __func__, msg, msg->expires_at, jiffies); + + msg->expires_policy = sinfo->sinfo_pr_policy; + + if(msg->expires_policy) { + switch(msg->expires_policy) { + case SCTP_PR_SCTP_TTL: + /* sinfo_timetolive is in milliseconds */ + msg->expires_at = jiffies + + msecs_to_jiffies(sinfo->sinfo_pr_value); + break; + } } max = asoc->frag_point; @@ -291,11 +295,15 @@ int sctp_chunk_abandoned(struct sctp_chunk *chunk) { struct sctp_datamsg *msg = chunk->msg; - if (!msg->can_abandon) + if (!msg->expires_policy) return 0; - if (time_after(jiffies, msg->expires_at)) - return 1; + switch(msg->expires_policy) { + case SCTP_PR_SCTP_TTL: + if(time_after(jiffies, msg->expires_at)) + return 1; + break; + } return 0; } diff --git a/net/sctp/output.c b/net/sctp/output.c index c3f417f..b344a9d 100644 --- a/net/sctp/output.c +++ b/net/sctp/output.c @@ -745,7 +745,7 @@ static sctp_xmit_t sctp_packet_append_data(struct sctp_packet *packet, asoc->peer.rwnd = rwnd; /* Has been accepted for transmission. */ if (!asoc->peer.prsctp_capable) - chunk->msg->can_abandon = 0; + chunk->msg->expires_policy = SCTP_PR_SCTP_NONE; finish: return retval; diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a1b9045..eef5842 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -1698,7 +1698,8 @@ SCTP_STATIC int sctp_sendmsg(struct kiocb *iocb, struct sock *sk, default_sinfo.sinfo_flags = asoc->default_flags; default_sinfo.sinfo_ppid = asoc->default_ppid; default_sinfo.sinfo_context = asoc->default_context; - default_sinfo.sinfo_timetolive = asoc->default_timetolive; + default_sinfo.sinfo_pr_policy = asoc->default_pr_policy; + default_sinfo.sinfo_pr_value = asoc->default_pr_value; default_sinfo.sinfo_assoc_id = sctp_assoc2id(asoc); sinfo = &default_sinfo; } @@ -2539,7 +2540,7 @@ static int sctp_setsockopt_initmsg(struct sock *sk, char __user *optval, int opt * in to this call the sctp_sndrcvinfo structure defined in Section * 5.2.2) The input parameters accepted by this call include * sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, - * sinfo_timetolive. The user must provide the sinfo_assoc_id field in + * sinfo_pr_value. The user must provide the sinfo_assoc_id field in * to this call if the caller is using the UDP model. */ static int sctp_setsockopt_default_send_param(struct sock *sk, @@ -2563,13 +2564,15 @@ static int sctp_setsockopt_default_send_param(struct sock *sk, asoc->default_flags = info.sinfo_flags; asoc->default_ppid = info.sinfo_ppid; asoc->default_context = info.sinfo_context; - asoc->default_timetolive = info.sinfo_timetolive; + asoc->default_pr_policy = info.sinfo_pr_policy; + asoc->default_pr_value = info.sinfo_pr_value; } else { sp->default_stream = info.sinfo_stream; sp->default_flags = info.sinfo_flags; sp->default_ppid = info.sinfo_ppid; sp->default_context = info.sinfo_context; - sp->default_timetolive = info.sinfo_timetolive; + sp->default_pr_policy = info.sinfo_pr_policy; + sp->default_pr_value = info.sinfo_pr_value; } return 0; @@ -3524,7 +3527,8 @@ SCTP_STATIC int sctp_init_sock(struct sock *sk) sp->default_ppid = 0; sp->default_flags = 0; sp->default_context = 0; - sp->default_timetolive = 0; + sp->default_pr_policy = 0; + sp->default_pr_value = 0; sp->default_rcv_context = 0; sp->max_burst = sctp_max_burst; @@ -4824,7 +4828,7 @@ static int sctp_getsockopt_adaptation_layer(struct sock *sk, int len, * in to this call the sctp_sndrcvinfo structure defined in Section * 5.2.2) The input parameters accepted by this call include * sinfo_stream, sinfo_flags, sinfo_ppid, sinfo_context, - * sinfo_timetolive. The user must provide the sinfo_assoc_id field in + * sinfo_pr_value. The user must provide the sinfo_assoc_id field in * to this call if the caller is using the UDP model. * * For getsockopt, it get the default sctp_sndrcvinfo structure. @@ -4854,13 +4858,15 @@ static int sctp_getsockopt_default_send_param(struct sock *sk, info.sinfo_flags = asoc->default_flags; info.sinfo_ppid = asoc->default_ppid; info.sinfo_context = asoc->default_context; - info.sinfo_timetolive = asoc->default_timetolive; + info.sinfo_pr_policy = asoc->default_pr_policy; + info.sinfo_pr_value = asoc->default_pr_value; } else { info.sinfo_stream = sp->default_stream; info.sinfo_flags = sp->default_flags; info.sinfo_ppid = sp->default_ppid; info.sinfo_context = sp->default_context; - info.sinfo_timetolive = sp->default_timetolive; + info.sinfo_pr_policy = sp->default_pr_policy; + info.sinfo_pr_value = sp->default_pr_value; } if (put_user(len, optlen)) @@ -6106,11 +6112,6 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg, cmsgs->info = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg); - /* Minimally, validate the sinfo_flags. */ - if (cmsgs->info->sinfo_flags & - ~(SCTP_UNORDERED | SCTP_ADDR_OVER | - SCTP_ABORT | SCTP_EOF)) - return -EINVAL; break; default: diff --git a/net/sctp/ulpevent.c b/net/sctp/ulpevent.c index 5f186ca..2c6f111 100644 --- a/net/sctp/ulpevent.c +++ b/net/sctp/ulpevent.c @@ -948,7 +948,8 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, sinfo.sinfo_context = event->asoc->default_rcv_context; /* These fields are not used while receiving. */ - sinfo.sinfo_timetolive = 0; + sinfo.sinfo_pr_policy = 0; + sinfo.sinfo_pr_value = 0; put_cmsg(msghdr, IPPROTO_SCTP, SCTP_SNDRCV, sizeof(struct sctp_sndrcvinfo), (void *)&sinfo); -- 1.5.6.3 -- To unsubscribe from this list: send the line "unsubscribe linux-sctp" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html