Skip to contentSkip to conversation

net: sctp: implement rfc6458, 5.3.6. SCTP_NXTINFO cmsg support

PATCH Applied Daniel Borkmann 1 participant 1 message Jul 12, 2014

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH v2 4/6 net: sctp: implement rfc6458, 5.3.6. SCTP_NXTINFO cmsg support

From: Geir Ola Vaagland <[email protected]>

This patch implements section 5.3.6. of RFC6458, that is, support for 'SCTP Next Receive Information Structure' (SCTP_NXTINFO) which is placed into ancillary data cmsghdr structure for each recvmsg() call, if this information is already available when delivering the current message.

This option can be enabled/disabled via setsockopt(2) on SOL_SCTP level by setting an int value with 1/0 for SCTP_RECVNXTINFO in user space applications as per RFC6458, section 8.1.30.

The sctp_nxtinfo structure is defined as per RFC as below ...

  struct sctp_nxtinfo {
    uint16_t nxt_sid;
    uint16_t nxt_flags;
    uint32_t nxt_ppid;
    uint32_t nxt_length;
    sctp_assoc_t nxt_assoc_id;
  };

... and provided under cmsg_level IPPROTO_SCTP, cmsg_type SCTP_NXTINFO, while cmsg_data[] contains struct sctp_nxtinfo.

Joint work with Daniel Borkmann.

---
 include/net/sctp/sctp.h     |  1 +
 include/net/sctp/structs.h  |  1 +
 include/net/sctp/ulpevent.h |  9 ++------
 include/uapi/linux/sctp.h   | 47 +++++++++++++++++++++++++++++-----------
 net/sctp/socket.c           | 52 +++++++++++++++++++++++++++++++++++++++++----
 net/sctp/ulpevent.c         | 38 +++++++++++++++++++++++++++++++++
 6 files changed, 125 insertions(+), 23 deletions(-)
include/net/sctp/sctp.h +1 -0
index c2035c9..90c1ccc 100644
@@ -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
include/net/sctp/structs.h +1 -0
index 11d5df0..7741d1b 100644
@@ -218,6 +218,7 @@ struct sctp_sock {
 	__u32 adaptation_ind;
 	__u32 pd_point;
 	__u8 recvrcvinfo;
+	__u8 recvnxtinfo;
 
 	atomic_t pd_mode;
 	/* Receive to here while partial delivery is in effect. */
include/net/sctp/ulpevent.h +2 -7
index e8095f9..cccdcfd 100644
@@ -132,6 +132,8 @@ 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);
 
@@ -158,10 +160,3 @@ static inline int sctp_ulpevent_is_enabled(const struct sctp_ulpevent *event,
 }
 
 #endif /* __sctp_ulpevent_h__ */
-
-
-
-
-
-
-
include/uapi/linux/sctp.h +35 -12

83 lines not on this page · raw message

net/sctp/socket.c +48 -4

100 lines not on this page · raw message

net/sctp/ulpevent.c +38 -0
index b31f365..e049298 100644
@@ -911,6 +911,44 @@ void sctp_ulpevent_read_rcvinfo(const struct sctp_ulpevent *event,
 		 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.
  */
Signature · 1 line
1.7.11.7