From 102ab0962240a9fc949bf12c1025946610cfe3dc Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Thu, 26 Nov 2015 19:05:35 +0100
Subject: [PATCH] add srto_assoc_id

---
 gtests/net/packetdrill/lexer.l                |  1 +
 gtests/net/packetdrill/parser.y               | 23 ++++++++++++++-----
 gtests/net/packetdrill/run_system_call.c      | 23 +++++++++++++++++--
 gtests/net/packetdrill/script.c               |  5 ++++
 gtests/net/packetdrill/script.h               |  1 +
 .../bsd/sctp/sctp_get_socket_options.pkt      | 12 ++++++----
 .../tests/bsd/sctp/sctp_init_rtx.pkt          |  2 +-
 .../tests/bsd/sctp/sctp_socket_options.pkt    | 18 +++++++--------
 8 files changed, 62 insertions(+), 23 deletions(-)

diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index a308a572..530db0f4 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -215,6 +215,7 @@ stream_id			return STREAM_ID;
 stream_value			return STREAM_VALUE;
 sack_delay			return SACK_DELAY;
 sack_freq			return SACK_FREQ;
+srto_assoc_id			return SRTO_ASSOC_ID;
 srto_initial			return SRTO_INITIAL;
 srto_max			return SRTO_MAX;
 srto_min			return SRTO_MIN;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index cb23b55e..b459a755 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -503,7 +503,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> IPV4 IPV6 ICMP SCTP UDP UDPLITE GRE MTU
 %token <reserved> MPLS LABEL TC TTL
 %token <reserved> OPTION
-%token <reserved> SRTO_INITIAL SRTO_MAX SRTO_MIN
+%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
@@ -607,7 +607,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %type <expression> sctp_initmsg sinit_num_ostreams sinit_max_instreams sinit_max_attempts
 %type <expression> sinit_max_init_timeo sctp_assoc_value sctp_stream_value
 %type <expression> sctp_sackinfo sack_delay sack_freq
-%type <expression> sctp_rtoinfo srto_initial srto_max srto_min sctp_paddrinfo
+%type <expression> sctp_rtoinfo srto_assoc_id srto_initial srto_max srto_min sctp_paddrinfo
 %type <expression> sctp_paddrparams spp_address spp_hbinterval spp_pathmtu spp_pathmaxrxt
 %type <expression> spp_flags spp_ipv6_flowlabel spp_dscp
 %type <expression> spinfo_address spinfo_state spinfo_cwnd spinfo_srtt spinfo_rto spinfo_mtu
@@ -2766,6 +2766,16 @@ linger
 }
 ;
 
+srto_assoc_id
+: SRTO_ASSOC_ID '=' INTEGER {
+	if (!is_valid_u32($3)){
+		semantic_error("srto_assoc_id out of range");
+	}
+        $$ = new_integer_expression($3, "%u");
+}
+| SRTO_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
 srto_initial
 : SRTO_INITIAL '=' INTEGER {
 	if (!is_valid_u32($3)){
@@ -2797,12 +2807,13 @@ srto_min
 ;
 
 sctp_rtoinfo
-: '{' srto_initial ',' srto_max ',' srto_min '}' {
+: '{' srto_assoc_id ',' srto_initial ',' srto_max ',' srto_min '}' {
 	$$ = new_expression(EXPR_SCTP_RTOINFO);
 	$$->value.sctp_rtoinfo = calloc(1, sizeof(struct sctp_rtoinfo_expr));
-	$$->value.sctp_rtoinfo->srto_initial = $2;
-	$$->value.sctp_rtoinfo->srto_max = $4;
-	$$->value.sctp_rtoinfo->srto_min = $6;
+	$$->value.sctp_rtoinfo->srto_assoc_id = $2;
+	$$->value.sctp_rtoinfo->srto_initial = $4;
+	$$->value.sctp_rtoinfo->srto_max = $6;
+	$$->value.sctp_rtoinfo->srto_min = $8;
 }
 ;
 
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index 7403cc71..2ad5a7f3 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -2488,6 +2488,9 @@ static int check_linger(struct linger_expr *expr,
 static int check_sctp_rtoinfo(struct sctp_rtoinfo_expr *expr,
 			      struct sctp_rtoinfo *sctp_rtoinfo, char **error)
 {
+	if (check_u32_expr(expr->srto_assoc_id, sctp_rtoinfo->srto_assoc_id,
+			   "sctp_rtoinfo.srto_assoc_id", error))
+		return STATUS_ERR;
 	if (check_u32_expr(expr->srto_initial, sctp_rtoinfo->srto_initial,
 			   "sctp_rtoinfo.srto_initial", error))
 		return STATUS_ERR;
@@ -2835,7 +2838,16 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 	case EXPR_SCTP_RTOINFO:
 		live_optval = malloc(sizeof(struct sctp_rtoinfo));
 		live_optlen = (socklen_t)sizeof(struct sctp_rtoinfo);
-		((struct sctp_rtoinfo*)live_optval)->srto_assoc_id = 0;
+		if (val_expression->value.sctp_rtoinfo->srto_assoc_id->type != EXPR_ELLIPSIS) {
+			if (get_u32(val_expression->value.sctp_rtoinfo->srto_assoc_id,
+				    &((struct sctp_rtoinfo*)live_optval)->srto_assoc_id,
+				    error)) {
+				free(live_optval);
+				return STATUS_ERR;
+			}
+		} else {
+			((struct sctp_rtoinfo*)live_optval)->srto_assoc_id = 0;
+		}
 		break;
 #endif
 #ifdef SCTP_ASSOCINFO
@@ -3152,7 +3164,14 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 		break;
 #ifdef SCTP_RTOINFO
 	case EXPR_SCTP_RTOINFO:
-		rtoinfo.srto_assoc_id = 0;
+		if (val_expression->value.sctp_rtoinfo->srto_assoc_id->type != EXPR_ELLIPSIS) {
+			if (get_u32(val_expression->value.sctp_rtoinfo->srto_assoc_id,
+				    &rtoinfo.srto_assoc_id, error)) {
+				return STATUS_ERR;
+			}
+		} else {
+			rtoinfo.srto_assoc_id = 0;
+		}
 		if (get_u32(val_expression->value.sctp_rtoinfo->srto_initial,
 			    &rtoinfo.srto_initial, error)) {
 			return STATUS_ERR;
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 47d6c43b..c32024a1 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -313,6 +313,7 @@ void free_expression(struct expression *expression)
 		break;
 	case EXPR_SCTP_RTOINFO:
 		assert(expression->value.sctp_rtoinfo);
+		free_expression(expression->value.sctp_rtoinfo->srto_assoc_id);
 		free_expression(expression->value.sctp_rtoinfo->srto_initial);
 		free_expression(expression->value.sctp_rtoinfo->srto_max);
 		free_expression(expression->value.sctp_rtoinfo->srto_min);
@@ -787,6 +788,10 @@ static int evaluate_sctp_rtoinfo_expression(struct expression *in,
 	in_rtoinfo = in->value.sctp_rtoinfo;
 	out_rtoinfo = out->value.sctp_rtoinfo;
 
+	if (evaluate(in_rtoinfo->srto_assoc_id,
+	             &out_rtoinfo->srto_assoc_id,
+	             error))
+		return STATUS_ERR;
 	if (evaluate(in_rtoinfo->srto_initial,
 	             &out_rtoinfo->srto_initial,
 	             error))
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index 00ab1b4b..d61168d7 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -190,6 +190,7 @@ struct linger_expr {
 
 /* Parse tree for a sctp_rtoinfo struct in a [gs]etsockopt syscall. */
 struct sctp_rtoinfo_expr {
+	struct expression *srto_assoc_id;
 	struct expression *srto_initial;
 	struct expression *srto_max;
 	struct expression *srto_min;
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 a33a6d19..b0c3f423 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
@@ -83,11 +83,13 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv
 +0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=..., linger=30}, [8]) = 0
 +0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=..., linger=...}, [8]) = 0
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, [16]) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=..., srto_max=200, srto_min=50}, [16]) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=..., srto_min=50}, [16]) = 0
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=...}, [16]) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=0, srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=0, srto_initial=100, srto_max=200, srto_min=50}, [16]) = 0
++0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=0, srto_initial=..., srto_max=200, srto_min=50}, [16]) = 0
++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 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
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_init_rtx.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_init_rtx.pkt
index ed3759cd..75debec3 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_init_rtx.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_init_rtx.pkt
@@ -9,7 +9,7 @@
 +0.0 bind(3, ..., ...) = 0
 +0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR)
 +0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0
-+0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
 +0.0 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress)
 // Check the number and the timing of the restransmissions
 +0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=0, ...]
diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt
index af811a60..8b975d08 100644
--- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt
+++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_socket_options.pkt
@@ -1,14 +1,14 @@
 0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=200, srto_min=50}, 16) = 0
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=200, srto_max=200, srto_min=50}, 16) = 0
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=50, srto_min=50}, 16) = 0
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 17) = 0 
-//+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=..., srto_max=200, srto_min=50}, 15) = -1 EINVAL (Invalid argument)
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=25, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=225, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=50, srto_max=50, srto_min=200}, 16) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=0, srto_initial=100, srto_max=200, srto_min=50}, 16) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=50, srto_max=200, srto_min=50}, 16) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=200, srto_max=200, srto_min=50}, 16) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=50, srto_max=50, srto_min=50}, 16) = 0
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=100, srto_max=200, srto_min=50}, 17) = 0 
+//+0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=..., srto_max=200, srto_min=50}, 15) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=25, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=225, srto_max=200, srto_min=50}, 16) = -1 EINVAL (Invalid argument)
++0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_assoc_id=..., srto_initial=50, srto_max=50, srto_min=200}, 16) = -1 EINVAL (Invalid argument)
 
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=1024, sinit_max_instreams=1024, sinit_max_attempts=5, sinit_max_init_timeo=100}, 8) = 0
 +0 setsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=1024, sinit_max_instreams=1024, sinit_max_attempts=5, sinit_max_init_timeo=100}, 9) = 0
-- 
GitLab