svn commit: r235172 - stable/9/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Wed May 9 14:16:00 UTC 2012
Author: tuexen
Date: Wed May 9 14:15:59 2012
New Revision: 235172
URL: http://svn.freebsd.org/changeset/base/235172
Log:
MFC r235075:
Add support for SCTP_SEND_FAILED_EVENT as required by RFC 6458.
Modified:
stable/9/sys/netinet/sctp.h
stable/9/sys/netinet/sctp_uio.h
stable/9/sys/netinet/sctp_usrreq.c
stable/9/sys/netinet/sctputil.c
Directory Properties:
stable/9/sys/ (props changed)
Modified: stable/9/sys/netinet/sctp.h
==============================================================================
--- stable/9/sys/netinet/sctp.h Wed May 9 14:12:08 2012 (r235171)
+++ stable/9/sys/netinet/sctp.h Wed May 9 14:15:59 2012 (r235172)
@@ -526,7 +526,7 @@ struct sctp_error_unrecognized_chunk {
#define SCTP_PCB_FLAGS_RECVASSOCEVNT 0x00000800
#define SCTP_PCB_FLAGS_RECVPADDREVNT 0x00001000
#define SCTP_PCB_FLAGS_RECVPEERERR 0x00002000
-#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x00004000
+#define SCTP_PCB_FLAGS_RECVSENDFAILEVNT 0x00004000 /* deprecated */
#define SCTP_PCB_FLAGS_RECVSHUTDOWNEVNT 0x00008000
#define SCTP_PCB_FLAGS_ADAPTATIONEVNT 0x00010000
#define SCTP_PCB_FLAGS_PDAPIEVNT 0x00020000
@@ -542,6 +542,7 @@ struct sctp_error_unrecognized_chunk {
#define SCTP_PCB_FLAGS_RECVNXTINFO 0x10000000
#define SCTP_PCB_FLAGS_ASSOC_RESETEVNT 0x20000000
#define SCTP_PCB_FLAGS_STREAM_CHANGEEVNT 0x40000000
+#define SCTP_PCB_FLAGS_RECVNSENDFAILEVNT 0x80000000
/*-
* mobility_features parameters (by micchie).Note
Modified: stable/9/sys/netinet/sctp_uio.h
==============================================================================
--- stable/9/sys/netinet/sctp_uio.h Wed May 9 14:12:08 2012 (r235171)
+++ stable/9/sys/netinet/sctp_uio.h Wed May 9 14:15:59 2012 (r235172)
@@ -343,7 +343,7 @@ struct sctp_remote_error {
uint8_t sre_data[4];
};
-/* data send failure event */
+/* data send failure event (deprecated) */
struct sctp_send_failed {
uint16_t ssf_type;
uint16_t ssf_flags;
@@ -354,6 +354,17 @@ struct sctp_send_failed {
uint8_t ssf_data[];
};
+/* data send failure event (not deprecated) */
+struct sctp_send_failed_event {
+ uint16_t ssfe_type;
+ uint16_t ssfe_flags;
+ uint32_t ssfe_length;
+ uint32_t ssfe_error;
+ struct sctp_sndinfo ssfe_info;
+ sctp_assoc_t ssfe_assoc_id;
+ uint8_t ssfe_data[];
+};
+
/* flag that indicates state of data */
#define SCTP_DATA_UNSENT 0x0001 /* inqueue never on wire */
#define SCTP_DATA_SENT 0x0002 /* on wire at failure */
@@ -513,22 +524,22 @@ union sctp_notification {
};
/* notification types */
-#define SCTP_ASSOC_CHANGE 0x0001
-#define SCTP_PEER_ADDR_CHANGE 0x0002
-#define SCTP_REMOTE_ERROR 0x0003
-#define SCTP_SEND_FAILED 0x0004
-#define SCTP_SHUTDOWN_EVENT 0x0005
-#define SCTP_ADAPTATION_INDICATION 0x0006
+#define SCTP_ASSOC_CHANGE 0x0001
+#define SCTP_PEER_ADDR_CHANGE 0x0002
+#define SCTP_REMOTE_ERROR 0x0003
+#define SCTP_SEND_FAILED 0x0004
+#define SCTP_SHUTDOWN_EVENT 0x0005
+#define SCTP_ADAPTATION_INDICATION 0x0006
/* same as above */
-#define SCTP_ADAPTION_INDICATION 0x0006
-#define SCTP_PARTIAL_DELIVERY_EVENT 0x0007
-#define SCTP_AUTHENTICATION_EVENT 0x0008
-#define SCTP_STREAM_RESET_EVENT 0x0009
-#define SCTP_SENDER_DRY_EVENT 0x000a
-#define SCTP_NOTIFICATIONS_STOPPED_EVENT 0x000b /* we don't send this */
-#define SCTP_ASSOC_RESET_EVENT 0x000c
-#define SCTP_STREAM_CHANGE_EVENT 0x000d
-
+#define SCTP_ADAPTION_INDICATION 0x0006
+#define SCTP_PARTIAL_DELIVERY_EVENT 0x0007
+#define SCTP_AUTHENTICATION_EVENT 0x0008
+#define SCTP_STREAM_RESET_EVENT 0x0009
+#define SCTP_SENDER_DRY_EVENT 0x000a
+#define SCTP_NOTIFICATIONS_STOPPED_EVENT 0x000b /* we don't send this */
+#define SCTP_ASSOC_RESET_EVENT 0x000c
+#define SCTP_STREAM_CHANGE_EVENT 0x000d
+#define SCTP_SEND_FAILED_EVENT 0x000e
/*
* socket option structs
*/
Modified: stable/9/sys/netinet/sctp_usrreq.c
==============================================================================
--- stable/9/sys/netinet/sctp_usrreq.c Wed May 9 14:12:08 2012 (r235171)
+++ stable/9/sys/netinet/sctp_usrreq.c Wed May 9 14:15:59 2012 (r235172)
@@ -2989,6 +2989,9 @@ flags_out:
case SCTP_STREAM_CHANGE_EVENT:
event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT;
break;
+ case SCTP_SEND_FAILED_EVENT:
+ event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT;
+ break;
default:
event_type = 0;
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
@@ -5412,6 +5415,9 @@ sctp_setopt(struct socket *so, int optna
case SCTP_STREAM_CHANGE_EVENT:
event_type = SCTP_PCB_FLAGS_STREAM_CHANGEEVNT;
break;
+ case SCTP_SEND_FAILED_EVENT:
+ event_type = SCTP_PCB_FLAGS_RECVNSENDFAILEVNT;
+ break;
default:
event_type = 0;
SCTP_LTRACE_ERR_RET(inp, NULL, NULL, SCTP_FROM_SCTP_USRREQ, EINVAL);
Modified: stable/9/sys/netinet/sctputil.c
==============================================================================
--- stable/9/sys/netinet/sctputil.c Wed May 9 14:12:08 2012 (r235171)
+++ stable/9/sys/netinet/sctputil.c Wed May 9 14:15:59 2012 (r235172)
@@ -2798,39 +2798,66 @@ sctp_notify_send_failed(struct sctp_tcb
{
struct mbuf *m_notify;
struct sctp_send_failed *ssf;
+ struct sctp_send_failed_event *ssfe;
struct sctp_queued_to_read *control;
int length;
if ((stcb == NULL) ||
- sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) {
+ (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
+ sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
/* event not enabled */
return;
}
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 0, M_DONTWAIT, 1, MT_DATA);
+ if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
+ length = sizeof(struct sctp_send_failed_event);
+ } else {
+ length = sizeof(struct sctp_send_failed);
+ }
+ m_notify = sctp_get_mbuf_for_msg(length, 0, M_DONTWAIT, 1, MT_DATA);
if (m_notify == NULL)
/* no space left */
return;
- length = sizeof(struct sctp_send_failed) + chk->send_size;
+ length += chk->send_size;
length -= sizeof(struct sctp_data_chunk);
SCTP_BUF_LEN(m_notify) = 0;
- ssf = mtod(m_notify, struct sctp_send_failed *);
- ssf->ssf_type = SCTP_SEND_FAILED;
- if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
- ssf->ssf_flags = SCTP_DATA_UNSENT;
- else
- ssf->ssf_flags = SCTP_DATA_SENT;
- ssf->ssf_length = length;
- ssf->ssf_error = error;
- /* not exactly what the user sent in, but should be close :) */
- bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
- ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
- ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
- ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
- ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
- ssf->ssf_info.sinfo_context = chk->rec.data.context;
- ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
- ssf->ssf_assoc_id = sctp_get_associd(stcb);
-
+ if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
+ ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+ ssfe->ssfe_type = SCTP_SEND_FAILED_EVENT;
+ if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
+ ssfe->ssfe_flags = SCTP_DATA_UNSENT;
+ else
+ ssfe->ssfe_flags = SCTP_DATA_SENT;
+ ssfe->ssfe_length = length;
+ ssfe->ssfe_error = error;
+ /* not exactly what the user sent in, but should be close :) */
+ bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
+ ssfe->ssfe_info.snd_sid = chk->rec.data.stream_number;
+ ssfe->ssfe_info.snd_flags = chk->rec.data.rcv_flags;
+ ssfe->ssfe_info.snd_ppid = chk->rec.data.payloadtype;
+ ssfe->ssfe_info.snd_context = chk->rec.data.context;
+ ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
+ ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
+ } else {
+ ssf = mtod(m_notify, struct sctp_send_failed *);
+ ssf->ssf_type = SCTP_SEND_FAILED;
+ if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
+ ssf->ssf_flags = SCTP_DATA_UNSENT;
+ else
+ ssf->ssf_flags = SCTP_DATA_SENT;
+ ssf->ssf_length = length;
+ ssf->ssf_error = error;
+ /* not exactly what the user sent in, but should be close :) */
+ bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
+ ssf->ssf_info.sinfo_stream = chk->rec.data.stream_number;
+ ssf->ssf_info.sinfo_ssn = chk->rec.data.stream_seq;
+ ssf->ssf_info.sinfo_flags = chk->rec.data.rcv_flags;
+ ssf->ssf_info.sinfo_ppid = chk->rec.data.payloadtype;
+ ssf->ssf_info.sinfo_context = chk->rec.data.context;
+ ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
+ ssf->ssf_assoc_id = sctp_get_associd(stcb);
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
+ }
if (chk->data) {
/*
* trim off the sctp chunk header(it should be there)
@@ -2842,7 +2869,6 @@ sctp_notify_send_failed(struct sctp_tcb
}
}
SCTP_BUF_NEXT(m_notify) = chk->data;
- SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
/* Steal off the mbuf */
chk->data = NULL;
/*
@@ -2882,43 +2908,75 @@ sctp_notify_send_failed2(struct sctp_tcb
{
struct mbuf *m_notify;
struct sctp_send_failed *ssf;
+ struct sctp_send_failed_event *ssfe;
struct sctp_queued_to_read *control;
int length;
if ((stcb == NULL) ||
- sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT)) {
+ (sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVSENDFAILEVNT) &&
+ sctp_stcb_is_feature_off(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT))) {
/* event not enabled */
return;
}
- length = sizeof(struct sctp_send_failed) + sp->length;
- m_notify = sctp_get_mbuf_for_msg(sizeof(struct sctp_send_failed), 0, M_DONTWAIT, 1, MT_DATA);
- if (m_notify == NULL)
+ if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
+ length = sizeof(struct sctp_send_failed_event);
+ } else {
+ length = sizeof(struct sctp_send_failed);
+ }
+ m_notify = sctp_get_mbuf_for_msg(length, 0, M_DONTWAIT, 1, MT_DATA);
+ if (m_notify == NULL) {
/* no space left */
return;
+ }
+ length += sp->length;
SCTP_BUF_LEN(m_notify) = 0;
- ssf = mtod(m_notify, struct sctp_send_failed *);
- ssf->ssf_type = SCTP_SEND_FAILED;
- if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
- ssf->ssf_flags = SCTP_DATA_UNSENT;
- else
- ssf->ssf_flags = SCTP_DATA_SENT;
- ssf->ssf_length = length;
- ssf->ssf_error = error;
- /* not exactly what the user sent in, but should be close :) */
- bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
- ssf->ssf_info.sinfo_stream = sp->stream;
- ssf->ssf_info.sinfo_ssn = sp->strseq;
- if (sp->some_taken) {
- ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG;
+ if (sctp_stcb_is_feature_on(stcb->sctp_ep, stcb, SCTP_PCB_FLAGS_RECVNSENDFAILEVNT)) {
+ ssfe = mtod(m_notify, struct sctp_send_failed_event *);
+ ssfe->ssfe_type = SCTP_SEND_FAILED;
+ if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
+ ssfe->ssfe_flags = SCTP_DATA_UNSENT;
+ else
+ ssfe->ssfe_flags = SCTP_DATA_SENT;
+ ssfe->ssfe_length = length;
+ ssfe->ssfe_error = error;
+ /* not exactly what the user sent in, but should be close :) */
+ bzero(&ssfe->ssfe_info, sizeof(ssfe->ssfe_info));
+ ssfe->ssfe_info.snd_sid = sp->stream;
+ if (sp->some_taken) {
+ ssfe->ssfe_info.snd_flags = SCTP_DATA_LAST_FRAG;
+ } else {
+ ssfe->ssfe_info.snd_flags = SCTP_DATA_NOT_FRAG;
+ }
+ ssfe->ssfe_info.snd_ppid = sp->ppid;
+ ssfe->ssfe_info.snd_context = sp->context;
+ ssfe->ssfe_info.snd_assoc_id = sctp_get_associd(stcb);
+ ssfe->ssfe_assoc_id = sctp_get_associd(stcb);
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed_event);
} else {
- ssf->ssf_info.sinfo_flags = SCTP_DATA_NOT_FRAG;
+ ssf = mtod(m_notify, struct sctp_send_failed *);
+ ssf->ssf_type = SCTP_SEND_FAILED;
+ if (error == SCTP_NOTIFY_DATAGRAM_UNSENT)
+ ssf->ssf_flags = SCTP_DATA_UNSENT;
+ else
+ ssf->ssf_flags = SCTP_DATA_SENT;
+ ssf->ssf_length = length;
+ ssf->ssf_error = error;
+ /* not exactly what the user sent in, but should be close :) */
+ bzero(&ssf->ssf_info, sizeof(ssf->ssf_info));
+ ssf->ssf_info.sinfo_stream = sp->stream;
+ ssf->ssf_info.sinfo_ssn = sp->strseq;
+ if (sp->some_taken) {
+ ssf->ssf_info.sinfo_flags = SCTP_DATA_LAST_FRAG;
+ } else {
+ ssf->ssf_info.sinfo_flags = SCTP_DATA_NOT_FRAG;
+ }
+ ssf->ssf_info.sinfo_ppid = sp->ppid;
+ ssf->ssf_info.sinfo_context = sp->context;
+ ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
+ ssf->ssf_assoc_id = sctp_get_associd(stcb);
+ SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
}
- ssf->ssf_info.sinfo_ppid = sp->ppid;
- ssf->ssf_info.sinfo_context = sp->context;
- ssf->ssf_info.sinfo_assoc_id = sctp_get_associd(stcb);
- ssf->ssf_assoc_id = sctp_get_associd(stcb);
SCTP_BUF_NEXT(m_notify) = sp->data;
- SCTP_BUF_LEN(m_notify) = sizeof(struct sctp_send_failed);
/* Steal off the mbuf */
sp->data = NULL;
More information about the svn-src-stable-9
mailing list