diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 92a6d22940649be7a0d5ba870c63e2876fd54c77..44f21cf7651573ea8430a22fde049007e3204613 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -242,6 +242,10 @@ 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; +snd_sid return SND_SID; +snd_flags return SND_FLAGS; +snd_ppid return SND_PPID; +snd_context return SND_CONTEXT; 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..ad885c86fd7e532133528db05c57b634293a3c4f 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -537,6 +537,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %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> SND_SID SND_FLAGS SND_PPID SND_CONTEXT %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -586,6 +587,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %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_sndinfo snd_sid snd_flags snd_ppid snd_context %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2374,6 +2376,9 @@ expression | sctp_event { $$ = $1; } +| sctp_sndinfo { + $$ = $1; +} ; decimal_integer @@ -3005,6 +3010,65 @@ sctp_event } ; +snd_sid +: SND_SID '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("snd_sid out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SND_SID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +snd_flags +: SND_FLAGS '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("snd_flags out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SND_FLAGS '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| SND_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +snd_ppid +: SND_PPID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("snd_ppid out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SND_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +snd_context +: SND_CONTEXT '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("snd_context out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SND_CONTEXT '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_sndinfo +: '{' snd_sid ',' snd_flags ',' snd_ppid ',' snd_context '}' { +#ifdef SCTP_DEFAULT_SNDINFO + $$ = new_expression(EXPR_SCTP_SNDINFO); + $$->value.sctp_sndinfo = calloc(1, sizeof(struct sctp_sndinfo)); + $$->value.sctp_sndinfo->snd_sid = $2; + $$->value.sctp_sndinfo->snd_flags = $4; + $$->value.sctp_sndinfo->snd_ppid = $6; + $$->value.sctp_sndinfo->snd_context = $8; +#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..af50fa71c34aa08993d57b935617820d0ccae2a5 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -2257,6 +2257,63 @@ static int check_sctp_event(struct sctp_event_expr *expr, } #endif +#ifdef SCTP_DEFAULT_SNDINFO +static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr, + struct sctp_sndinfo *sctp_sndinfo, + char **error) +{ + if (expr->snd_sid->type != EXPR_ELLIPSIS) { + u16 snd_sid; + + if (get_u16(expr->snd_sid, &snd_sid, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_sid != snd_sid) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_sid: expected: %hu actual: %hu", + snd_sid, sctp_sndinfo->snd_sid); + return STATUS_ERR; + } + } + if (expr->snd_flags->type != EXPR_ELLIPSIS) { + u16 snd_flags; + + if (get_u16(expr->snd_flags, &snd_flags, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_flags != snd_flags) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_flags: expected: %hu actual: %hu", + snd_flags, sctp_sndinfo->snd_flags); + return STATUS_ERR; + } + } + if (expr->snd_ppid->type != EXPR_ELLIPSIS) { + u32 snd_ppid; + + if (get_u32(expr->snd_ppid, &snd_ppid, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_ppid != snd_ppid) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_ppid: expected: %u actual: %u", + snd_ppid, sctp_sndinfo->snd_ppid); + return STATUS_ERR; + } + } + if (expr->snd_context->type != EXPR_ELLIPSIS) { + u32 snd_context; + + if (get_u32(expr->snd_context, &snd_context, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_context != snd_context) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_context: expected: %u actual: %u", + snd_context, sctp_sndinfo->snd_context); + 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 +2451,12 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, free(live_optval); return STATUS_ERR; } +#endif +#ifdef SCTP_DEFAULT_SNDINFO + } else if (val_expression->type == EXPR_SCTP_SNDINFO) { + live_optval = malloc(sizeof(struct sctp_sndinfo)); + live_optlen = sizeof(struct sctp_sndinfo); + ((struct sctp_sndinfo *)live_optval)->snd_assoc_id = 0; #endif } else { s32_bracketed_arg(args, 3, &script_optval, error); @@ -2489,6 +2552,13 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, free(live_optval); return STATUS_ERR; } +#endif +#ifdef SCTP_DEFAULT_SNDINFO + } else if (val_expression->type == EXPR_SCTP_SNDINFO) { + if (check_sctp_sndinfo(val_expression->value.sctp_sndinfo, live_optval, error)) { + free(live_optval); + return STATUS_ERR; + } #endif } else { if (*(int*)live_optval != script_optval) { @@ -2536,6 +2606,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #ifdef SCTP_EVENT struct sctp_event event; #endif +#ifdef SCTP_DEFAULT_SNDINFO + struct sctp_sndinfo sndinfo; +#endif #ifdef SCTP_PEER_ADDR_PARAMS struct sctp_paddrparams paddrparams; #ifdef linux @@ -2713,11 +2786,6 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #endif #ifdef SCTP_EVENT case EXPR_SCTP_EVENT: - event.se_assoc_id = 0; - if (get_u16(val_expression->value.sctp_event->se_type, - &event.se_type, error)) { - return STATUS_ERR; - } if (get_u8(val_expression->value.sctp_event->se_on, &event.se_on, error)) { return STATUS_ERR; @@ -2725,6 +2793,28 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, optval = &event; break; #endif +#ifdef SCTP_DEFAULT_SNDINFO + case EXPR_SCTP_SNDINFO: + sndinfo.snd_assoc_id = 0; + if (get_u16(val_expression->value.sctp_sndinfo->snd_sid, + &sndinfo.snd_sid, error)) { + return STATUS_ERR; + } + if (get_u16(val_expression->value.sctp_sndinfo->snd_flags, + &sndinfo.snd_flags, error)) { + return STATUS_ERR; + } + if (get_u32(val_expression->value.sctp_sndinfo->snd_ppid, + &sndinfo.snd_ppid, error)) { + return STATUS_ERR; + } + if (get_u32(val_expression->value.sctp_sndinfo->snd_context, + &sndinfo.snd_context, error)) { + return STATUS_ERR; + } + optval = &sndinfo; + 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..509d8dd7f349268a1a9d571d4dc9638e8bfcec8e 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -92,6 +92,9 @@ struct expression_type_entry expression_type_table[] = { #endif #ifdef SCTP_EVENT { EXPR_SCTP_EVENT, "sctp_event" }, +#endif +#ifdef SCTP_DEFAULT_SNDINFO + { EXPR_SCTP_SNDINFO, "sctp_sndinfo" }, #endif { NUM_EXPR_TYPES, NULL} }; @@ -389,6 +392,14 @@ 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_DEFAULT_SNDINFO + case EXPR_SCTP_SNDINFO: + free_expression(expression->value.sctp_sndinfo->snd_sid); + free_expression(expression->value.sctp_sndinfo->snd_flags); + free_expression(expression->value.sctp_sndinfo->snd_ppid); + free_expression(expression->value.sctp_sndinfo->snd_context); + break; #endif case EXPR_WORD: assert(expression->value.string); @@ -950,6 +961,43 @@ static int evaluate_sctp_accocparams_expression(struct expression *in, } #endif +#ifdef SCTP_DEFAULT_SNDINFO +static int evaluate_sctp_sndinfo_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_sndinfo_expr *in_sndinfo; + struct sctp_sndinfo_expr *out_sndinfo; + + assert(in->type == EXPR_SCTP_SNDINFO); + assert(in->value.sctp_sndinfo); + assert(out->type == EXPR_SCTP_SNDINFO); + + out->value.sctp_sndinfo = calloc(1, sizeof(struct sctp_sndinfo_expr)); + + in_sndinfo = in->value.sctp_sndinfo; + out_sndinfo = out->value.sctp_sndinfo; + + if (evaluate(in_sndinfo->snd_sid, + &out_sndinfo->snd_sid, + error)) + return STATUS_ERR; + if (evaluate(in_sndinfo->snd_flags, + &out_sndinfo->snd_flags, + error)) + return STATUS_ERR; + if (evaluate(in_sndinfo->snd_ppid, + &out_sndinfo->snd_ppid, + error)) + return STATUS_ERR; + if (evaluate(in_sndinfo->snd_context, + &out_sndinfo->snd_context, + error)) + return STATUS_ERR; + return STATUS_OK; + } +#endif + static int evaluate(struct expression *in, struct expression **out_ptr, char **error) { @@ -1020,6 +1068,11 @@ static int evaluate(struct expression *in, case EXPR_SCTP_EVENT: result = evaluate_sctp_event_expression(in, out, error); break; +#endif +#ifdef SCTP_DEFAULT_SNDINFO + case EXPR_SCTP_SNDINFO: + result = evaluate_sctp_sndinfo_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..a7fb722cbb922698ff69e90cd9313ce6e29e0f92 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -72,7 +72,10 @@ enum expression_t { EXPR_SCTP_ASSOCPARAMS, /* struct sctp_assocparams for SCTP_ASSOCINFO */ #endif #ifdef SCTP_EVENT - EXPR_SCTP_EVENT, /* struct sctp_event to for SCTP_EVENT */ + EXPR_SCTP_EVENT, /* struct sctp_event for SCTP_EVENT */ +#endif +#ifdef SCTP_DEFAULT_SNDINFO + EXPR_SCTP_SNDINFO, /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */ #endif NUM_EXPR_TYPES, }; @@ -120,6 +123,9 @@ struct expression { #endif #ifdef SCTP_EVENT struct sctp_event_expr *sctp_event; +#endif +#ifdef SCTP_DEFAULT_SNDINFO + struct sctp_sndinfo_expr *sctp_sndinfo; #endif } value; const char *format; /* the printf format for printing the value */ @@ -262,6 +268,16 @@ struct sctp_event_expr { }; #endif +#ifdef SCTP_DEFAULT_SNDINFO +/* Parse tree for sctp_sndinfo struct in [gs]etsockopt syscall. */ +struct sctp_sndinfo_expr { + struct expression *snd_sid; + struct expression *snd_flags; + struct expression *snd_ppid; + struct expression *snd_context; +}; +#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..cfc45973cbbc1965673aeafb3f63651b630ff7ed 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -88,6 +88,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_MAX_BURST, "SCTP_MAX_BURST" }, { SCTP_PEER_ADDR_PARAMS, "SCTP_PEER_ADDR_PARAMS" }, { SCTP_EVENT, "SCTP_EVENT" }, + { SCTP_DEFAULT_SNDINFO, "SCTP_DEFAULT_SNDINFO" }, { SCTP_STATUS, "SCTP_STATUS" }, { SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" }, { SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" }, @@ -176,6 +177,12 @@ struct int_symbol platform_symbols_table[] = { { SCTP_ASSOC_RESET_EVENT, "SCTP_ASSOC_RESET_EVENT" }, { SCTP_STREAM_CHANGE_EVENT, "SCTP_STREAM_CHANGE_EVENT" }, { SCTP_SEND_FAILED_EVENT, "SCTP_SEND_FAILED_EVENT" }, + { SCTP_UNORDERED, "SCTP_UNORDERED" }, + { SCTP_ADDR_OVER, "SCTP_ADDR_OVER" }, + { SCTP_ABORT, "SCTP_ABORT" }, + { SCTP_EOF, "SCTP_EOF" }, + { SCTP_SENDALL, "SCTP_SENDALL" }, + /* /usr/include/netinet/tcp.h */ { TCP_NODELAY, "TCP_NODELAY" }, { TCP_MAXSEG, "TCP_MAXSEG" }, diff --git a/gtests/net/packetdrill/symbols_linux.c b/gtests/net/packetdrill/symbols_linux.c index 2fe28908a2172b7a8af5d149567093eda86c77ae..66f54bae7e29c4cbfd9870cdefd58673db3b0435 100644 --- a/gtests/net/packetdrill/symbols_linux.c +++ b/gtests/net/packetdrill/symbols_linux.c @@ -140,24 +140,34 @@ 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 #if 0 { SPP_IPV6_FLOWLABEL, "SPP_IPV6_FLOWLABEL" }, 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..6d8246efc77f1074e3233e4351307934df4a4d7d 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 @@ -107,6 +107,8 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv +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 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=0, snd_ppid=0, snd_context=0}, [16]) = 0 + +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