Commit ed410ecf authored by David S. Miller's avatar David S. Miller

Merge branch 'sctp-next'

Daniel Borkmann says:

====================
SCTP updates

This set improves the SCTP socket API to be more in line with RFC6458,
Geir and myself have finalized it eventually. While at it, the first
patch also fixes two possible information leaks that should go to net
tree as well (therefore the change is already here in net-next via a
merge of the 'net' tree -DaveM). For more details, I refer you to the
patches themselves.

Thanks a lot.

v1 -> v2:
 - Added 6th patch to deprecate SCTP_SNDRCV, rest unchanged
====================

CC: Jay Vosburgh <j.vosburgh@gmail.com>
CC: Andy Gospodarek <andy@greyhouse.net>
Signed-off-by: default avatarVeaceslav Falico <vfalico@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 1a98c69a bbbea41d
......@@ -109,6 +109,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
struct sctp_association *asoc);
extern struct percpu_counter sctp_sockets_allocated;
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *);
struct sk_buff *sctp_skb_recv_datagram(struct sock *, int, int, int *);
/*
* sctp/primitive.c
......
......@@ -207,7 +207,9 @@ struct sctp_sock {
struct sctp_paddrparams paddrparam;
struct sctp_event_subscribe subscribe;
struct sctp_assocparams assocparams;
int user_frag;
__u32 autoclose;
__u8 nodelay;
__u8 disable_fragments;
......@@ -215,6 +217,8 @@ struct sctp_sock {
__u8 frag_interleave;
__u32 adaptation_ind;
__u32 pd_point;
__u8 recvrcvinfo;
__u8 recvnxtinfo;
atomic_t pd_mode;
/* Receive to here while partial delivery is in effect. */
......@@ -1919,7 +1923,8 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
/* A convenience structure to parse out SCTP specific CMSGs. */
typedef struct sctp_cmsgs {
struct sctp_initmsg *init;
struct sctp_sndrcvinfo *info;
struct sctp_sndrcvinfo *srinfo;
struct sctp_sndinfo *sinfo;
} sctp_cmsgs_t;
/* Structure for tracking memory objects */
......
......@@ -130,6 +130,11 @@ struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
struct msghdr *);
void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,
struct msghdr *, struct sock *sk);
__u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
/* Is this event type enabled? */
......@@ -155,10 +160,3 @@ static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
}
#endif /* __sctp_ulpevent_h__ */
......@@ -95,6 +95,9 @@ typedef __s32 sctp_assoc_t;
#define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */
#define SCTP_AUTO_ASCONF 30
#define SCTP_PEER_ADDR_THLDS 31
#define SCTP_RECVRCVINFO 32
#define SCTP_RECVNXTINFO 33
#define SCTP_DEFAULT_SNDINFO 34
/* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options.
......@@ -110,8 +113,14 @@ typedef __s32 sctp_assoc_t;
#define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */
#define SCTP_GET_ASSOC_STATS 112 /* Read only */
/*
* 5.2.1 SCTP Initiation Structure (SCTP_INIT)
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
/* On user space Linux, these live in <bits/socket.h> as an enum. */
enum sctp_msg_flags {
MSG_NOTIFICATION = 0x8000,
#define MSG_NOTIFICATION MSG_NOTIFICATION
};
/* 5.3.1 SCTP Initiation Structure (SCTP_INIT)
*
* This cmsghdr structure provides information for initializing new
* SCTP associations with sendmsg(). The SCTP_INITMSG socket option
......@@ -121,7 +130,6 @@ typedef __s32 sctp_assoc_t;
* cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ ----------------------
* IPPROTO_SCTP SCTP_INIT struct sctp_initmsg
*
*/
struct sctp_initmsg {
__u16 sinit_num_ostreams;
......@@ -130,8 +138,7 @@ struct sctp_initmsg {
__u16 sinit_max_init_timeo;
};
/*
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
/* 5.3.2 SCTP Header Information Structure (SCTP_SNDRCV)
*
* This cmsghdr structure specifies SCTP options for sendmsg() and
* describes SCTP header information about a received message through
......@@ -140,7 +147,6 @@ struct sctp_initmsg {
* cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ ----------------------
* IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo
*
*/
struct sctp_sndrcvinfo {
__u16 sinfo_stream;
......@@ -154,19 +160,74 @@ struct sctp_sndrcvinfo {
sctp_assoc_t sinfo_assoc_id;
};
/* 5.3.4 SCTP Send Information Structure (SCTP_SNDINFO)
*
* This cmsghdr structure specifies SCTP options for sendmsg().
*
* cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ -------------------
* IPPROTO_SCTP SCTP_SNDINFO struct sctp_sndinfo
*/
struct sctp_sndinfo {
__u16 snd_sid;
__u16 snd_flags;
__u32 snd_ppid;
__u32 snd_context;
sctp_assoc_t snd_assoc_id;
};
/* 5.3.5 SCTP Receive Information Structure (SCTP_RCVINFO)
*
* This cmsghdr structure describes SCTP receive information
* about a received message through recvmsg().
*
* cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ -------------------
* IPPROTO_SCTP SCTP_RCVINFO struct sctp_rcvinfo
*/
struct sctp_rcvinfo {
__u16 rcv_sid;
__u16 rcv_ssn;
__u16 rcv_flags;
__u32 rcv_ppid;
__u32 rcv_tsn;
__u32 rcv_cumtsn;
__u32 rcv_context;
sctp_assoc_t rcv_assoc_id;
};
/* 5.3.6 SCTP Next Receive Information Structure (SCTP_NXTINFO)
*
* This cmsghdr structure describes SCTP receive information
* of the next message that will be delivered through recvmsg()
* if this information is already available when delivering
* the current message.
*
* cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ -------------------
* IPPROTO_SCTP SCTP_NXTINFO struct sctp_nxtinfo
*/
struct sctp_nxtinfo {
__u16 nxt_sid;
__u16 nxt_flags;
__u32 nxt_ppid;
__u32 nxt_length;
sctp_assoc_t nxt_assoc_id;
};
/*
* sinfo_flags: 16 bits (unsigned integer)
*
* This field may contain any of the following flags and is composed of
* a bitwise OR of these values.
*/
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_SACK_IMMEDIATELY = 8, /* SACK should be sent without delay */
SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */
SCTP_UNORDERED = (1 << 0), /* Send/receive message unordered. */
SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */
SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */
SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */
SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */
SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */
};
typedef union {
......@@ -181,6 +242,12 @@ typedef enum sctp_cmsg_type {
#define SCTP_INIT SCTP_INIT
SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */
#define SCTP_SNDRCV SCTP_SNDRCV
SCTP_SNDINFO, /* 5.3.4 SCTP Send Information Structure */
#define SCTP_SNDINFO SCTP_SNDINFO
SCTP_RCVINFO, /* 5.3.5 SCTP Receive Information Structure */
#define SCTP_RCVINFO SCTP_RCVINFO
SCTP_NXTINFO, /* 5.3.6 SCTP Next Receive Information Structure */
#define SCTP_NXTINFO SCTP_NXTINFO
} sctp_cmsg_t;
/*
......@@ -808,13 +875,6 @@ struct sctp_assoc_stats {
__u64 sas_ictrlchunks; /* Control chunks received */
};
/* These are bit fields for msghdr->msg_flags. See section 5.1. */
/* On user space Linux, these live in <bits/socket.h> as an enum. */
enum sctp_msg_flags {
MSG_NOTIFICATION = 0x8000,
#define MSG_NOTIFICATION MSG_NOTIFICATION
};
/*
* 8.1 sctp_bindx()
*
......
This diff is collapsed.
......@@ -886,6 +886,69 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
sizeof(sinfo), &sinfo);
}
/* RFC6458, Section 5.3.5 SCTP Receive Information Structure
* (SCTP_SNDRCV)
*/
void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
struct msghdr *msghdr)
{
struct sctp_rcvinfo rinfo;
if (sctp_ulpevent_is_notification(event))
return;
memset(&rinfo, 0, sizeof(struct sctp_rcvinfo));
rinfo.rcv_sid = event->stream;
rinfo.rcv_ssn = event->ssn;
rinfo.rcv_ppid = event->ppid;
rinfo.rcv_flags = event->flags;
rinfo.rcv_tsn = event->tsn;
rinfo.rcv_cumtsn = event->cumtsn;
rinfo.rcv_assoc_id = sctp_assoc2id(event->asoc);
rinfo.rcv_context = event->asoc->default_rcv_context;
put_cmsg(msghdr, IPPROTO_SCTP, SCTP_RCVINFO,
sizeof(rinfo), &rinfo);
}
/* RFC6458, Section 5.3.6. SCTP Next Receive Information Structure
* (SCTP_NXTINFO)
*/
static void __sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,
struct msghdr *msghdr,
const struct sk_buff *skb)
{
struct sctp_nxtinfo nxtinfo;
memset(&nxtinfo, 0, sizeof(nxtinfo));
nxtinfo.nxt_sid = event->stream;
nxtinfo.nxt_ppid = event->ppid;
nxtinfo.nxt_flags = event->flags;
if (sctp_ulpevent_is_notification(event))
nxtinfo.nxt_flags |= SCTP_NOTIFICATION;
nxtinfo.nxt_length = skb->len;
nxtinfo.nxt_assoc_id = sctp_assoc2id(event->asoc);
put_cmsg(msghdr, IPPROTO_SCTP, SCTP_NXTINFO,
sizeof(nxtinfo), &nxtinfo);
}
void sctp_ulpevent_read_nxtinfo(const struct sctp_ulpevent *event,
struct msghdr *msghdr,
struct sock *sk)
{
struct sk_buff *skb;
int err;
skb = sctp_skb_recv_datagram(sk, MSG_PEEK, 1, &err);
if (skb != NULL) {
__sctp_ulpevent_read_nxtinfo(sctp_skb2event(skb),
msghdr, skb);
/* Just release refcount here. */
kfree_skb(skb);
}
}
/* Do accounting for bytes received and hold a reference to the association
* for each skb.
*/
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment