net: sctp: implement rfc6458, 5.3.6. SCTP_NXTINFO cmsg support
Subsystems (2)
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
@@ -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
@@ -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
@@ -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
@@ -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