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, ...@@ -109,6 +109,7 @@ void sctp_copy_sock(struct sock *newsk, struct sock *sk,
struct sctp_association *asoc); struct sctp_association *asoc);
extern struct percpu_counter sctp_sockets_allocated; extern struct percpu_counter sctp_sockets_allocated;
int sctp_asconf_mgmt(struct sctp_sock *, struct sctp_sockaddr_entry *); 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 * sctp/primitive.c
......
...@@ -207,7 +207,9 @@ struct sctp_sock { ...@@ -207,7 +207,9 @@ struct sctp_sock {
struct sctp_paddrparams paddrparam; struct sctp_paddrparams paddrparam;
struct sctp_event_subscribe subscribe; struct sctp_event_subscribe subscribe;
struct sctp_assocparams assocparams; struct sctp_assocparams assocparams;
int user_frag; int user_frag;
__u32 autoclose; __u32 autoclose;
__u8 nodelay; __u8 nodelay;
__u8 disable_fragments; __u8 disable_fragments;
...@@ -215,6 +217,8 @@ struct sctp_sock { ...@@ -215,6 +217,8 @@ struct sctp_sock {
__u8 frag_interleave; __u8 frag_interleave;
__u32 adaptation_ind; __u32 adaptation_ind;
__u32 pd_point; __u32 pd_point;
__u8 recvrcvinfo;
__u8 recvnxtinfo;
atomic_t pd_mode; atomic_t pd_mode;
/* Receive to here while partial delivery is in effect. */ /* Receive to here while partial delivery is in effect. */
...@@ -1919,7 +1923,8 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc); ...@@ -1919,7 +1923,8 @@ struct sctp_chunk *sctp_get_ecne_prepend(struct sctp_association *asoc);
/* A convenience structure to parse out SCTP specific CMSGs. */ /* A convenience structure to parse out SCTP specific CMSGs. */
typedef struct sctp_cmsgs { typedef struct sctp_cmsgs {
struct sctp_initmsg *init; struct sctp_initmsg *init;
struct sctp_sndrcvinfo *info; struct sctp_sndrcvinfo *srinfo;
struct sctp_sndinfo *sinfo;
} sctp_cmsgs_t; } sctp_cmsgs_t;
/* Structure for tracking memory objects */ /* Structure for tracking memory objects */
......
...@@ -129,7 +129,12 @@ struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event( ...@@ -129,7 +129,12 @@ struct sctp_ulpevent *sctp_ulpevent_make_sender_dry_event(
const struct sctp_association *asoc, gfp_t gfp); const struct sctp_association *asoc, gfp_t gfp);
void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
struct msghdr *); 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); __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event);
/* Is this event type enabled? */ /* Is this event type enabled? */
...@@ -155,10 +160,3 @@ static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event, ...@@ -155,10 +160,3 @@ static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
} }
#endif /* __sctp_ulpevent_h__ */ #endif /* __sctp_ulpevent_h__ */
...@@ -95,6 +95,9 @@ typedef __s32 sctp_assoc_t; ...@@ -95,6 +95,9 @@ typedef __s32 sctp_assoc_t;
#define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */ #define SCTP_GET_ASSOC_ID_LIST 29 /* Read only */
#define SCTP_AUTO_ASCONF 30 #define SCTP_AUTO_ASCONF 30
#define SCTP_PEER_ADDR_THLDS 31 #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 /* Internal Socket Options. Some of the sctp library functions are
* implemented using these socket options. * implemented using these socket options.
...@@ -110,8 +113,14 @@ typedef __s32 sctp_assoc_t; ...@@ -110,8 +113,14 @@ typedef __s32 sctp_assoc_t;
#define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */ #define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */
#define SCTP_GET_ASSOC_STATS 112 /* Read only */ #define SCTP_GET_ASSOC_STATS 112 /* Read only */
/* /* These are bit fields for msghdr->msg_flags. See section 5.1. */
* 5.2.1 SCTP Initiation Structure (SCTP_INIT) /* 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 * This cmsghdr structure provides information for initializing new
* SCTP associations with sendmsg(). The SCTP_INITMSG socket option * SCTP associations with sendmsg(). The SCTP_INITMSG socket option
...@@ -121,7 +130,6 @@ typedef __s32 sctp_assoc_t; ...@@ -121,7 +130,6 @@ typedef __s32 sctp_assoc_t;
* cmsg_level cmsg_type cmsg_data[] * cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ ---------------------- * ------------ ------------ ----------------------
* IPPROTO_SCTP SCTP_INIT struct sctp_initmsg * IPPROTO_SCTP SCTP_INIT struct sctp_initmsg
*
*/ */
struct sctp_initmsg { struct sctp_initmsg {
__u16 sinit_num_ostreams; __u16 sinit_num_ostreams;
...@@ -130,8 +138,7 @@ struct sctp_initmsg { ...@@ -130,8 +138,7 @@ struct sctp_initmsg {
__u16 sinit_max_init_timeo; __u16 sinit_max_init_timeo;
}; };
/* /* 5.3.2 SCTP Header Information Structure (SCTP_SNDRCV)
* 5.2.2 SCTP Header Information Structure (SCTP_SNDRCV)
* *
* This cmsghdr structure specifies SCTP options for sendmsg() and * This cmsghdr structure specifies SCTP options for sendmsg() and
* describes SCTP header information about a received message through * describes SCTP header information about a received message through
...@@ -140,7 +147,6 @@ struct sctp_initmsg { ...@@ -140,7 +147,6 @@ struct sctp_initmsg {
* cmsg_level cmsg_type cmsg_data[] * cmsg_level cmsg_type cmsg_data[]
* ------------ ------------ ---------------------- * ------------ ------------ ----------------------
* IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo * IPPROTO_SCTP SCTP_SNDRCV struct sctp_sndrcvinfo
*
*/ */
struct sctp_sndrcvinfo { struct sctp_sndrcvinfo {
__u16 sinfo_stream; __u16 sinfo_stream;
...@@ -154,19 +160,74 @@ struct sctp_sndrcvinfo { ...@@ -154,19 +160,74 @@ struct sctp_sndrcvinfo {
sctp_assoc_t sinfo_assoc_id; 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) * sinfo_flags: 16 bits (unsigned integer)
* *
* This field may contain any of the following flags and is composed of * This field may contain any of the following flags and is composed of
* a bitwise OR of these values. * a bitwise OR of these values.
*/ */
enum sctp_sinfo_flags { enum sctp_sinfo_flags {
SCTP_UNORDERED = 1, /* Send/receive message unordered. */ SCTP_UNORDERED = (1 << 0), /* Send/receive message unordered. */
SCTP_ADDR_OVER = 2, /* Override the primary destination. */ SCTP_ADDR_OVER = (1 << 1), /* Override the primary destination. */
SCTP_ABORT=4, /* Send an ABORT message to the peer. */ SCTP_ABORT = (1 << 2), /* Send an ABORT message to the peer. */
SCTP_SACK_IMMEDIATELY = 8, /* SACK should be sent without delay */ SCTP_SACK_IMMEDIATELY = (1 << 3), /* SACK should be sent without delay. */
SCTP_EOF=MSG_FIN, /* Initiate graceful shutdown process. */ SCTP_NOTIFICATION = MSG_NOTIFICATION, /* Next message is not user msg but notification. */
SCTP_EOF = MSG_FIN, /* Initiate graceful shutdown process. */
}; };
typedef union { typedef union {
...@@ -177,10 +238,16 @@ typedef union { ...@@ -177,10 +238,16 @@ typedef union {
/* These are cmsg_types. */ /* These are cmsg_types. */
typedef enum sctp_cmsg_type { typedef enum sctp_cmsg_type {
SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */ SCTP_INIT, /* 5.2.1 SCTP Initiation Structure */
#define SCTP_INIT SCTP_INIT #define SCTP_INIT SCTP_INIT
SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */ SCTP_SNDRCV, /* 5.2.2 SCTP Header Information Structure */
#define SCTP_SNDRCV SCTP_SNDRCV #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; } sctp_cmsg_t;
/* /*
...@@ -808,13 +875,6 @@ struct sctp_assoc_stats { ...@@ -808,13 +875,6 @@ struct sctp_assoc_stats {
__u64 sas_ictrlchunks; /* Control chunks received */ __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() * 8.1 sctp_bindx()
* *
......
This diff is collapsed.
...@@ -886,6 +886,69 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event, ...@@ -886,6 +886,69 @@ void sctp_ulpevent_read_sndrcvinfo(const struct sctp_ulpevent *event,
sizeof(sinfo), &sinfo); 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 /* Do accounting for bytes received and hold a reference to the association
* for each skb. * 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