diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index fdb44cee35561ae2acb22dda80adef64199016f9..cc958793bbee6e63a645444cdec2d2300a85e9e2 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -291,6 +291,10 @@ recvv_nxtinfo return RECVV_NXTINFO; sse_type return SSE_TYPE; sse_flags return SSE_FLAGS; sse_length return SSE_LENGTH; +sender_dry_type return SENDER_DRY_TYPE; +sender_dry_flags return SENDER_DRY_FLAGS; +sender_dry_length return SENDER_DRY_LENGTH; +sender_dry_assoc_id return SENDER_DRY_ASSOC_ID; CHUNK return CHUNK; DATA return DATA; INIT return INIT; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 344826a81c11729b3bc2c8455968157078dfd886..2f413edc0b8fc5f310c5244117b30deae8432d22 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -548,6 +548,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> NXT_SID NXT_FLAGS NXT_PPID NXT_LENGTH %token <reserved> RECVV_RCVINFO RECVV_NXTINFO %token <reserved> SSE_TYPE SSE_FLAGS SSE_LENGTH +%token <reserved> SENDER_DRY_TYPE SENDER_DRY_FLAGS SENDER_DRY_LENGTH SENDER_DRY_ASSOC_ID %token <rexerved> _SCTP_DATA_IO_EVENT_ _SCTP_ASSOCIATION_EVENT_ _SCTP_ADDRESS_EVENT_ %token <reserved> _SCTP_SEND_FAILURE_EVENT_ _SCTP_PEER_ERROR_EVENT_ _SCTP_SHUTDOWN_EVENT_ %token <reserved> _SCTP_PARTIAL_DELIVERY_EVENT_ _SCTP_ADAPTATION_LAYER_EVENT_ @@ -608,6 +609,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_rcvinfo rcv_sid rcv_ssn rcv_flags rcv_ppid rcv_tsn rcv_cumtsn rcv_context %type <expression> sctp_nxtinfo nxt_sid nxt_flags nxt_ppid nxt_length sctp_recvv_rn %type <expression> sctp_shutdown_event sse_type sse_flags sse_length +%type <expression> sctp_sender_dry_event sender_dry_type sender_dry_flags sender_dry_length sender_dry_assoc_id %type <expression> sctp_event_subscribe %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec @@ -2584,6 +2586,7 @@ sockaddr data : ELLIPSIS { new_expression(EXPR_ELLIPSIS); } | sctp_shutdown_event { $$ = $1; } +| sctp_sender_dry_event { $$ = $1; } ; msghdr @@ -3569,6 +3572,61 @@ sctp_shutdown_event $$->value.sctp_shutdown_event->sse_length = $6; }; +sender_dry_type +: SENDER_DRY_TYPE '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("sender_dry_type out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SENDER_DRY_TYPE '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| SENDER_DRY_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sender_dry_flags +: SENDER_DRY_FLAGS '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("sender_dry_flags out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SENDER_DRY_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sender_dry_length +: SENDER_DRY_LENGTH '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("sender_dry_length out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SENDER_DRY_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sender_dry_assoc_id +: SENDER_DRY_ASSOC_ID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("sender_dry_assoc_id out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SENDER_DRY_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_sender_dry_event +: '{'sender_dry_type ',' sender_dry_flags ',' sender_dry_length ',' sender_dry_assoc_id '}' { + $$ = new_expression(EXPR_SCTP_SENDER_DRY_EVENT); + $$->value.sctp_sender_dry_event = calloc(1, sizeof(struct sctp_sender_dry_event_expr)); + $$->value.sctp_sender_dry_event->sender_dry_type = $2; + $$->value.sctp_sender_dry_event->sender_dry_flags = $4; + $$->value.sctp_sender_dry_event->sender_dry_length = $6; + $$->value.sctp_sender_dry_event->sender_dry_assoc_id = $8; +} +; + opt_errno : { $$ = NULL; } | WORD note { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index db8e46ca27c804c4eba886630ee41e9a0c8e3c1d..cb55f62bd17cd35f328f33432930b0b6a8c243e1 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -460,7 +460,8 @@ static int iovec_new(struct expression *expression, iov_expr = list->expression->value.iovec; assert(iov_expr->iov_base->type == EXPR_ELLIPSIS || - iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT); + iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT || + iov_expr->iov_base->type == EXPR_SCTP_SENDER_DRY_EVENT); assert(iov_expr->iov_len->type == EXPR_INTEGER); len = iov_expr->iov_len->value.num; @@ -3918,6 +3919,62 @@ static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr, return STATUS_OK; } #endif +#ifdef __FreeBSD__ +static int check_sctp_sender_dry_event(struct sctp_sender_dry_event_expr *expr, + struct sctp_sender_dry_event *sctp_event, + char **error) { + if (expr->sender_dry_type->type != EXPR_ELLIPSIS) { + u16 sender_dry_type; + + if (get_u16(expr->sender_dry_type, &sender_dry_type, error)) { + return STATUS_ERR; + } + if (sctp_event->sender_dry_type != sender_dry_type) { + asprintf(error, "sctp_sender_dry_event.sender_dry_type: expected: %hu actual: %hu", + sender_dry_type, sctp_event->sender_dry_type); + return STATUS_ERR; + } + } + if (expr->sender_dry_flags->type != EXPR_ELLIPSIS) { + u16 sender_dry_flags; + + if (get_u16(expr->sender_dry_flags, &sender_dry_flags, error)) { + return STATUS_ERR; + } + if (sctp_event->sender_dry_flags != sender_dry_flags) { + asprintf(error, "sctp_sender_dry_event.sender_dry_flags: expected: %hu actual: %hu", + sender_dry_flags, sctp_event->sender_dry_flags); + return STATUS_ERR; + } + } + if (expr->sender_dry_type->type != EXPR_ELLIPSIS) { + u32 sender_dry_length; + + if (get_u32(expr->sender_dry_length, &sender_dry_length, error)) { + return STATUS_ERR; + } + if (sctp_event->sender_dry_length != sender_dry_length) { + asprintf(error, "sctp_sender_dry_event.sender_dry_length: expected: %u actual: %u", + sender_dry_length, sctp_event->sender_dry_length); + return STATUS_ERR; + } + } + if (expr->sender_dry_assoc_id->type != EXPR_ELLIPSIS) { + u32 sender_dry_assoc_id; + + if (get_u32(expr->sender_dry_assoc_id, &sender_dry_assoc_id, error)) { + return STATUS_ERR; + } + if (sctp_event->sender_dry_assoc_id != sender_dry_assoc_id) { + asprintf(error, "sctp_sender_dry_event.sender_dry_assoc_id: expected: %u actual: %u", + sender_dry_assoc_id, sctp_event->sender_dry_assoc_id); + return STATUS_ERR; + } + } + + return STATUS_OK; +} +#endif #if defined(__FreeBSD__) static int check_sctp_notification(struct iovec *iov, @@ -3943,6 +4000,12 @@ static int check_sctp_notification(struct iovec *iov, error)) return STATUS_ERR; break; + case EXPR_SCTP_SENDER_DRY_EVENT: + if (check_sctp_sender_dry_event(script_iov_base->value.sctp_sender_dry_event, + (struct sctp_sender_dry_event *) iov->iov_base, + error)) + return STATUS_ERR; + break; case EXPR_ELLIPSIS: break; default: diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 9f162ddf5f8eee300a0f0ac97c1719674728af61..d81e4e5b992944c68c32cf08db96ee094222c5d3 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -87,6 +87,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_NXTINFO, "sctp_nxtinfo" }, { EXPR_SCTP_RECVV_RN, "sctp_recvv_rn " }, { EXPR_SCTP_SHUTDOWN_EVENT, "sctp_shutdown_event"}, + { EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"}, { NUM_EXPR_TYPES, NULL} }; @@ -435,6 +436,12 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_shutdown_event->sse_flags); free_expression(expression->value.sctp_shutdown_event->sse_length); break; + case EXPR_SCTP_SENDER_DRY_EVENT: + free_expression(expression->value.sctp_sender_dry_event->sender_dry_type); + free_expression(expression->value.sctp_sender_dry_event->sender_dry_flags); + free_expression(expression->value.sctp_sender_dry_event->sender_dry_length); + free_expression(expression->value.sctp_sender_dry_event->sender_dry_assoc_id); + break; case EXPR_WORD: assert(expression->value.string); free(expression->value.string); @@ -1378,6 +1385,42 @@ static int evaluate_sctp_shutdown_event_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_sender_dry_event_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_sender_dry_event_expr *in_event; + struct sctp_sender_dry_event_expr *out_event; + + assert(in->type == EXPR_SCTP_SENDER_DRY_EVENT); + assert(in->value.sctp_sender_dry_event); + assert(out->type == EXPR_SCTP_SENDER_DRY_EVENT); + + out->value.sctp_sender_dry_event = calloc(1, sizeof(struct sctp_sender_dry_event_expr)); + + in_event = in->value.sctp_sender_dry_event; + out_event = out->value.sctp_sender_dry_event; + + if (evaluate(in_event->sender_dry_type, + &out_event->sender_dry_type, + error)) + return STATUS_ERR; + if (evaluate(in_event->sender_dry_flags, + &out_event->sender_dry_flags, + error)) + return STATUS_ERR; + if (evaluate(in_event->sender_dry_length, + &out_event->sender_dry_length, + error)) + return STATUS_ERR; + if (evaluate(in_event->sender_dry_assoc_id, + &out_event->sender_dry_assoc_id, + error)) + return STATUS_ERR; + + return STATUS_OK; +} + static int evaluate(struct expression *in, struct expression **out_ptr, char **error) { @@ -1466,6 +1509,9 @@ static int evaluate(struct expression *in, case EXPR_SCTP_SHUTDOWN_EVENT: result = evaluate_sctp_shutdown_event_expression(in, out, error); break; + case EXPR_SCTP_SENDER_DRY_EVENT: + result = evaluate_sctp_sender_dry_event_expression(in, out, error); + break; case EXPR_WORD: out->type = EXPR_INTEGER; if (symbol_to_int(in->value.string, diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 95ca7231b944ca261927844a5aef633c0b0ffff8..fbcf3009cdb2b57fd4b28b860359005638fa742d 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -67,6 +67,7 @@ enum expression_t { EXPR_SCTP_NXTINFO, /* struct sctp_nxtinfo for syscall sctp_recvv */ EXPR_SCTP_RECVV_RN, /* struct sctp_recvv_rn for syscall sctp_recvv */ EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */ + EXPR_SCTP_SENDER_DRY_EVENT, /* expression tree for sctp_sender_dry_event */ NUM_EXPR_TYPES, }; /* Convert an expression type to a human-readable string */ @@ -107,6 +108,7 @@ struct expression { struct sctp_nxtinfo_expr *sctp_nxtinfo; struct sctp_recvv_rn_expr *sctp_recvv_rn; struct sctp_shutdown_event_expr *sctp_shutdown_event; + struct sctp_sender_dry_event_expr *sctp_sender_dry_event; } value; const char *format; /* the printf format for printing the value */ }; @@ -324,6 +326,14 @@ struct sctp_shutdown_event_expr { struct expression *sse_length; }; +/* Parse tree for sctp_shutdown_event for notifications. */ +struct sctp_sender_dry_event_expr { + struct expression *sender_dry_type; + struct expression *sender_dry_flags; + struct expression *sender_dry_length; + struct expression *sender_dry_assoc_id; +}; + /* 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 8f8bd758060100cac0c0075508e1b80ab12ed73d..63c501f5939789880e159c2c3960aac22e2550f6 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -169,6 +169,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_REMOTE_ERROR, "SCTP_REMOTE_ERROR" }, { SCTP_SEND_FAILED, "SCTP_SEND_FAILED" }, { SCTP_SHUTDOWN_EVENT, "SCTP_SHUTDOWN_EVENT" }, + { SCTP_SENDER_DRY_EVENT, "SCTP_SENDER_DRY_EVENT" }, { SCTP_ADAPTATION_INDICATION, "SCTP_ADAPTATION_INDICATION" }, { SCTP_ADAPTION_INDICATION, "SCTP_ADAPTION_INDICATION" }, { SCTP_PARTIAL_DELIVERY_EVENT, "SCTP_PARTIAL_DELIVERY_EVENT" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt index d6662b3851cc802630a15a777b6fe4678a05de0c..df4d613cf608fd9e3fff382cd06609dc75d907b5 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_notifications.pkt @@ -10,6 +10,26 @@ +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 //enable shutdown events +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0 ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0 ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=0}, 8) = 0 ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=0}, [8]) = 0 + ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENTS, {sctp_data_io_event=1, sctp_association_event=1, sctp_address_event=0, sctp_send_failure_event=1, +sctp_peer_error_event=0, sctp_shutdown_event=1, sctp_partial_delivery_event=0, sctp_adaptation_layer_event=0, sctp_authentication_event=0, +sctp_sender_dry_event=0}, 11) = 0 ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0 ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENTS, {sctp_data_io_event=1, sctp_association_event=1, sctp_address_event=0, sctp_send_failure_event=1, +sctp_peer_error_event=0, sctp_shutdown_event=0, sctp_partial_delivery_event=0, sctp_adaptation_layer_event=0, sctp_authentication_event=0, +sctp_sender_dry_event=0}, 11) = 0 + ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SENDER_DRY_EVENT, se_on=1}, 8) = 0 ++0.0 sctp_recvv(3, [{iov_base={sender_dry_type=SCTP_SENDER_DRY_EVENT, sender_dry_flags=0, sender_dry_length=12, sender_dry_assoc_id=3}, iov_len=1000}], 1, +..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 12 + + + ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=0}, [8]) = 0 ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0 // Tear down the association +0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0] * > sctp: SHUTDOWN_ACK[flgs=0]