From a0ee12318d415d7cc975721efc14d80550b380c5 Mon Sep 17 00:00:00 2001
From: hoelscher <jens.hoelscher@fh-muenster.de>
Date: Thu, 26 Nov 2015 22:02:01 +0100
Subject: [PATCH] add spp_assoc_id for sctp_paddrparams

---
 gtests/net/packetdrill/lexer.l                |  1 +
 gtests/net/packetdrill/parser.y               | 32 +++++++++++++------
 gtests/net/packetdrill/run_system_call.c      | 13 +++++---
 gtests/net/packetdrill/script.c               |  5 +++
 gtests/net/packetdrill/script.h               |  1 +
 .../bsd/sctp/sctp_get_socket_options.pkt      | 12 +++----
 6 files changed, 44 insertions(+), 20 deletions(-)

diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l
index 3f564c4c..fe563ba9 100644
--- a/gtests/net/packetdrill/lexer.l
+++ b/gtests/net/packetdrill/lexer.l
@@ -243,6 +243,7 @@ spinfo_cwnd			return SPINFO_CWND;
 spinfo_srtt			return SPINFO_SRTT;
 spinfo_rto			return SPINFO_RTO;
 spinfo_mtu			return SPINFO_MTU;
+spp_assoc_id			return SPP_ASSOC_ID;
 spp_address			return SPP_ADDRESS;
 spp_hbinterval			return SPP_HBINTERVAL;
 spp_pathmaxrxt			return SPP_PATHMAXRXT;
diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y
index 91f05e8d..26810a98 100644
--- a/gtests/net/packetdrill/parser.y
+++ b/gtests/net/packetdrill/parser.y
@@ -534,7 +534,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %token <reserved> COOKIE_RECEIVED_WHILE_SHUTDOWN RESTART_WITH_NEW_ADDRESSES
 %token <reserved> USER_INITIATED_ABORT PROTOCOL_VIOLATION
 %token <reserved> STALENESS CHK PARAM UNRECOGNIZED_PARAMETERS
-%token <reserved> SPP_ADDRESS SPP_HBINTERVAL SPP_PATHMAXRXT SPP_PATHMTU
+%token <reserved> SPP_ASSOC_ID SPP_ADDRESS SPP_HBINTERVAL SPP_PATHMAXRXT SPP_PATHMTU
 %token <reserved> SPP_FLAGS SPP_IPV6_FLOWLABEL_ SPP_DSCP_
 %token <reserved> SASOC_ASOCMAXRXT SASOC_ASSOC_ID SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND
 %token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_ASSOC_ID SE_TYPE SE_ON
@@ -609,7 +609,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
 %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_assoc_id srto_initial srto_max srto_min sctp_paddrinfo
-%type <expression> sctp_paddrparams spp_address spp_hbinterval spp_pathmtu spp_pathmaxrxt
+%type <expression> sctp_paddrparams spp_assoc_id 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
 %type <expression> sasoc_assoc_id sasoc_asocmaxrxt sasoc_number_peer_destinations sasoc_peer_rwnd
@@ -3074,6 +3074,16 @@ sctp_status
 }
 ;
 
+spp_assoc_id
+: SPP_ASSOC_ID '=' INTEGER {
+	if (!is_valid_u32($3)) {
+		semantic_error("spp_assoc_id out of range");
+	}
+	$$ = new_integer_expression($3, "%u");
+}
+| SPP_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
+;
+
 spp_address
 : SPP_ADDRESS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
 | SPP_ADDRESS '=' sockaddr { $$ = $3; }
@@ -3134,16 +3144,18 @@ spp_dscp
 ;
 
 sctp_paddrparams
-: '{' spp_address ',' spp_hbinterval ',' spp_pathmaxrxt ',' spp_pathmtu ','spp_flags ',' spp_ipv6_flowlabel ',' spp_dscp'}' {
+: '{' spp_assoc_id ',' spp_address ',' spp_hbinterval ',' spp_pathmaxrxt ',' spp_pathmtu ','spp_flags ','
+      spp_ipv6_flowlabel ',' spp_dscp'}' {
 	$$ = new_expression(EXPR_SCTP_PEER_ADDR_PARAMS);
 	$$->value.sctp_paddrparams = calloc(1, sizeof(struct sctp_paddrparams_expr));
-	$$->value.sctp_paddrparams->spp_address = $2;
-	$$->value.sctp_paddrparams->spp_hbinterval = $4;
-	$$->value.sctp_paddrparams->spp_pathmaxrxt = $6;
-	$$->value.sctp_paddrparams->spp_pathmtu = $8;
-	$$->value.sctp_paddrparams->spp_flags = $10;
-	$$->value.sctp_paddrparams->spp_ipv6_flowlabel = $12;
-	$$->value.sctp_paddrparams->spp_dscp = $14;
+	$$->value.sctp_paddrparams->spp_assoc_id = $2;
+	$$->value.sctp_paddrparams->spp_address = $4;
+	$$->value.sctp_paddrparams->spp_hbinterval = $6;
+	$$->value.sctp_paddrparams->spp_pathmaxrxt = $8;
+	$$->value.sctp_paddrparams->spp_pathmtu = $10;
+	$$->value.sctp_paddrparams->spp_flags = $12;
+	$$->value.sctp_paddrparams->spp_ipv6_flowlabel = $14;
+	$$->value.sctp_paddrparams->spp_dscp = $16;
 }
 ;
 
diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c
index e06ef241..85b15011 100644
--- a/gtests/net/packetdrill/run_system_call.c
+++ b/gtests/net/packetdrill/run_system_call.c
@@ -2943,13 +2943,15 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
 		struct sctp_paddrparams *live_params = malloc(sizeof(struct sctp_paddrparams));
 		memset(live_params, 0, sizeof(struct sctp_paddrparams));
 		live_optlen = sizeof(struct sctp_paddrparams);
-		if (get_sockstorage_arg(expr_params->spp_address, &live_params->spp_address,
-					live_fd)) {
+		if (get_sockstorage_arg(expr_params->spp_address, &live_params->spp_address, live_fd)) {
 			asprintf(error, "can't determine spp_address");
 			free(live_params);
 			return STATUS_ERR;
 		}
-		live_params->spp_assoc_id = 0;
+		if (get_sctp_assoc_t(expr_params->spp_assoc_id, &live_params->spp_assoc_id, error)) {
+			free(live_params);
+			return STATUS_ERR;
+		}
 		live_optval = live_params;
 		break;
 	}
@@ -3462,7 +3464,10 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
 #endif
 #ifdef SCTP_PEER_ADDR_PARAMS
 	case EXPR_SCTP_PEER_ADDR_PARAMS:
-		paddrparams.spp_assoc_id = 0;
+		if (get_sctp_assoc_t(val_expression->value.sctp_paddrparams->spp_assoc_id,
+				     &paddrparams.spp_assoc_id, error)) {
+			return STATUS_ERR;
+		}
 		if (get_sockstorage_arg(val_expression->value.sctp_paddrparams->spp_address,
 					&paddrparams.spp_address, live_fd)) {
 			asprintf(error, "can't determine spp_address");
diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c
index 3cb25578..9c2fa23e 100644
--- a/gtests/net/packetdrill/script.c
+++ b/gtests/net/packetdrill/script.c
@@ -357,6 +357,7 @@ void free_expression(struct expression *expression)
 		break;
 	case EXPR_SCTP_PEER_ADDR_PARAMS:
 		assert(expression->value.sctp_paddrparams);
+		free_expression(expression->value.sctp_paddrparams->spp_assoc_id);
 		free_expression(expression->value.sctp_paddrparams->spp_address);
 		free_expression(expression->value.sctp_paddrparams->spp_hbinterval);
 		free_expression(expression->value.sctp_paddrparams->spp_pathmaxrxt);
@@ -1014,6 +1015,10 @@ static int evaluate_sctp_peer_addr_param_expression(struct expression *in,
 	in_paddrparams = in->value.sctp_paddrparams;
 	out_paddrparams = out->value.sctp_paddrparams;
 
+	if (evaluate(in_paddrparams->spp_assoc_id,
+	             &out_paddrparams->spp_assoc_id,
+	             error))
+		return STATUS_ERR;
 	if (evaluate(in_paddrparams->spp_address,
 	             &out_paddrparams->spp_address,
 	             error))
diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h
index d5951572..6c9ca735 100644
--- a/gtests/net/packetdrill/script.h
+++ b/gtests/net/packetdrill/script.h
@@ -247,6 +247,7 @@ struct sctp_paddrinfo_expr {
 
 /* Parse tree for a sctp_paddrparams struct in a [gs]etsockopt syscall. */
 struct sctp_paddrparams_expr {
+	struct expression *spp_assoc_id;
 	struct expression *spp_address;
 	struct expression *spp_hbinterval;
 	struct expression *spp_pathmaxrxt;
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 90677ab3..10794143 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
@@ -61,22 +61,22 @@ spinfo_state=SCTP_ACTIVE, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=..., spi
 spinfo_state=SCTP_ACTIVE, spinfo_cwnd=4464, spinfo_srtt=..., spinfo_rto=1000, spinfo_mtu=...}, [152]) = 0
 
 
-+0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=300, spp_pathmaxrxt=8, spp_pathmtu=1468, spp_flags=SPP_DSCP|SPP_HB_ENABLE, spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=300, spp_pathmaxrxt=8, spp_pathmtu=1468, spp_flags=SPP_DSCP|SPP_HB_ENABLE|SPP_PMTUD_ENABLE, spp_ipv6_flowlabel=0, spp_dscp=0}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=..., spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=..., spp_ipv6_flowlabel=0, spp_dscp=0}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=..., spp_flags=521, spp_ipv6_flowlabel=0, spp_dscp=0}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv6_flowlabel=..., spp_dscp=0}, [152]) = 0
 
-+0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
++0 getsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_assoc_id=0, spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},
 spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv6_flowlabel=0, spp_dscp=...}, [152]) = 0
 
 
-- 
GitLab