From ab8ba5dc9af521cc1b1d6f52d885c67ccc7794b7 Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Thu, 26 Nov 2015 22:24:39 +0100
Subject: [PATCH] add sack_assoc_id in for structure sctp_sack_info_expr

---
 gtests/net/packetdrill/lexer.l                     |  1 +
 gtests/net/packetdrill/parser.y                    |  9 +++++----
 gtests/net/packetdrill/run_system_call.c           | 14 +++++++++++++-
 gtests/net/packetdrill/script.c                    |  7 ++++++-
 gtests/net/packetdrill/script.h                    |  1 +
 .../tests/bsd/sctp/sctp_get_socket_options.pkt     |  8 ++++----
 6 files changed, 30 insertions(+), 10 deletions(-)

diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index 57c43594..2476987f 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -214,6 +214,7 @@ assoc_id			return ASSOC_ID;
 assoc_value			return ASSOC_VALUE;
 stream_id			return STREAM_ID;
 stream_value			return STREAM_VALUE;
+sack_assoc_id			return SACK_ASSOC_ID;
 sack_delay			return SACK_DELAY;
 sack_freq			return SACK_FREQ;
 srto_assoc_id			return SRTO_ASSOC_ID;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 2e94c594..89cbf3c7 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -508,7 +508,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SINIT_MAX_INIT_TIMEO
 %token <reserved> ASSOC_ID ASSOC_VALUE
 %token <reserved> STREAM_ID STREAM_VALUE
-%token <reserved> SACK_DELAY SACK_FREQ
+%token <reserved> SACK_ASSOC_ID SACK_DELAY SACK_FREQ
 %token <reserved> SSTAT_STATE SSTAT_RWND SSTAT_UNACKDATA SSTAT_PENDDATA
 %token <reserved> SSTAT_INSTRMS SSTAT_OUTSTRMS SSTAT_FRAGMENTATION_POINT
 %token <reserved> SSTAT_PRIMARY
@@ -2910,11 +2910,12 @@ sack_freq
 | SACK_FREQ '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
 
 sctp_sackinfo
-: '{' sack_delay ',' sack_freq '}' {
+: '{' SACK_ASSOC_ID '=' expression ',' sack_delay ',' sack_freq '}' {
 	$$ = new_expression(EXPR_SCTP_SACKINFO);
 	$$->value.sctp_sack_info = calloc(1, sizeof(struct sctp_sack_info_expr));
-	$$->value.sctp_sack_info->sack_delay = $2;
-	$$->value.sctp_sack_info->sack_freq = $4;
+	$$->value.sctp_sack_info->sack_assoc_id = $4;
+	$$->value.sctp_sack_info->sack_delay = $6;
+	$$->value.sctp_sack_info->sack_freq = $8;
 }
 ;
 
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 93ee0e86..d5ce3c0d 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -2552,6 +2552,9 @@ static int check_sctp_sack_info(struct sctp_sack_info_expr *expr,
 				struct sctp_sack_info *sctp_sack_info,
 				char **error)
 {
+	if (check_u32_expr(expr->sack_assoc_id, sctp_sack_info->sack_assoc_id,
+			   "sctp_sack_info.sack_assoc_id", error))
+		return STATUS_ERR;
 	if (check_u32_expr(expr->sack_delay, sctp_sack_info->sack_delay,
 			   "sctp_sack_info.sack_delay", error))
 		return STATUS_ERR;
@@ -2913,7 +2916,12 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 	case EXPR_SCTP_SACKINFO:
 		live_optval = malloc(sizeof(struct sctp_sack_info));
 		live_optlen = (socklen_t)sizeof(struct sctp_sack_info);
-		((struct sctp_sack_info*) live_optval)->sack_assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_sack_info->sack_assoc_id,
+				    &((struct sctp_sack_info*) live_optval)->sack_assoc_id,
+				    error)) {
+			free(live_optval);
+			return STATUS_ERR;
+		}
 		break;
 #endif
 #ifdef SCTP_STATUS
@@ -3331,6 +3339,10 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #ifdef SCTP_DELAYED_SACK
 	case EXPR_SCTP_SACKINFO:
 		sack_info.sack_assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_sack_info->sack_assoc_id,
+				    &sack_info.sack_assoc_id, error)) {
+			return STATUS_ERR;
+		}
 		if (get_u32(val_expression->value.sctp_sack_info->sack_delay,
 			    &sack_info.sack_delay, error)) {
 			return STATUS_ERR;
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index c67edad4..ec2f92d6 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -333,8 +333,9 @@ void free_expression(struct expression *expression)
 		break;
 	case EXPR_SCTP_SACKINFO:
 		assert(expression->value.sctp_sack_info);
+		free_expression(expression->value.sctp_sack_info->sack_assoc_id);
 		free_expression(expression->value.sctp_sack_info->sack_delay);
-		free_expression(expression->value.sctp_sack_info->sack_freq);		
+		free_expression(expression->value.sctp_sack_info->sack_freq);
 		break;
 	case EXPR_SCTP_PADDRINFO:
 		assert(expression->value.sctp_paddrinfo);
@@ -897,6 +898,10 @@ static int evaluate_sctp_sack_info_expression(struct expression *in,
 	in_sack_info = in->value.sctp_sack_info;
 	out_sack_info = out->value.sctp_sack_info;
 
+	if (evaluate(in_sack_info->sack_assoc_id,
+		     &out_sack_info->sack_assoc_id,
+		     error))
+		return STATUS_ERR;
 	if (evaluate(in_sack_info->sack_delay,
 		     &out_sack_info->sack_delay,
 		     error))
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index 4e118f89..740e7485 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -220,6 +220,7 @@ struct sctp_stream_value_expr {
 
 /* Parse tree for a sctp_sack_info struct in a [gs]etsockopt syscall. */
 struct sctp_sack_info_expr {
+	struct expression *sack_assoc_id;
 	struct expression *sack_delay;
 	struct expression *sack_freq;
 };
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt
index c4e8d254..637209b2 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt
@@ -112,10 +112,10 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_assoc_id=0, sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=..., sasoc_peer_rwnd=...,
 						sasoc_local_rwnd=..., sasoc_cookie_life=...}, [20]) = 0
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=1}, 12) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=1}, [12]) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=..., sack_freq=1}, [12]) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=...}, [12]) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_assoc_id=0, sack_delay=250, sack_freq=1}, 12) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_assoc_id=0, sack_delay=..., sack_freq=1}, [12]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_assoc_id=0, sack_delay=..., sack_freq=1}, [12]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_assoc_id=0, sack_delay=250, sack_freq=...}, [12]) = 0
 
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_assoc_id=0, se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_assoc_id=0, se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0
-- 
GitLab