diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 92a6d22940649be7a0d5ba870c63e2876fd54c77..53e33af76bc44dcabe30c85ededd067c10791fc5 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -242,6 +242,7 @@ spp_ipv6_flowlabel return SPP_IPV6_FLOWLABEL_; /* avoid name clash */ spp_dscp return SPP_DSCP_; /* avoid name clash */ se_type return SE_TYPE; se_on return SE_ON; +ssb_adaptation_ind return SSB_ADAPTATION_IND; CHUNK return CHUNK; DATA return DATA; INIT return INIT; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 151546a15dc31ab66f4fff5c7939310b89d94ad3..36b09f9258f018e0c31f7361a76ddbc2d53cd024 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -536,7 +536,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SPP_ADDRESS SPP_HBINTERVAL SPP_PATHMAXRXT SPP_PATHMTU %token <reserved> SPP_FLAGS SPP_IPV6_FLOWLABEL_ SPP_DSCP_ %token <reserved> SASOC_ASOCMAXRXT SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND -%token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_TYPE SE_ON +%token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_TYPE SE_ON SSB_ADAPTATION_IND %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -585,7 +585,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> spinfo_address spinfo_state spinfo_cwnd spinfo_srtt spinfo_rto spinfo_mtu %type <expression> sasoc_asocmaxrxt sasoc_number_peer_destinations sasoc_peer_rwnd %type <expression> sasoc_local_rwnd sasoc_cookie_life sctp_assocparams -%type <expression> sctp_event se_type se_on +%type <expression> sctp_event se_type se_on sctp_setadaptation %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2374,6 +2374,9 @@ expression | sctp_event { $$ = $1; } +| sctp_setadaptation{ + $$ = $1; +} ; decimal_integer @@ -3005,6 +3008,21 @@ sctp_event } ; +sctp_setadaptation +: '{' SSB_ADAPTATION_IND '=' INTEGER '}' { +#ifdef SCTP_ADAPTATION_LAYER + $$ = new_expression(EXPR_SCTP_SETADAPTATION); + $$->value.sctp_setadaptation = calloc(1, sizeof(struct sctp_setadaptation)); + if (!is_valid_u32($4)) { + semantic_error("ssb_adaptation_ind out of range"); + } + $$->value.sctp_setadaptation->ssb_adaptation_ind = new_integer_expression($4, "%u"); +#elif + $$ = NULL; +#endif +} +; + opt_errno : { $$ = NULL; } | WORD note { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index c550a868867f3699b26365948dbc578b238e83fd..27954fe7a5010c35ff8fbb69fc94ed7eaa232f08 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -2257,6 +2257,27 @@ static int check_sctp_event(struct sctp_event_expr *expr, } #endif +#ifdef SCTP_ADAPTATION_LAYER +static int check_sctp_setadaptation(struct sctp_setadaptation_expr *expr, + struct sctp_setadaptation *sctp_setadaptation, + char **error) +{ + if (expr->ssb_adaptation_ind->type != EXPR_ELLIPSIS) { + u32 ssb_adaptation_ind; + + if (get_u32(expr->ssb_adaptation_ind, &ssb_adaptation_ind, error)) { + return STATUS_ERR; + } + if (sctp_setadaptation->ssb_adaptation_ind != ssb_adaptation_ind) { + asprintf(error, "Bad getsockopt sctp_setadaptation.ssb_adaptation_ind: expected: %u actual: %u", + ssb_adaptation_ind, sctp_setadaptation->ssb_adaptation_ind); + return STATUS_ERR; + } + } + return STATUS_OK; +} +#endif + static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { @@ -2394,6 +2415,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, free(live_optval); return STATUS_ERR; } +#endif +#ifdef SCTP_ADAPTATION_LAYER + } else if (val_expression->type == EXPR_SCTP_SETADAPTATION) { + live_optval = malloc(sizeof(struct sctp_setadaptation)); + live_optlen = sizeof(struct sctp_setadaptation); #endif } else { s32_bracketed_arg(args, 3, &script_optval, error); @@ -2489,6 +2515,13 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, free(live_optval); return STATUS_ERR; } +#endif +#ifdef SCTP_ADAPTATION_LAYER + } else if (val_expression->type == EXPR_SCTP_SETADAPTATION) { + if (check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error)) { + free(live_optval); + return STATUS_ERR; + } #endif } else { if (*(int*)live_optval != script_optval) { @@ -2536,6 +2569,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #ifdef SCTP_EVENT struct sctp_event event; #endif +#ifdef SCTP_ADAPTATION_LAYER + struct sctp_setadaptation setadaptation; +#endif #ifdef SCTP_PEER_ADDR_PARAMS struct sctp_paddrparams paddrparams; #ifdef linux @@ -2725,6 +2761,15 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, optval = &event; break; #endif +#ifdef SCTP_ADAPTATION_LAYER + case EXPR_SCTP_SETADAPTATION: + if (get_u32(val_expression->value.sctp_setadaptation->ssb_adaptation_ind, + &setadaptation.ssb_adaptation_ind, error)) { + return STATUS_ERR; + } + optval = &setadaptation; + break; +#endif #ifdef SCTP_PEER_ADDR_PARAMS case EXPR_SCTP_PEER_ADDR_PARAMS: paddrparams.spp_assoc_id = 0; diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 729475dbc498e2c35715bc25b304cccbe3ae39e0..43df660d900898db2a0a28e1867e6f401f970cf2 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -93,6 +93,10 @@ struct expression_type_entry expression_type_table[] = { #ifdef SCTP_EVENT { EXPR_SCTP_EVENT, "sctp_event" }, #endif +#ifdef SCTP_ADAPTATION_LAYER + { EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"}, +#endif + { NUM_EXPR_TYPES, NULL} }; @@ -389,6 +393,11 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_event->se_type); free_expression(expression->value.sctp_event->se_on); break; +#endif +#ifdef SCTP_ADAPTATION_LAYER + case EXPR_SCTP_SETADAPTATION: + free_expression(expression->value.sctp_setadaptation->ssb_adaptation_ind); + break; #endif case EXPR_WORD: assert(expression->value.string); @@ -950,6 +959,32 @@ static int evaluate_sctp_accocparams_expression(struct expression *in, } #endif +#ifdef SCTP_ADAPTATION_LAYER +static int evaluate_sctp_setadaptation_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_setadaptation_expr *in_adaptation; + struct sctp_setadaptation_expr *out_adaptation; + + assert(in->type == EXPR_SCTP_SETADAPTATION); + assert(in->value.sctp_setadaptation); + assert(out->type == EXPR_SCTP_SETADAPTATION); + + out->value.sctp_setadaptation = calloc(1, sizeof(struct sctp_setadaptation_expr)); + + in_adaptation = in->value.sctp_setadaptation; + out_adaptation = out->value.sctp_setadaptation; + + if (evaluate(in_adaptation->ssb_adaptation_ind, + &out_adaptation->ssb_adaptation_ind, + error)) + return STATUS_ERR; + + return STATUS_OK; +} +#endif + static int evaluate(struct expression *in, struct expression **out_ptr, char **error) { @@ -1020,6 +1055,11 @@ static int evaluate(struct expression *in, case EXPR_SCTP_EVENT: result = evaluate_sctp_event_expression(in, out, error); break; +#endif +#ifdef SCTP_ADAPTATION_LAYER + case EXPR_SCTP_SETADAPTATION: + result = evaluate_sctp_setadaptation_expression(in, out, error); + break; #endif case EXPR_WORD: out->type = EXPR_INTEGER; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 647155410aa1546803a380771d95800603369f59..3711795ebcbf12707db3d13d208e527ceca97ddb 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -73,6 +73,9 @@ enum expression_t { #endif #ifdef SCTP_EVENT EXPR_SCTP_EVENT, /* struct sctp_event to for SCTP_EVENT */ +#endif +#ifdef SCTP_ADAPTATION_LAYER + EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */ #endif NUM_EXPR_TYPES, }; @@ -121,6 +124,10 @@ struct expression { #ifdef SCTP_EVENT struct sctp_event_expr *sctp_event; #endif +#ifdef SCTP_ADAPTATION_LAYER + struct sctp_setadaptation_expr *sctp_setadaptation; +#endif + } value; const char *format; /* the printf format for printing the value */ }; @@ -255,13 +262,20 @@ struct sctp_assocparams_expr { #endif #ifdef SCTP_EVENT -/* Parse tree for sctp_enevt struct in [gs]etsockopt syscall. */ +/* Parse tree for sctp_event struct in [gs]etsockopt syscall. */ struct sctp_event_expr { struct expression *se_type; struct expression *se_on; }; #endif +#ifdef SCTP_ADAPTATION_LAYER +/* Parse tree for sctp_setadaptation struct in [gs]etsockopt syscall. */ +struct sctp_setadaptation_expr { + struct expression *ssb_adaptation_ind; +}; +#endif + /* The errno-related info from strace to summarize a system call error */ struct errno_spec { const char *errno_macro; /* errno symbol (C macro name) */ diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index 6576badbd3944cb5f44a30a2ac65e3d51ac8b7d1..779c8aab75642cd6cc36e9672eeb921c8959442f 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -83,6 +83,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_ASSOCINFO, "SCTP_ASSOCINFO" }, { SCTP_INITMSG, "SCTP_INITMSG" }, { SCTP_NODELAY, "SCTP_NODELAY" }, + { SCTP_ADAPTATION_LAYER, "SCTP_ADAPTATION_LAYER" }, { SCTP_MAXSEG, "SCTP_MAXSEG" }, { SCTP_DELAYED_SACK, "SCTP_DELAYED_SACK" }, { SCTP_MAX_BURST, "SCTP_MAX_BURST" }, diff --git a/gtests/net/packetdrill/symbols_linux.c b/gtests/net/packetdrill/symbols_linux.c index 2fe28908a2172b7a8af5d149567093eda86c77ae..2eccf3d26bf7885a913a4f28a14feff99cdc25b3 100644 --- a/gtests/net/packetdrill/symbols_linux.c +++ b/gtests/net/packetdrill/symbols_linux.c @@ -140,25 +140,37 @@ struct int_symbol platform_symbols_table[] = { { SPP_SACKDELAY_DISABLE, "SPP_SACKDELAY_DISABLE" }, #ifdef SCTP_ASSOC_CHANGE { SCTP_ASSOC_CHANGE, "SCTP_ASSOC_CHANGE" }, +#endif #ifdef SCTP_PEER_ADDR_CHANGE { SCTP_PEER_ADDR_CHANGE, "SCTP_PEER_ADDR_CHANGE" }, +#endif #ifdef SCTP_REMOTE_ERROR { SCTP_REMOTE_ERROR, "SCTP_REMOTE_ERROR" }, +#endif #ifdef SCTP_SEND_FAILED { SCTP_SEND_FAILED, "SCTP_SEND_FAILED" }, +#endif #ifdef SCTP_SHUTDOWN_EVENT { SCTP_SHUTDOWN_EVENT, "SCTP_SHUTDOWN_EVENT" }, +#endif #ifdef SCTP_ADAPTATION_INDICATION { SCTP_ADAPTATION_INDICATION, "SCTP_ADAPTATION_INDICATION" }, +#endif #ifdef SCTP_ADAPTION_INDICATION { SCTP_ADAPTION_INDICATION, "SCTP_ADAPTION_INDICATION" }, +#endif #ifdef SCTP_PARTIAL_DELIVERY_EVENT { SCTP_PARTIAL_DELIVERY_EVENT, "SCTP_PARTIAL_DELIVERY_EVENT" }, +#endif #ifdef SCTP_AUTHENTICATION_EVENT { SCTP_AUTHENTICATION_EVENT, "SCTP_AUTHENTICATION_EVENT" }, +#endif #ifdef SCTP_SENDER_DRY_EVENT { SCTP_SENDER_DRY_EVENT, "SCTP_SENDER_DRY_EVENT" }, - +#endif +#ifdef SCTP_ADAPTATION_LAYER + { SCTP_ADAPTATION_LAYER, "SCTP_ADAPTATION_LAYER" }, +#endif #if 0 { SPP_IPV6_FLOWLABEL, "SPP_IPV6_FLOWLABEL" }, { SPP_DSCP, "SPP_DSCP" }, 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 cf8dda781a11e14006c2d17d1802f7644ccd239f..7671c7d28cbf64f9a3e5c352a3fb7440006ff4bd 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 @@ -110,4 +110,7 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv +0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, {ssb_adaptation_ind=2}, 4) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, {ssb_adaptation_ind=2}, [4]) = 0 + +0 close(3) = 0