From dc6785f164b8c615bdb02a1d8d9292cfca0ca132 Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Thu, 26 Nov 2015 22:15:23 +0100
Subject: [PATCH] add assoc_id in MAXSEG socketoption

---
 gtests/net/packetdrill/lexer.l                |  1 +
 gtests/net/packetdrill/parser.y               |  7 +++---
 gtests/net/packetdrill/run_system_call.c      | 24 ++++++++++++-------
 gtests/net/packetdrill/script.c               |  5 ++++
 gtests/net/packetdrill/script.h               |  1 +
 .../bsd/sctp/sctp_get_socket_options.pkt      |  2 +-
 6 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index fe563ba9..57c43594 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -210,6 +210,7 @@ ce				return CE;
 iov_base			return IOV_BASE;
 iov_len				return IOV_LEN;
 [.][.][.]			return ELLIPSIS;
+assoc_id			return ASSOC_ID;
 assoc_value			return ASSOC_VALUE;
 stream_id			return STREAM_ID;
 stream_value			return STREAM_VALUE;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 26810a98..2e94c594 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -506,7 +506,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> SRTO_ASSOC_ID SRTO_INITIAL SRTO_MAX SRTO_MIN
 %token <reserved> SINIT_NUM_OSTREAMS SINIT_MAX_INSTREAMS SINIT_MAX_ATTEMPTS
 %token <reserved> SINIT_MAX_INIT_TIMEO
-%token <reserved> ASSOC_VALUE
+%token <reserved> ASSOC_ID ASSOC_VALUE
 %token <reserved> STREAM_ID STREAM_VALUE
 %token <reserved> SACK_DELAY SACK_FREQ
 %token <reserved> SSTAT_STATE SSTAT_RWND SSTAT_UNACKDATA SSTAT_PENDDATA
@@ -2883,10 +2883,11 @@ sctp_stream_value
 ;
 
 sctp_assoc_value
-: '{' ASSOC_VALUE '=' expression '}' {
+: '{' ASSOC_ID '=' expression ',' ASSOC_VALUE '=' expression '}' {
 	$$ = new_expression(EXPR_SCTP_ASSOC_VALUE);
 	$$->value.sctp_assoc_value = calloc(1, sizeof(struct sctp_assoc_value_expr));
-	$$->value.sctp_assoc_value->assoc_value = $4;
+	$$->value.sctp_assoc_value->assoc_id = $4;
+	$$->value.sctp_assoc_value->assoc_value = $8;
 }
 ;
 
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 85b15011..93ee0e86 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -2671,6 +2671,9 @@ static int check_sctp_assoc_value(struct sctp_assoc_value_expr *expr,
 				  struct sctp_assoc_value *sctp_assoc_value,
 				  char **error)
 {
+	if (check_u32_expr(expr->assoc_id, sctp_assoc_value->assoc_id,
+			   "sctp_assoc_value.assoc_id", error))
+		return STATUS_ERR;
 	if (check_u16_expr(expr->assoc_value, sctp_assoc_value->assoc_value,
 			   "sctp_assoc_value.stream_id", error))
 		return STATUS_ERR;
@@ -2960,7 +2963,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 	case EXPR_SCTP_ASSOC_VALUE:
 		live_optval = malloc(sizeof(struct sctp_assoc_value));
 		live_optlen = (socklen_t)sizeof(struct sctp_assoc_value);
-		((struct sctp_assoc_value *) live_optval)->assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_assoc_value->assoc_id,
+			&((struct sctp_assoc_value *) live_optval)->assoc_id, error)) {
+			free(live_optval);
+			return STATUS_ERR;
+		}
 		break;
 #endif
 #ifdef SCTP_SS_VALUE
@@ -3296,7 +3303,10 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #endif
 #if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED)
 	case EXPR_SCTP_ASSOC_VALUE:
-		assoc_value.assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_assoc_value->assoc_id,
+				     &assoc_value.assoc_id, error)) {
+			return STATUS_ERR;
+		}
 		if (get_u32(val_expression->value.sctp_assoc_value->assoc_value,
 			    &assoc_value.assoc_value, error)) {
 			return STATUS_ERR;
@@ -3351,13 +3361,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #endif
 #ifdef SCTP_EVENT
 	case EXPR_SCTP_EVENT:
-		if (val_expression->value.sctp_event->se_assoc_id->type != EXPR_ELLIPSIS) {
-			if (get_sctp_assoc_t(val_expression->value.sctp_event->se_assoc_id,
-					     &event.se_assoc_id, error)) {
-				return STATUS_ERR;
-			}
-		} else {
-			event.se_assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_event->se_assoc_id,
+				     &event.se_assoc_id, error)) {
+			return STATUS_ERR;
 		}
 		if (get_u16(val_expression->value.sctp_event->se_type,
 			    &event.se_type, error)) {
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 9c2fa23e..c67edad4 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -321,6 +321,7 @@ void free_expression(struct expression *expression)
 		break;
 	case EXPR_SCTP_ASSOC_VALUE:
 		assert(expression->value.sctp_assoc_value);
+		free_expression(expression->value.sctp_assoc_value->assoc_id);
 		free_expression(expression->value.sctp_assoc_value->assoc_value);
 		break;
 	case EXPR_SCTP_INITMSG:
@@ -868,6 +869,10 @@ static int evaluate_sctp_assoc_value_expression(struct expression *in,
 	in_value = in->value.sctp_assoc_value;
 	out_value = out->value.sctp_assoc_value;
 
+	if (evaluate(in_value->assoc_id,
+	             &out_value->assoc_id,
+	             error))
+		return STATUS_ERR;
 	if (evaluate(in_value->assoc_value,
 	             &out_value->assoc_value,
 	             error))
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index 6c9ca735..4e118f89 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -208,6 +208,7 @@ struct sctp_initmsg_expr {
 
 /* Parse tree for a sctp_assoc_value struct in a [gs]etsockopt syscall. */
 struct sctp_assoc_value_expr {
+	struct expression *assoc_id;
 	struct expression *assoc_value;
 };
 
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 10794143..c4e8d254 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
@@ -93,7 +93,7 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=0, srto_initial=100, srto_max=..., srto_min=50}, [16]) = 0
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=0, srto_initial=100, srto_max=200, srto_min=...}, [16]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_value=1452}, [8]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_MAXSEG, {assoc_id=0, assoc_value=1452}, [8]) = 0
 
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=2, sinit_max_instreams=2, sinit_max_attempts=2, sinit_max_init_timeo=30}, 8) = 0
 +0 getsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=2, sinit_max_instreams=2, sinit_max_attempts=2, sinit_max_init_timeo=30}, [8]) = 0
-- 
GitLab