diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 57c435947ce6e24b3b085695fb61ab57b552d3e5..2476987f47460b74fbe554a8938d12622ba63e56 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 2e94c59431e7e8e5399c98707aa4da93d52483db..89cbf3c78ce7a799981f876dde53d1e884b42015 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 93ee0e86228ddae3baf0d9afd6426d3e327cff70..d5ce3c0deeb800fb9eec8aeca079a4ae8e8d856c 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 c67edad4b17e1816effcb87a967542e6b2c82cc6..ec2f92d6a8e431c0bf44e6b4923f87f74a422c3a 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 4e118f890f0f99cd00f8be45be1527a95b18dde7..740e7485348f55c6cb2c5d01e8934046c2d88edd 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 c4e8d2549bf2c8e955c6c293e7184da6ed7421c6..637209b23abfed68b9fea1104cf5b337e3aca1ef 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