diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index 8f9aaa8c75c131253d4050bce16c2ee778b757a7..53effec3dc0fcf27f671b3769d5e456f6aa1e058 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -336,6 +336,13 @@ spc_aaddr                       return SPC_AADDR;
 spc_state                       return SPC_STATE;
 spc_error                       return SPC_ERROR;
 spc_assoc_id                    return SPC_ASSOC_ID;
+ssf_type                        return SSF_TYPE;
+ssf_length                      return SSF_LENGTH;
+ssf_flags                       return SSF_FLAGS;
+ssf_error                       return SSF_ERROR;
+ssf_info                        return SSF_INFO;
+ssf_assoc_id                    return SSF_ASSOC_ID;
+ssf_data                        return SSF_DATA;
 CHUNK				return CHUNK;
 DATA				return DATA;
 INIT				return INIT;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index e3cb12a15a24744f94d0d620f50a9b15926b55e4..320d694c47485ad82b079d68c0111fadfbaa5c4f 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -560,6 +560,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SRE_TYPE SRE_FLAGS SRE_LENGTH SRE_ERROR SRE_ASSOC_ID SRE_DATA PDAPI_ASSOC_ID
 %token <reserved> PDAPI_TYPE PDAPI_FLAGS PDAPI_LENGTH PDAPI_INDICATION PDAPI_STREAM PDAPI_SEQ
 %token <reserved> SPC_TYPE SPC_FLAGS SPC_LENGTH SPC_AADDR SPC_STATE SPC_ERROR SPC_ASSOC_ID
+%token <reserved> SSF_TYPE SSF_LENGTH SSF_FLAGS SSF_ERROR SSF_INFO SSF_ASSOC_ID SSF_DATA
 %token <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -625,6 +626,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sctp_remote_error sre_type sre_flags sre_length sre_error sre_assoc_id sre_data
 %type <expression> sctp_pdapi_event pdapi_type pdapi_flags pdapi_length pdapi_indication pdapi_stream pdapi_seq pdapi_assoc_id
 %type <expression> sctp_paddr_change spc_type spc_flags spc_length spc_aaddr spc_error spc_state spc_assoc_id
+%type <expression> sctp_send_failed ssf_type ssf_length ssf_flags ssf_error ssf_info ssf_assoc_id ssf_data
 %type <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
 %type <chunk_list_item> sctp_chunk_spec
@@ -2602,6 +2604,7 @@ data
 | sctp_assoc_change         { $$ = $1; }
 | sctp_paddr_change         { $$ = $1; }
 | sctp_remote_error         { $$ = $1; }
+| sctp_send_failed          { $$ = $1; }
 | sctp_shutdown_event       { $$ = $1; }
 | sctp_pdapi_event          { $$ = $1; }
 | sctp_sender_dry_event     { $$ = $1; }
@@ -4166,6 +4169,91 @@ sctp_paddr_change
 	$$->value.sctp_paddr_change->spc_assoc_id = $14;
 }
 ;
+ssf_type
+: SSF_TYPE '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("ssf_type out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| SSF_TYPE '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| SSF_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssf_length
+: SSF_LENGTH '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("ssf_length out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SSF_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssf_flags
+: SSF_FLAGS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("ssf_flags out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| SSF_FLAGS '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| SSF_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssf_error
+: SSF_ERROR '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("ssf_error out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SSF_ERROR '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| SSF_ERROR '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssf_info
+: SSF_INFO '=' sctp_sndrcvinfo { $$ = $3; }
+| SSF_INFO '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssf_assoc_id
+: SSF_ASSOC_ID '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("ssf_assoc_id out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SSF_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssf_data
+: SSF_DATA '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+| SSF_DATA '=' array { $$ = $3; }
+;
+
+sctp_send_failed
+: '{' ssf_type ',' ssf_flags ',' ssf_length ',' ssf_error ',' ssf_info ',' ssf_assoc_id ',' ssf_data '}' {
+	$$ = new_expression(EXPR_SCTP_SEND_FAILED);
+	$$->value.sctp_send_failed = calloc(1, sizeof(struct sctp_send_failed_expr));
+	$$->value.sctp_send_failed->ssf_type = $2;
+	$$->value.sctp_send_failed->ssf_flags = $4;
+	$$->value.sctp_send_failed->ssf_length = $6;
+	$$->value.sctp_send_failed->ssf_error = $8;
+	$$->value.sctp_send_failed->ssf_info = $10;
+	$$->value.sctp_send_failed->ssf_assoc_id = $12;
+	$$->value.sctp_send_failed->ssf_data = $14;
+}
+;
 
 opt_errno
 :                   { $$ = NULL; }
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 7a0a66134718838cc8f72e79ed8027e7fca14d64..57013b8292a0d5ffceb23989b15e7775f0747a62 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -571,6 +571,7 @@ static int iovec_new(struct expression *expression,
 		       iov_expr->iov_base->type == EXPR_SCTP_ASSOC_CHANGE ||
 		       iov_expr->iov_base->type == EXPR_SCTP_PADDR_CHANGE ||
 		       iov_expr->iov_base->type == EXPR_SCTP_REMOTE_ERROR ||
+		       iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED ||
 		       iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT ||
 		       iov_expr->iov_base->type == EXPR_SCTP_PDAPI_EVENT ||
 		       iov_expr->iov_base->type == EXPR_SCTP_AUTHKEY_EVENT ||
@@ -3477,6 +3478,37 @@ static int check_sctp_remote_error(struct sctp_remote_error_expr *expr,
 }
 #endif
 
+#if defined(__FreeBSD__) || defined(linux)
+static int check_sctp_send_failed(struct sctp_send_failed_expr *expr,
+				  struct sctp_send_failed *sctp_event,
+				  char **error) {
+
+	if (check_u16_expr(expr->ssf_type, sctp_event->ssf_type,
+			   "sctp_send_failed.ssf_type", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->ssf_flags, sctp_event->ssf_flags,
+			   "sctp_send_failed.ssf_flags", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->ssf_length, sctp_event->ssf_length,
+			   "sctp_send_failed.ssf_length", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->ssf_error, sctp_event->ssf_error,
+			   "sctp_send_failed.ssf_error", error))
+		return STATUS_ERR;
+	if (check_sctp_sndrcvinfo(expr->ssf_info->value.sctp_sndrcvinfo,
+				  &sctp_event->ssf_info, error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->ssf_assoc_id, sctp_event->ssf_assoc_id,
+			   "sctp_send_failed.ssf_assoc_id", error))
+		return STATUS_ERR;
+	if (check_u8array_expr(expr->ssf_data, sctp_event->ssf_data, sctp_event->ssf_length - sizeof(struct sctp_send_failed),
+			       "sctp_send_failed.ssf_data", error))
+			return STATUS_ERR;
+
+	return STATUS_OK;
+}
+#endif
+
 #if defined(__FreeBSD__) || defined(linux)
 static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr,
 				     struct sctp_shutdown_event *sctp_event,
@@ -3645,6 +3677,12 @@ static int check_sctp_notification(struct iovec *iov,
 						    error))
 				return STATUS_ERR;
 			break;
+		case EXPR_SCTP_SEND_FAILED:
+			if (check_sctp_send_failed(script_iov_base->value.sctp_send_failed,
+						   (struct sctp_send_failed *) iov[i].iov_base,
+						   error))
+				return STATUS_ERR;
+			break;
 		case EXPR_SCTP_SHUTDOWN_EVENT:
 			if (check_sctp_shutdown_event(script_iov_base->value.sctp_shutdown_event,
 						      (struct sctp_shutdown_event *) iov[i].iov_base,
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 35979f33210cdd52722d924542fad048a3080ad4..53b30e8582da5b85d0c1997b24412fd5b9b93efe 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -89,6 +89,7 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_SCTP_ASSOC_CHANGE,    "sctp_assoc_change"},
 	{ EXPR_SCTP_PADDR_CHANGE,    "sctp_paddr_change"},
 	{ EXPR_SCTP_REMOTE_ERROR,    "sctp_remote_error"},
+	{ EXPR_SCTP_SEND_FAILED,     "sctp_send_failed"},
 	{ EXPR_SCTP_SHUTDOWN_EVENT,  "sctp_shutdown_event"},
 	{ EXPR_SCTP_PDAPI_EVENT,     "sctp_pdapi_event"},
 	{ EXPR_SCTP_AUTHKEY_EVENT,   "sctp_authkey_event"},
@@ -465,6 +466,15 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_remote_error->sre_assoc_id);
 		free_expression(expression->value.sctp_remote_error->sre_data);
 		break;
+	case EXPR_SCTP_SEND_FAILED:
+		free_expression(expression->value.sctp_send_failed->ssf_type);
+		free_expression(expression->value.sctp_send_failed->ssf_flags);
+		free_expression(expression->value.sctp_send_failed->ssf_length);
+		free_expression(expression->value.sctp_send_failed->ssf_error);
+		free_expression(expression->value.sctp_send_failed->ssf_info);
+		free_expression(expression->value.sctp_send_failed->ssf_assoc_id);
+		free_expression(expression->value.sctp_send_failed->ssf_data);
+		break;
 	case EXPR_SCTP_SHUTDOWN_EVENT:
 		free_expression(expression->value.sctp_shutdown_event->sse_type);
 		free_expression(expression->value.sctp_shutdown_event->sse_flags);
@@ -1560,6 +1570,54 @@ static int evaluate_sctp_remote_error_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+static int evaluate_sctp_send_failed_expression(struct expression *in,
+						struct expression *out,
+						char **error)
+{
+	struct sctp_send_failed_expr *in_event;
+	struct sctp_send_failed_expr *out_event;
+
+	assert(in->type == EXPR_SCTP_SEND_FAILED);
+	assert(in->value.sctp_send_failed);
+	assert(out->type == EXPR_SCTP_SEND_FAILED);
+
+	out->value.sctp_send_failed = calloc(1, sizeof(struct sctp_send_failed_expr));
+
+	in_event = in->value.sctp_send_failed;
+	out_event = out->value.sctp_send_failed;
+
+	if (evaluate(in_event->ssf_type,
+		     &out_event->ssf_type,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssf_flags,
+		     &out_event->ssf_flags,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssf_length,
+		     &out_event->ssf_length,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssf_error,
+		     &out_event->ssf_error,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssf_info,
+		     &out_event->ssf_info,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssf_assoc_id,
+		     &out_event->ssf_assoc_id,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssf_data,
+		     &out_event->ssf_data,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
 static int evaluate_sctp_shutdown_event_expression(struct expression *in,
 						   struct expression *out,
 						   char **error)
@@ -1862,6 +1920,9 @@ static int evaluate(struct expression *in,
 	case EXPR_SCTP_REMOTE_ERROR:
 		result = evaluate_sctp_remote_error_expression(in, out, error);
 		break;
+	case EXPR_SCTP_SEND_FAILED:
+		result = evaluate_sctp_send_failed_expression(in, out, error);
+		break;
 	case EXPR_SCTP_SHUTDOWN_EVENT:
 		result = evaluate_sctp_shutdown_event_expression(in, out, error);
 		break;
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index f6f444dff3e042bd6283f44c24fde2b535a515a2..dc755dbb8ca5dee844e248557f589dd7d9a5888c 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -69,6 +69,7 @@ enum expression_t {
 	EXPR_SCTP_ASSOC_CHANGE,   /* expression tree for sctp_assoc_change_event */
 	EXPR_SCTP_PADDR_CHANGE,   /* expression tree for sctp_peer_addr_change */
 	EXPR_SCTP_REMOTE_ERROR,   /* expression tree for sctp_remote_error_event */
+	EXPR_SCTP_SEND_FAILED,     /* expression tree for sctp_send_failed event (DEPRICATED) */
 	EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */
 	EXPR_SCTP_PDAPI_EVENT,    /* expression tree for sctp_partial_delivery_event */
 	EXPR_SCTP_AUTHKEY_EVENT,  /* expression tree for sctp_authentication_event */
@@ -116,6 +117,7 @@ struct expression {
 		struct sctp_assoc_change_expr *sctp_assoc_change;
 		struct sctp_paddr_change_expr *sctp_paddr_change;
 		struct sctp_remote_error_expr *sctp_remote_error;
+		struct sctp_send_failed_expr *sctp_send_failed;
 		struct sctp_shutdown_event_expr *sctp_shutdown_event;
 		struct sctp_pdapi_event_expr *sctp_pdapi_event;
 		struct sctp_authkey_event_expr *sctp_authkey_event;
@@ -364,6 +366,18 @@ struct sctp_remote_error_expr {
 	struct expression *sre_assoc_id;
 	struct expression *sre_data;
 };
+
+/* Parse tree for sctp_shutdown_event for notifications. */
+struct sctp_send_failed_expr {
+	struct expression *ssf_type;
+	struct expression *ssf_flags;
+	struct expression *ssf_length;
+	struct expression *ssf_error;
+	struct expression *ssf_info;
+	struct expression *ssf_assoc_id;
+	struct expression *ssf_data;
+};
+
 /* Parse tree for sctp_shutdown_event for notifications. */
 struct sctp_shutdown_event_expr {
 	struct expression *sse_type;
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_send_failed.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_send_failed.pkt
new file mode 100644
index 0000000000000000000000000000000000000000..6a55b3dc6db8f738d6f1dc25008c0547089ca008
--- /dev/null
+++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_send_failed.pkt
@@ -0,0 +1,30 @@
++0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
++0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
++0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
+// Check the handshake with an empty(!) cookie
++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
++0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=1, ...]
++0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=1, is=1, tsn=1, STATE_COOKIE[len=4, val=...]]
++0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...]
++0.1 < sctp: COOKIE_ACK[flgs=0]
++0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
+
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address=..., spp_hbinterval=0, spp_pathmaxrxt=100, spp_pathmtu=1468, spp_flags=SPP_HB_DISABLE, 
+spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0
+
+//test for SEND_FAILED_EVENT
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SEND_FAILED, se_on=1}, 8) = 0
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=150, srto_min=50}, 16) = 0
++0.0 write(3, ..., 1000) = 1000
++0.0 > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+*    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
++1.0 sctp_recvv(3, [{iov_base={ssf_type=SCTP_SEND_FAILED, ssf_flags=SCTP_DATA_SENT, ssf_length=1144, ssf_error=0,
+ssf_info={sinfo_stream=0, sinfo_ssn=0, sinfo_flags=3, sinfo_ppid=htonl(0), sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=0, sinfo_cumtsn=0},
+ssf_assoc_id=3, ssf_data=...}, iov_len=1000}],
+1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION]) = 1000