diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index a9b9484315d86ffce9b2be68080698f82b6ecb96..f54f7a597db864f2b2ea752f2b9dc01d9271a932 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -524,6 +524,12 @@ assocreset_length		return ASSOCRESET_LENGTH;
 assocreset_assoc_id		return ASSOCRESET_ASSOC_ID;
 assocreset_local_tsn		return ASSOCRESET_LOCAL_TSN;
 assocreset_remote_tsn		return ASSOCRESET_REMOTE_TSN;
+strchange_type			return STRCHANGE_TYPE;
+strchange_flags			return STRCHANGE_FLAGS;
+strchange_length		return STRCHANGE_LENGTH;
+strchange_assoc_id		return STRCHANGE_ASSOC_ID;
+strchange_instrms		return STRCHANGE_INSTRMS;
+strchange_outstrms		return STRCHANGE_OUTSTRMS;
 CHUNK				return CHUNK;
 DATA				return DATA;
 INIT				return INIT;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 0b5c90e8cdc5b36900662093c0fee7925b62e907..3ac46b6497d1788cc9038a3c95d4fa4a51b99567 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -571,6 +571,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SAS_ASSOC_ID SAS_INSTRMS SAS_OUTSTRMS
 %token <reserved> STRRESET_TYPE STRRESET_FLAGS STRRESET_LENGTH STRRESET_ASSOC_ID STRRESET_STREAM_LIST
 %token <reserved> ASSOCRESET_TYPE ASSOCRESET_FLAGS ASSOCRESET_LENGTH ASSOCRESET_ASSOC_ID ASSOCRESET_LOCAL_TSN ASSOCRESET_REMOTE_TSN
+%token <reserved> STRCHANGE_TYPE STRCHANGE_FLAGS STRCHANGE_LENGTH STRCHANGE_ASSOC_ID STRCHANGE_INSTRMS STRCHANGE_OUTSTRMS
 %token <floating> FLOAT
 %token <integer> INTEGER HEX_INTEGER
 %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
@@ -648,6 +649,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sctp_stream_reset_event strreset_type strreset_flags strreset_length
 %type <expression> sctp_assoc_reset_event assocreset_type assocreset_flags assocreset_length
 %type <expression> assocreset_local_tsn assocreset_remote_tsn
+%type <expression> sctp_stream_change_event strchange_type strchange_flags strchange_length strchange_instrms strchange_outstrms
 %type <expression> sctp_add_streams
 %type <errno_info> opt_errno
 %type <chunk_list> sctp_chunk_list_spec
@@ -2747,6 +2749,7 @@ data
 | sctp_tlv                  { $$ = $1; }
 | sctp_stream_reset_event   { $$ = $1; }
 | sctp_assoc_reset_event    { $$ = $1; }
+| sctp_stream_change_event  { $$ = $1; }
 ;
 
 msghdr
@@ -5154,6 +5157,79 @@ sctp_assoc_reset_event
 }
 ;
 
+strchange_type
+: STRCHANGE_TYPE '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("strchange_type out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| STRCHANGE_TYPE '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| STRCHANGE_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+strchange_flags
+: STRCHANGE_FLAGS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("strchange_flags out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| STRCHANGE_FLAGS '=' WORD {
+	$$ = new_expression(EXPR_WORD);
+	$$->value.string = $3;
+}
+| STRCHANGE_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+| STRCHANGE_FLAGS '=' binary_expression { $$ = $3; }
+;
+
+strchange_length
+: STRCHANGE_LENGTH '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("strchange_length out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| STRCHANGE_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+strchange_instrms
+: STRCHANGE_INSTRMS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("strchange_instrms out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| STRCHANGE_INSTRMS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+strchange_outstrms
+: STRCHANGE_OUTSTRMS '=' INTEGER {
+	if (!is_valid_u16($3)) {
+		semantic_error("strchange_outstrms out of range");
+	}
+	$$ = new_integer_expression($3, "%hu");
+}
+| STRCHANGE_OUTSTRMS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
+sctp_stream_change_event
+: '{' strchange_type ',' strchange_flags ',' strchange_length ',' STRCHANGE_ASSOC_ID '=' sctp_assoc_id ',' strchange_instrms ',' strchange_outstrms '}' {
+	$$ = new_expression(EXPR_SCTP_STREAM_CHANGE_EVENT);
+	$$->value.sctp_stream_change_event = calloc(1, sizeof(struct sctp_stream_change_event_expr));
+	$$->value.sctp_stream_change_event->strchange_type = $2;
+	$$->value.sctp_stream_change_event->strchange_flags = $4;
+	$$->value.sctp_stream_change_event->strchange_length = $6;
+	$$->value.sctp_stream_change_event->strchange_assoc_id = $10;
+	$$->value.sctp_stream_change_event->strchange_instrms = $12;
+	$$->value.sctp_stream_change_event->strchange_outstrms = $14;
+
+}
+;
+
 opt_errno
 :                   { $$ = NULL; }
 | WORD note         {
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 7af2664bf089f98f7d98eb7723d6755e46832ba1..492abf05310c81765388f260aaa4ac0543e85fec 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -855,7 +855,8 @@ static int iovec_new(struct expression *expression,
 		       iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED_EVENT ||
 		       iov_expr->iov_base->type == EXPR_SCTP_TLV ||
 		       iov_expr->iov_base->type == EXPR_SCTP_STREAM_RESET_EVENT ||
-		       iov_expr->iov_base->type == EXPR_SCTP_ASSOC_RESET_EVENT);
+		       iov_expr->iov_base->type == EXPR_SCTP_ASSOC_RESET_EVENT ||
+		       iov_expr->iov_base->type == EXPR_SCTP_STREAM_CHANGE_EVENT);
 		assert(iov_expr->iov_len->type == EXPR_INTEGER);
 
 		len = iov_expr->iov_len->value.num;
@@ -5290,6 +5291,33 @@ static int check_sctp_assoc_reset_event(struct sctp_assoc_reset_event_expr *expr
 }
 #endif
 
+#if defined(__FreeBSD__)
+static int check_sctp_stream_change_event(struct sctp_stream_change_event_expr *expr,
+					  struct sctp_stream_change_event *sctp_stream_change_event,
+					  char **error) {
+	if (check_u16_expr(expr->strchange_type, sctp_stream_change_event->strchange_type,
+			   "sctp_stream_change_event.strchange_type", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->strchange_flags, sctp_stream_change_event->strchange_flags,
+			   "sctp_stream_change_event.strchange_flags", error))
+		return STATUS_ERR;
+	if (check_u32_expr(expr->strchange_length, sctp_stream_change_event->strchange_length,
+			   "sctp_stream_change_event.strchange_length", error))
+		return STATUS_ERR;
+	if (check_sctp_assoc_t_expr(expr->strchange_assoc_id, sctp_stream_change_event->strchange_assoc_id,
+			   "sctp_stream_change_event.strchange_assoc_id", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->strchange_instrms, sctp_stream_change_event->strchange_instrms,
+			   "sctp_stream_change_event.strchange_instrms", error))
+		return STATUS_ERR;
+	if (check_u16_expr(expr->strchange_outstrms, sctp_stream_change_event->strchange_outstrms,
+			   "sctp_stream_change_event.strchange_outstrms", error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+#endif
+
 #if defined(__FreeBSD__) || defined(linux)
 static int check_sctp_notification(struct iovec *iov,
 				   struct expression *iovec_expr,
@@ -5391,6 +5419,14 @@ static int check_sctp_notification(struct iovec *iov,
 						         error))
 				return STATUS_ERR;
 			break;
+#endif
+#if defined(__FreeBSD__)
+		case EXPR_SCTP_STREAM_CHANGE_EVENT:
+			if (check_sctp_stream_change_event(script_iov_base->value.sctp_stream_change_event,
+						           (struct sctp_stream_change_event *) iov[i].iov_base,
+						           error))
+				return STATUS_ERR;
+			break;
 #endif
 		case EXPR_ELLIPSIS:
 			break;
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index bb16a64a198d49bcb87cbbd6bfa1a874ea3c8e8d..250dcd4c6531cb2e9006460a0b53eb3464dea65f 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -112,6 +112,7 @@ struct expression_type_entry expression_type_table[] = {
 	{ EXPR_SCTP_ADD_STREAMS,     "sctp_add_streams"},
 	{ EXPR_SCTP_STREAM_RESET_EVENT, "sctp_stream_reset_event"},
 	{ EXPR_SCTP_ASSOC_RESET_EVENT, "sctp_assoc_reset_event"},
+	{ EXPR_SCTP_STREAM_CHANGE_EVENT, "sctp_stream_change_event"},
 	{ NUM_EXPR_TYPES,            NULL}
 };
 
@@ -637,6 +638,14 @@ void free_expression(struct expression *expression)
 		free_expression(expression->value.sctp_assoc_reset_event->assocreset_local_tsn);
 		free_expression(expression->value.sctp_assoc_reset_event->assocreset_remote_tsn);
 		break;
+	case EXPR_SCTP_STREAM_CHANGE_EVENT:
+		free_expression(expression->value.sctp_stream_change_event->strchange_type);
+		free_expression(expression->value.sctp_stream_change_event->strchange_flags);
+		free_expression(expression->value.sctp_stream_change_event->strchange_length);
+		free_expression(expression->value.sctp_stream_change_event->strchange_assoc_id);
+		free_expression(expression->value.sctp_stream_change_event->strchange_instrms);
+		free_expression(expression->value.sctp_stream_change_event->strchange_outstrms);
+		break;
 	case EXPR_WORD:
 		assert(expression->value.string);
 		free(expression->value.string);
@@ -2600,6 +2609,50 @@ static int evaluate_sctp_assoc_reset_event_expression(struct expression *in,
 	return STATUS_OK;
 }
 
+static int evaluate_sctp_stream_change_event_expression(struct expression *in,
+						        struct expression *out,
+						        char **error)
+{
+	struct sctp_stream_change_event_expr *in_event;
+	struct sctp_stream_change_event_expr *out_event;
+
+	assert(in->type == EXPR_SCTP_STREAM_CHANGE_EVENT);
+	assert(in->value.sctp_stream_change_event);
+	assert(out->type == EXPR_SCTP_STREAM_CHANGE_EVENT);
+
+	out->value.sctp_stream_change_event = calloc(1, sizeof(struct sctp_stream_change_event_expr));
+
+	in_event = in->value.sctp_stream_change_event;
+	out_event = out->value.sctp_stream_change_event;
+
+	if (evaluate(in_event->strchange_type,
+		     &out_event->strchange_type,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->strchange_flags,
+		     &out_event->strchange_flags,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->strchange_length,
+		     &out_event->strchange_length,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->strchange_assoc_id,
+		     &out_event->strchange_assoc_id,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->strchange_instrms,
+		     &out_event->strchange_instrms,
+		     error))
+		return STATUS_ERR;
+	if (evaluate(in_event->strchange_outstrms,
+		     &out_event->strchange_outstrms,
+		     error))
+		return STATUS_ERR;
+
+	return STATUS_OK;
+}
+
 static int evaluate(struct expression *in,
 		    struct expression **out_ptr, char **error)
 {
@@ -2760,6 +2813,9 @@ static int evaluate(struct expression *in,
 	case EXPR_SCTP_ASSOC_RESET_EVENT:
 		result = evaluate_sctp_assoc_reset_event_expression(in, out, error);
 		break;
+	case EXPR_SCTP_STREAM_CHANGE_EVENT:
+		result = evaluate_sctp_stream_change_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 9556a841106ce6b38e52d74f594db0be1bf83f18..0dc20025819b2e04ea482756465c7096ec542f21 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -92,6 +92,7 @@ enum expression_t {
 	EXPR_SCTP_ADD_STREAMS,    /* expression tree for sctp_add_streams struct for [gs]etsockopt */
 	EXPR_SCTP_STREAM_RESET_EVENT, /* expression tree for sctp_stream_reset_event struct for sctp notifications */
 	EXPR_SCTP_ASSOC_RESET_EVENT,  /* expression tree for sctp_assoc_reset_event struct for sctp notifications */
+	EXPR_SCTP_STREAM_CHANGE_EVENT, /* expression tree for sctp_stream_change_event struct for sctp notifications */
 	NUM_EXPR_TYPES,
 };
 /* Convert an expression type to a human-readable string */
@@ -157,6 +158,7 @@ struct expression {
 		struct sctp_add_streams_expr *sctp_add_streams;
 		struct sctp_stream_reset_event_expr *sctp_stream_reset_event;
 		struct sctp_assoc_reset_event_expr *sctp_assoc_reset_event;
+		struct sctp_stream_change_event_expr *sctp_stream_change_event;
 	} value;
 	const char *format;	/* the printf format for printing the value */
 };
@@ -607,6 +609,16 @@ struct sctp_assoc_reset_event_expr {
 	struct expression *assocreset_remote_tsn;
 };
 
+/* Parse tree for sctp_stream_change_event struct for sctp notifications. */
+struct sctp_stream_change_event_expr {
+	struct expression *strchange_type;
+	struct expression *strchange_flags;
+	struct expression *strchange_length;
+	struct expression *strchange_assoc_id;
+	struct expression *strchange_instrms;
+	struct expression *strchange_outstrms;
+};
+
 /* The errno-related info from strace to summarize a system call error */
 struct errno_spec {
 	const char *errno_macro;	/* errno symbol (C macro name) */