diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index cc958793bbee6e63a645444cdec2d2300a85e9e2..dcfc8bb9a6c870e6cc7e94bdb9568191dd1696bf 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -275,6 +275,13 @@ sendv_flags			return SENDV_FLAGS;
 sendv_sndinfo			return SENDV_SNDINFO;
 sendv_prinfo			return SENDV_PRINFO;
 sendv_authinfo			return SENDV_AUTHINFO;
+ssfe_type                       return SSFE_TYPE;
+ssfe_flags                      return SSFE_FLAGS;
+ssfe_length                     return SSFE_LENGTH;
+ssfe_error                      return SSFE_ERROR;
+ssfe_info                       return SSFE_INFO;
+ssfe_assoc_id                   return SSFE_ASSOC_ID;
+ssfe_data                       return SSFE_DATA;
 rcv_sid                         return RCV_SID;
 rcv_ssn                         return RCV_SSN;
 rcv_flags                       return RCV_FLAGS;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 2f413edc0b8fc5f310c5244117b30deae8432d22..443cbd589a6f1ae2120c074f04d36fac895add8a 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -553,6 +553,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> _SCTP_SEND_FAILURE_EVENT_ _SCTP_PEER_ERROR_EVENT_ _SCTP_SHUTDOWN_EVENT_
 %token <reserved> _SCTP_PARTIAL_DELIVERY_EVENT_ _SCTP_ADAPTATION_LAYER_EVENT_
 %token <reserved> _SCTP_AUTHENTICATION_EVENT_ _SCTP_SENDER_DRY_EVENT_
+%token <reserved> SSFE_TYPE SSFE_FLAGS SSFE_LENGTH SSFE_ERROR SSFE_INFO SSFE_ASSOC_ID SSFE_DATA
 %token <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -611,6 +612,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sctp_shutdown_event sse_type sse_flags sse_length
 %type <expression> sctp_sender_dry_event sender_dry_type sender_dry_flags sender_dry_length sender_dry_assoc_id
 %type <expression> sctp_event_subscribe
+%type <expression> sctp_send_failed_event ssfe_type ssfe_flags ssfe_length ssfe_error ssfe_assoc_id
 %type <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
 %type <chunk_list_item> sctp_chunk_spec
@@ -2584,9 +2586,10 @@ sockaddr
 ;
 
 data
-: ELLIPSIS { new_expression(EXPR_ELLIPSIS); }
-| sctp_shutdown_event { $$ = $1; }
-| sctp_sender_dry_event { $$ = $1; }
+: ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+| sctp_shutdown_event        { $$ = $1; }
+| sctp_sender_dry_event      { $$ = $1; }
+| sctp_send_failed_event     { $$ = $1; }
 ;
 
 msghdr
@@ -3626,6 +3629,76 @@ sctp_sender_dry_event
 	$$->value.sctp_sender_dry_event->sender_dry_assoc_id = $8;
 }
 ;
+ssfe_type
+: SSFE_TYPE '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("ssfe_type out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| SSFE_TYPE '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| SSFE_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssfe_flags
+: SSFE_FLAGS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("ssfe_flags out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| SSFE_FLAGS '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| SSFE_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssfe_length
+: SSFE_LENGTH '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("ssfe_length out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SSFE_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssfe_error
+: SSFE_ERROR '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("ssfe_error out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SSFE_ERROR '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+ssfe_assoc_id
+: SSFE_ASSOC_ID '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("ssfe_assoc_id out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SSFE_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sctp_send_failed_event
+: '{' ssfe_type ',' ssfe_flags ',' ssfe_length ',' ssfe_error ',' SSFE_INFO '=' sctp_sndinfo ',' ssfe_assoc_id ',' SSFE_DATA '=' ELLIPSIS '}' {
+	$$ = new_expression(EXPR_SCTP_SEND_FAILED_EVENT);
+	$$->value.sctp_send_failed_event = calloc(1, sizeof(struct sctp_send_failed_event_expr));
+	$$->value.sctp_send_failed_event->ssfe_type = $2;
+	$$->value.sctp_send_failed_event->ssfe_flags = $4;
+	$$->value.sctp_send_failed_event->ssfe_length = $6;
+	$$->value.sctp_send_failed_event->ssfe_error = $8;
+	$$->value.sctp_send_failed_event->ssfe_info = $12;
+	$$->value.sctp_send_failed_event->ssfe_assoc_id = $14;
+	$$->value.sctp_send_failed_event->ssfe_data = new_expression(EXPR_ELLIPSIS);
+};
 
 opt_errno
 :                   { $$ = NULL; }
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index cb55f62bd17cd35f328f33432930b0b6a8c243e1..198cfd2538119d49f4fd99be205731a65d6e1984 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -461,7 +461,8 @@ static int iovec_new(struct expression *expression,
 
 		assert(iov_expr->iov_base->type == EXPR_ELLIPSIS ||
 		       iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT ||
-		       iov_expr->iov_base->type == EXPR_SCTP_SENDER_DRY_EVENT);
+		       iov_expr->iov_base->type == EXPR_SCTP_SENDER_DRY_EVENT ||
+		       iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED_EVENT);
 		assert(iov_expr->iov_len->type == EXPR_INTEGER);
 
 		len = iov_expr->iov_len->value.num;
@@ -3727,6 +3728,37 @@ static int syscall_sctp_sendv(struct state *state, struct syscall_spec *syscall,
 #endif
 }
 
+int check_u16_expr(struct expression *expr, u16 value, char *val_name, char **error) {
+	if (expr->type != EXPR_ELLIPSIS) {
+		u16 script_val;
+		 
+		if (get_u16(expr, &script_val, error)) {
+			return STATUS_ERR;
+		}
+		if (script_val != value) {
+			asprintf(error, "%s: expected: %hu actual: %hu", val_name, script_val, value);
+			return STATUS_ERR;
+		}
+	}
+	return STATUS_OK;
+}
+
+int check_u32_expr(struct expression *expr, u16 value, char *val_name, char **error) {
+	if (expr->type != EXPR_ELLIPSIS) {
+		u32 script_val;
+		 
+		if (get_u32(expr, &script_val, error)) {
+			return STATUS_ERR;
+		}
+		if (script_val != value) {
+			asprintf(error, "%s: expected: %u actual: %u", val_name, script_val, value);
+			return STATUS_ERR;
+		}
+	}
+	return STATUS_OK;
+}
+
+
 #if defined(__FreeBSD__)
 static int check_sctp_rcvinfo(struct sctp_rcvinfo_expr *expr,
 			      struct sctp_rcvinfo *sctp_rcvinfo,
@@ -3825,30 +3857,10 @@ static int check_sctp_nxtinfo(struct sctp_nxtinfo_expr *expr,
 			      struct sctp_nxtinfo *sctp_nxtinfo,
 			      char **error)
 {
-	if (expr->nxt_sid->type != EXPR_ELLIPSIS) {
-		u16 nxt_sid;
-
-		if (get_u16(expr->nxt_sid, &nxt_sid, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_nxtinfo->nxt_sid != nxt_sid) {
-			asprintf(error, "sctp_nxtinfo.nxt_sid: expected: %hu actual: %hu",
-				 nxt_sid, sctp_nxtinfo->nxt_sid);
-			return STATUS_ERR;
-		}
-	}
-	if (expr->nxt_flags->type != EXPR_ELLIPSIS) {
-		u16 nxt_flags;
-
-		if (get_u16(expr->nxt_flags, &nxt_flags, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_nxtinfo->nxt_flags != nxt_flags) {
-			asprintf(error, "sctp_nxtinfo.nxt_flags: expected: %hu actual: %hu",
-				 nxt_flags, sctp_nxtinfo->nxt_flags);
-			return STATUS_ERR;
-		}
-	}
+	if (check_u16_expr(expr->nxt_sid, sctp_nxtinfo->nxt_sid, "sctp_nxtinfo.nxt_sid", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->nxt_flags, sctp_nxtinfo->nxt_flags, "sctp_nxtinfo.nxt_flags", error))
+		return STATUS_ERR;
 	if (expr->nxt_ppid->type != EXPR_ELLIPSIS) {
 		u32 nxt_ppid;
 
@@ -3861,18 +3873,9 @@ static int check_sctp_nxtinfo(struct sctp_nxtinfo_expr *expr,
 			return STATUS_ERR;
 		}
 	}
-	if (expr->nxt_length->type != EXPR_ELLIPSIS) {
-		u32 nxt_length;
+	if (check_u32_expr(expr->nxt_length, sctp_nxtinfo->nxt_length, "sctp_nxtinfo.nxt_length", error))
+		return STATUS_ERR;
 
-		if (get_u32(expr->nxt_length, &nxt_length, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_nxtinfo->nxt_length != nxt_length) {
-			asprintf(error, "sctp_nxtinfo.nxt_length: expected: %u actual: %u",
-				 nxt_length, sctp_nxtinfo->nxt_length);
-			return STATUS_ERR;
-		}
-	}
 	return STATUS_OK;
 }
 #endif
@@ -3881,96 +3884,65 @@ static int check_sctp_nxtinfo(struct sctp_nxtinfo_expr *expr,
 static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr,
 				     struct sctp_shutdown_event *sctp_event,
 				     char **error) {
-	if (expr->sse_type->type != EXPR_ELLIPSIS) {
-		u16 sse_type;
-		 
-		if (get_u16(expr->sse_type, &sse_type, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_event->sse_type != sse_type) {
-			asprintf(error, "sctp_shutdown_event.sse_type: expected: %hu actual: %hu",
-				 sse_type, sctp_event->sse_type);
-			return STATUS_ERR;
-		}
-	}
-	if (expr->sse_flags->type != EXPR_ELLIPSIS) {
-		u16 sse_flags;
-		 
-		if (get_u16(expr->sse_flags, &sse_flags, error)) {
-			return STATUS_ERR;		}
-		if (sctp_event->sse_flags != sse_flags) {
-			asprintf(error, "sctp_shutdown_event.sse_flags: expected: %hu actual: %hu",
-				 sse_flags, sctp_event->sse_flags);
-			return STATUS_ERR;
-		}
-	}
-	if (expr->sse_length->type != EXPR_ELLIPSIS) {
-		u32 sse_length;
+	if (check_u16_expr(expr->sse_type, sctp_event->sse_type,
+			   "sctp_shutdown_event.sse_type", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->sse_flags, sctp_event->sse_flags,
+			   "sctp_shutdown_event.sse_flags", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->sse_length, sctp_event->sse_length,
+			   "sctp_shutdown_event.sse_length", error))
+		return STATUS_ERR;
 
-		if (get_u32(expr->sse_length, &sse_length, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_event->sse_length != sse_length) {
-			asprintf(error, "sctp_shutdown_event.sse_length: expected: %u actual: %u",
-				 sse_length, sctp_event->sse_length);
-			return STATUS_ERR;
-		}
-	}
 	return STATUS_OK;
 }
 #endif
+
 #ifdef __FreeBSD__
 static int check_sctp_sender_dry_event(struct sctp_sender_dry_event_expr *expr,
 				       struct sctp_sender_dry_event *sctp_event,
 				       char **error) {
-	if (expr->sender_dry_type->type != EXPR_ELLIPSIS) {
-		u16 sender_dry_type;
-		 
-		if (get_u16(expr->sender_dry_type, &sender_dry_type, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_event->sender_dry_type != sender_dry_type) {
-			asprintf(error, "sctp_sender_dry_event.sender_dry_type: expected: %hu actual: %hu",
-				 sender_dry_type, sctp_event->sender_dry_type);
-			return STATUS_ERR;
-		}
-	}
-	if (expr->sender_dry_flags->type != EXPR_ELLIPSIS) {
-		u16 sender_dry_flags;
-		 
-		if (get_u16(expr->sender_dry_flags, &sender_dry_flags, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_event->sender_dry_flags != sender_dry_flags) {
-			asprintf(error, "sctp_sender_dry_event.sender_dry_flags: expected: %hu actual: %hu",
-				 sender_dry_flags, sctp_event->sender_dry_flags);
-			return STATUS_ERR;
-		}
-	}
-	if (expr->sender_dry_type->type != EXPR_ELLIPSIS) {
-		u32 sender_dry_length;
-		 
-		if (get_u32(expr->sender_dry_length, &sender_dry_length, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_event->sender_dry_length != sender_dry_length) {
-			asprintf(error, "sctp_sender_dry_event.sender_dry_length: expected: %u actual: %u",
-				 sender_dry_length, sctp_event->sender_dry_length);
-			return STATUS_ERR;
-		}
-	}
-	if (expr->sender_dry_assoc_id->type != EXPR_ELLIPSIS) {
-		u32 sender_dry_assoc_id;
-		 
-		if (get_u32(expr->sender_dry_assoc_id, &sender_dry_assoc_id, error)) {
-			return STATUS_ERR;
-		}
-		if (sctp_event->sender_dry_assoc_id != sender_dry_assoc_id) {
-			asprintf(error, "sctp_sender_dry_event.sender_dry_assoc_id: expected: %u actual: %u",
-				 sender_dry_assoc_id, sctp_event->sender_dry_assoc_id);
+
+	if (check_u16_expr(expr->sender_dry_type, sctp_event->sender_dry_type,
+			   "sctp_sender_dry.sender_dry_type", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->sender_dry_flags, sctp_event->sender_dry_flags,
+			   "sctp_sender_dry.sender_dry_flags", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->sender_dry_length, sctp_event->sender_dry_length,
+			   "sctp_sender_dry.sender_dry_length", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->sender_dry_assoc_id, sctp_event->sender_dry_assoc_id,
+			   "sctp_sender_dry.sender_dry_assoc_id", error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+#endif
+
+#ifdef __FreeBSD__
+static int check_sctp_send_failed_event(struct sctp_send_failed_event_expr *expr,
+				       struct sctp_send_failed_event *sctp_event,
+				       char **error) {
+	if (check_u16_expr(expr->ssfe_type, sctp_event->ssfe_type,
+			   "sctp_send_failed.ssfe_type", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->ssfe_flags, sctp_event->ssfe_flags,
+			   "sctp_send_failed.ssfe_flags", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->ssfe_length, sctp_event->ssfe_length,
+			   "sctp_send_failed.ssfe_length", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->ssfe_error, sctp_event->ssfe_error,
+			   "sctp_send_failed.ssfe_error", error))
+		return STATUS_ERR;
+	if (expr->ssfe_info->type != EXPR_ELLIPSIS) {
+		if (check_sctp_sndinfo(expr->ssfe_info->value.sctp_sndinfo, &sctp_event->ssfe_info, error))
 			return STATUS_ERR;
-		}
 	}
+	if (check_u32_expr(expr->ssfe_assoc_id, sctp_event->ssfe_assoc_id,
+			   "sctp_send_failed.ssfe_assoc_id", error))
+		return STATUS_ERR;
 
 	return STATUS_OK;
 }
@@ -4006,6 +3978,12 @@ static int check_sctp_notification(struct iovec *iov,
 						       error))
 				return STATUS_ERR;
 			break;
+		case EXPR_SCTP_SEND_FAILED_EVENT:
+			if (check_sctp_send_failed_event(script_iov_base->value.sctp_send_failed_event,
+						        (struct sctp_send_failed_event *) iov->iov_base,
+						        error))
+				return STATUS_ERR;
+			break;
 		case EXPR_ELLIPSIS:
 			break;
 		default:
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index d81e4e5b992944c68c32cf08db96ee094222c5d3..4e27b63b942809ddce56cb83ec7784549925ae1f 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -88,6 +88,7 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_SCTP_RECVV_RN,        "sctp_recvv_rn "  },
 	{ EXPR_SCTP_SHUTDOWN_EVENT,  "sctp_shutdown_event"},
 	{ EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"},
+	{ EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"},
 	{ NUM_EXPR_TYPES,            NULL}
 };
 
@@ -442,6 +443,15 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_sender_dry_event->sender_dry_length);
 		free_expression(expression->value.sctp_sender_dry_event->sender_dry_assoc_id);
 		break;
+	case EXPR_SCTP_SEND_FAILED_EVENT:
+		free_expression(expression->value.sctp_send_failed_event->ssfe_type);
+		free_expression(expression->value.sctp_send_failed_event->ssfe_flags);
+		free_expression(expression->value.sctp_send_failed_event->ssfe_length);
+		free_expression(expression->value.sctp_send_failed_event->ssfe_error);
+		free_expression(expression->value.sctp_send_failed_event->ssfe_info);
+		free_expression(expression->value.sctp_send_failed_event->ssfe_assoc_id);
+		free_expression(expression->value.sctp_send_failed_event->ssfe_data);
+		break;
 	case EXPR_WORD:
 		assert(expression->value.string);
 		free(expression->value.string);
@@ -564,7 +574,6 @@ static int evaluate_iovec_expression(struct expression *in,
 
 	in_iov = in->value.iovec;
 	out_iov = out->value.iovec;
-
 	if (evaluate(in_iov->iov_base,		&out_iov->iov_base,	error))
 		return STATUS_ERR;
 	if (evaluate(in_iov->iov_len,		&out_iov->iov_len,	error))
@@ -1421,6 +1430,54 @@ static int evaluate_sctp_sender_dry_event_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+static int evaluate_sctp_send_failed_event_expression(struct expression *in,
+						      struct expression *out,
+						      char **error)
+{
+	struct sctp_send_failed_event_expr *in_event;
+	struct sctp_send_failed_event_expr *out_event;
+
+	assert(in->type == EXPR_SCTP_SEND_FAILED_EVENT);
+	assert(in->value.sctp_send_failed_event);
+	assert(out->type == EXPR_SCTP_SEND_FAILED_EVENT);
+
+	out->value.sctp_send_failed_event = calloc(1, sizeof(struct sctp_send_failed_event_expr));
+
+	in_event = in->value.sctp_send_failed_event;
+	out_event = out->value.sctp_send_failed_event;
+
+	if (evaluate(in_event->ssfe_type,
+		     &out_event->ssfe_type,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssfe_flags,
+		     &out_event->ssfe_flags,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssfe_length,
+		     &out_event->ssfe_length,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssfe_error,
+		     &out_event->ssfe_error,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssfe_info,
+		     &out_event->ssfe_info,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssfe_assoc_id,
+		     &out_event->ssfe_assoc_id,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->ssfe_data,
+		     &out_event->ssfe_data,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
 static int evaluate(struct expression *in,
 		    struct expression **out_ptr, char **error)
 {
@@ -1512,6 +1569,9 @@ static int evaluate(struct expression *in,
 	case EXPR_SCTP_SENDER_DRY_EVENT:
 		result = evaluate_sctp_sender_dry_event_expression(in, out, error);
 		break;
+	case EXPR_SCTP_SEND_FAILED_EVENT:
+		result = evaluate_sctp_send_failed_event_expression(in, out, error);
+		break;
 	case EXPR_WORD:
 		out->type = EXPR_INTEGER;
 		if (symbol_to_int(in->value.string,
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index fbcf3009cdb2b57fd4b28b860359005638fa742d..0f0763dc0b6295ff0e7dda089650f05eae75a9b4 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -68,6 +68,7 @@ enum expression_t {
 	EXPR_SCTP_RECVV_RN,       /* struct sctp_recvv_rn for syscall sctp_recvv */
 	EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */
 	EXPR_SCTP_SENDER_DRY_EVENT, /* expression tree for sctp_sender_dry_event */
+	EXPR_SCTP_SEND_FAILED_EVENT, /* expression tree for sctp_send_failed_event */
 	NUM_EXPR_TYPES,
 };
 /* Convert an expression type to a human-readable string */
@@ -109,6 +110,7 @@ struct expression {
 		struct sctp_recvv_rn_expr *sctp_recvv_rn;
 		struct sctp_shutdown_event_expr *sctp_shutdown_event;
 		struct sctp_sender_dry_event_expr *sctp_sender_dry_event;
+		struct sctp_send_failed_event_expr *sctp_send_failed_event;
 	} value;
 	const char *format;	/* the printf format for printing the value */
 };
@@ -326,7 +328,7 @@ struct sctp_shutdown_event_expr {
 	struct expression *sse_length;
 };
 
-/* Parse tree for sctp_shutdown_event for notifications. */
+/* Parse tree for sctp_sender_dry_event for notifications. */
 struct sctp_sender_dry_event_expr {
 	struct expression *sender_dry_type;
 	struct expression *sender_dry_flags;
@@ -334,6 +336,17 @@ struct sctp_sender_dry_event_expr {
 	struct expression *sender_dry_assoc_id;
 };
 
+/* Parse tree for sctp_send_failed_event for notifications. */
+struct sctp_send_failed_event_expr {
+	struct expression *ssfe_type;
+	struct expression *ssfe_flags;
+	struct expression *ssfe_length;
+	struct expression *ssfe_error;
+	struct expression *ssfe_info;
+	struct expression *ssfe_assoc_id;
+	struct expression *ssfe_data;
+};
+
 /* The errno-related info from strace to summarize a system call error */
 struct errno_spec {
 	const char *errno_macro;	/* errno symbol (C macro name) */
diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c
index 63c501f5939789880e159c2c3960aac22e2550f6..eef941bb2878ae2946b710a9dc88d6b1f791291e 100644
--- a/gtests/net/packetdrill/symbols_freebsd.c
+++ b/gtests/net/packetdrill/symbols_freebsd.c
@@ -170,6 +170,7 @@ struct int_symbol platform_symbols_table[] = {
 	{ SCTP_SEND_FAILED,                 "SCTP_SEND_FAILED"                },
 	{ SCTP_SHUTDOWN_EVENT,              "SCTP_SHUTDOWN_EVENT"             },
 	{ SCTP_SENDER_DRY_EVENT,            "SCTP_SENDER_DRY_EVENT"           },
+	{ SCTP_SEND_FAILED_EVENT,           "SCTP_SEND_FAILED_EVENT"          },
 	{ SCTP_ADAPTATION_INDICATION,       "SCTP_ADAPTATION_INDICATION"      }, 
 	{ SCTP_ADAPTION_INDICATION,         "SCTP_ADAPTION_INDICATION"        },
 	{ SCTP_PARTIAL_DELIVERY_EVENT,      "SCTP_PARTIAL_DELIVERY_EVENT"     },
@@ -203,6 +204,8 @@ struct int_symbol platform_symbols_table[] = {
 	{ SCTP_RECVV_RN,                    "SCTP_RECVV_RN"                   },
 	{ SCTP_RECVRCVINFO,                 "SCTP_RECVRCVINFO"                },
 	{ SCTP_RECVNXTINFO,                 "SCTP_RECVNXTINFO"                },
+	{ SCTP_DATA_SENT,                   "SCTP_DATA_SENT"                  },
+	{ SCTP_DATA_UNSENT,                 "SCTP_DATA_UNSENT"                },
 	/* /usr/include/netinet/tcp.h */
 	{ TCP_NODELAY,                      "TCP_NODELAY"                     },
 	{ TCP_MAXSEG,                       "TCP_MAXSEG"                      },
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt
index df4d613cf608fd9e3fff382cd06609dc75d907b5..56a49b96545da7667daf32d47cfff4795e72590b 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt
@@ -8,7 +8,7 @@
 +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
-//enable shutdown events
+//test for enable socketoptions with SCTP_EVENT and SCTP_EVENTS
 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0
 +0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0
 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=0}, 8) = 0
@@ -18,24 +18,43 @@
 sctp_peer_error_event=0, sctp_shutdown_event=1, sctp_partial_delivery_event=0, sctp_adaptation_layer_event=0, sctp_authentication_event=0,
 sctp_sender_dry_event=0}, 11) = 0
 +0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0
-+0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENTS, {sctp_data_io_event=1, sctp_association_event=1, sctp_address_event=0, sctp_send_failure_event=1,
+
+//Deactivate all EVENTS
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENTS, {sctp_data_io_event=0, sctp_association_event=0, sctp_address_event=0, sctp_send_failure_event=0,
 sctp_peer_error_event=0, sctp_shutdown_event=0, sctp_partial_delivery_event=0, sctp_adaptation_layer_event=0, sctp_authentication_event=0,
 sctp_sender_dry_event=0}, 11) = 0
 
+//test for SENDER_DRY_EVENT
 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SENDER_DRY_EVENT, se_on=1}, 8) = 0
-+0.0 sctp_recvv(3, [{iov_base={sender_dry_type=SCTP_SENDER_DRY_EVENT, sender_dry_flags=0, sender_dry_length=12, sender_dry_assoc_id=3}, iov_len=1000}], 1,
-..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 12
-
++0.0 sctp_recvv(3, [{iov_base={sender_dry_type=SCTP_SENDER_DRY_EVENT, sender_dry_flags=0, sender_dry_length=12, sender_dry_assoc_id=3}, iov_len=1000}],
+1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 12
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SENDER_DRY_EVENT, se_on=0}, 8) = 0
 
+//test for SEND_FAILED_EVENT
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SEND_FAILED_EVENT, 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={ssfe_type=SCTP_SEND_FAILED_EVENT, ssfe_flags=SCTP_DATA_SENT, ssfe_length=1032, ssfe_error=0,
+ssfe_info={snd_sid=0, snd_flags=3, snd_ppid=htonl(0), snd_context=0}, ssfe_assoc_id=3, ssfe_data=...}, iov_len=1000}],
+1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION]) = 1000
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SEND_FAILED_EVENT, se_on=0}, 8) = 0
 
-+0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=0}, [8]) = 0
-+0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0
+//+0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=0}, [8]) = 0
+//+0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0
 // Tear down the association
-+0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
-*    > sctp: SHUTDOWN_ACK[flgs=0]
-+0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0]
-+0.0 recvmsg(3, {msg_name(...)=..., 
-		 msg_iov(1)=[{iov_base={sse_type=SCTP_SHUTDOWN_EVENT, sse_flags=0, sse_length=12}, iov_len=1000}],
-		 msg_flags=MSG_NOTIFICATION|MSG_EOR}, 0) = 12
+//+0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0]
+//*    > sctp: SHUTDOWN_ACK[flgs=0]
+//+0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0]
+//+0.0 recvmsg(3, {msg_name(...)=..., 
+//		 msg_iov(1)=[{iov_base={sse_type=SCTP_SHUTDOWN_EVENT, sse_flags=0, sse_length=12}, iov_len=1000}],
+//		 msg_flags=MSG_NOTIFICATION|MSG_EOR}, 0) = 12
 //+0.0 sctp_recvv(3, [{iov_base={sse_type=SCTP_SHUTDOWN_EVENT, sse_flags=1, sse_length=12}, iov_len=1000}], 1,
 //..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 12
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt
index 29d2f27969af1a2255bff0570e43e42e42c13e40..114a476808ae46fa799c0b32ea28b879eb416d27 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendv.pkt
@@ -14,7 +14,7 @@
 //sctp_sendv(int sd, const struct iovec *iov, int iovcnt, struct sockaddr *addrs, int addrcnt, void *info, socklen_t infolen, unsigned int infotype, int flags);
 
 //test with sctp_sendv_authinfo
-+1.0 sctp_sendv(3, [{iov_base=..., iov_len=500}, {iov_base=..., iov_len=500}], 2, ..., 1, {auth_keynumber=123}, 2, SCTP_SENDV_AUTHINFO, 0) = 1000
++1.0 sctp_sendv(3, [{iov_base=..., iov_len=500}, {iov_base=..., iov_len=500}], 2, NULL, 0, {auth_keynumber=123}, 2, SCTP_SENDV_AUTHINFO, 0) = 1000
 *    > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
 +0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]