diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index cc94918d6ffe3730631e20d34a9f0f903caf2fcb..26d04437c01b4d235a13dd6092c48e2ae8adc321 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -322,6 +322,13 @@ 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; +pdapi_type return PDAPI_TYPE; +pdapi_flags return PDAPI_FLAGS; +pdapi_length return PDAPI_LENGTH; +pdapi_indication return PDAPI_INDICATION; +pdapi_stream return PDAPI_STREAM; +pdapi_seq return PDAPI_SEQ; +pdapi_assoc_id return PDAPI_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 04d2e4aa75e2c1160249d7c5560ca945aa1d2fc0..448638be8cb202fde0d4b306713924f330698bf0 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -557,7 +557,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SAC_INBOUND_STREAMS SAC_ASSOC_ID SAC_INFO %token <reserved> SSFE_TYPE SSFE_FLAGS SSFE_LENGTH SSFE_ERROR SSFE_INFO SSFE_ASSOC_ID SSFE_DATA %token <reserved> AUTH_TYPE AUTH_FLAGS AUTH_LENGTH AUTH_INDICATION AUTH_ASSOC_ID -%token <reserved> SRE_TYPE SRE_FLAGS SRE_LENGTH SRE_ERROR SRE_ASSOC_ID SRE_DATA +%token <reserved> SRE_TYPE SRE_FLAGS SRE_LENGTH SRE_ERROR SRE_ASSOC_ID SRE_DATA PDAPI_ASSOC_ID +%token <reserved> PDAPI_TYPE PDAPI_FLAGS PDAPI_LENGTH PDAPI_INDICATION PDAPI_STREAM PDAPI_SEQ %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -621,6 +622,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_send_failed_event ssfe_type ssfe_flags ssfe_length ssfe_error ssfe_assoc_id ssfe_data %type <expression> sctp_authkey_event auth_type auth_flags auth_length auth_keynumber auth_indication auth_assoc_id %type <expression> sctp_remote_error sre_type sre_flags sre_length sre_error sre_assoc_id sre_data +%type <expression> sctp_pdapi_event pdapi_type pdapi_flags pdapi_length pdapi_indication pdapi_stream pdapi_seq pdapi_assoc_id %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2594,10 +2596,11 @@ sockaddr ; data -: ELLIPSIS { new_expression(EXPR_ELLIPSIS); } +: ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } | sctp_assoc_change { $$ = $1; } | sctp_remote_error { $$ = $1; } | sctp_shutdown_event { $$ = $1; } +| sctp_pdapi_event { $$ = $1; } | sctp_sender_dry_event { $$ = $1; } | sctp_send_failed_event { $$ = $1; } | sctp_authkey_event { $$ = $1; } @@ -3586,6 +3589,97 @@ sctp_shutdown_event $$->value.sctp_shutdown_event->sse_length = $6; }; +pdapi_type +: PDAPI_TYPE '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("pdapi_type out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| PDAPI_TYPE '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| PDAPI_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; +pdapi_flags +: PDAPI_FLAGS '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("pdapi_flags out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| PDAPI_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +pdapi_length +: PDAPI_LENGTH '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("pdapi_length out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| PDAPI_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +pdapi_indication +: PDAPI_INDICATION '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("pdapi_indication out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| PDAPI_INDICATION '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| PDAPI_INDICATION '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +pdapi_stream +: PDAPI_STREAM '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("pdapi_stream out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| PDAPI_STREAM '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +pdapi_seq +: PDAPI_SEQ '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("pdapi_seq out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| PDAPI_SEQ '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +pdapi_assoc_id +: PDAPI_ASSOC_ID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("pdapi_assoc_id out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| PDAPI_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_pdapi_event +: '{' pdapi_type',' pdapi_flags ',' pdapi_length ',' pdapi_indication ',' pdapi_stream ',' pdapi_seq ',' pdapi_assoc_id '}' { + $$ = new_expression(EXPR_SCTP_PDAPI_EVENT); + $$->value.sctp_pdapi_event = calloc(1, sizeof(struct sctp_pdapi_event_expr)); + $$->value.sctp_pdapi_event->pdapi_type = $2; + $$->value.sctp_pdapi_event->pdapi_flags = $4; + $$->value.sctp_pdapi_event->pdapi_length = $6; + $$->value.sctp_pdapi_event->pdapi_indication = $8; + $$->value.sctp_pdapi_event->pdapi_stream = $10; + $$->value.sctp_pdapi_event->pdapi_seq = $12; + $$->value.sctp_pdapi_event->pdapi_assoc_id = $14; +} +; + auth_type : AUTH_TYPE '=' INTEGER { if (!is_valid_u16($3)) { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 15d1f85ad3a8469cf48e5c8d59f635869f1a0566..b5fc2103bf33917c52697f61736f4297c828f5a4 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -571,6 +571,7 @@ static int iovec_new(struct expression *expression, iov_expr->iov_base->type == EXPR_SCTP_ASSOC_CHANGE || iov_expr->iov_base->type == EXPR_SCTP_REMOTE_ERROR || iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT || + iov_expr->iov_base->type == EXPR_SCTP_PDAPI_EVENT || iov_expr->iov_base->type == EXPR_SCTP_AUTHKEY_EVENT || iov_expr->iov_base->type == EXPR_SCTP_SENDER_DRY_EVENT || iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED_EVENT); @@ -3464,6 +3465,37 @@ static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr, } #endif +#if defined(__FreeBSD__) || defined(linux) +static int check_sctp_pdapi_event(struct sctp_pdapi_event_expr *expr, + struct sctp_pdapi_event *sctp_event, + char **error) { + + if (check_u16_expr(expr->pdapi_type, sctp_event->pdapi_type, + "sctp_pdapi_event.pdapi_type", error)) + return STATUS_ERR; + if (check_u16_expr(expr->pdapi_flags, sctp_event->pdapi_flags, + "sctp_pdapi_event.pdapi_flags", error)) + return STATUS_ERR; + if (check_u32_expr(expr->pdapi_length, sctp_event->pdapi_length, + "sctp_pdapi_event.pdapi_length", error)) + return STATUS_ERR; + if (check_u32_expr(expr->pdapi_indication, sctp_event->pdapi_indication, + "sctp_pdapi_event.pdapi_indication", error)) + return STATUS_ERR; + if (check_u32_expr(expr->pdapi_stream, sctp_event->pdapi_stream, + "sctp_pdapi_event.pdapi_stream", error)) + return STATUS_ERR; + if (check_u32_expr(expr->pdapi_seq, sctp_event->pdapi_seq, + "sctp_pdapi_event.pdapi_seq", error)) + return STATUS_ERR; + if (check_u32_expr(expr->pdapi_assoc_id, sctp_event->pdapi_assoc_id, + "sctp_pdapi_event.pdapi_assoc_id", error)) + return STATUS_ERR; + + return STATUS_OK; +} +#endif + #if defined(__FreeBSD__) || defined(linux) static int check_sctp_authkey_event(struct sctp_authkey_event_expr *expr, struct sctp_authkey_event *sctp_event, @@ -3566,43 +3598,51 @@ static int check_sctp_notification(struct iovec *iov, switch (script_iov_base->type) { case EXPR_SCTP_ASSOC_CHANGE: if (check_sctp_assoc_change(script_iov_base->value.sctp_assoc_change, - (struct sctp_assoc_change *) iov->iov_base, + (struct sctp_assoc_change *) iov[i].iov_base, error)) return STATUS_ERR; break; case EXPR_SCTP_REMOTE_ERROR: if (check_sctp_remote_error(script_iov_base->value.sctp_remote_error, - (struct sctp_remote_error *) iov->iov_base, + (struct sctp_remote_error *) iov[i].iov_base, error)) return STATUS_ERR; break; case EXPR_SCTP_SHUTDOWN_EVENT: if (check_sctp_shutdown_event(script_iov_base->value.sctp_shutdown_event, - (struct sctp_shutdown_event *) iov->iov_base, + (struct sctp_shutdown_event *) iov[i].iov_base, + error)) + return STATUS_ERR; + break; + case EXPR_SCTP_PDAPI_EVENT: + printf("check PDAPI\n"); + if (check_sctp_pdapi_event(script_iov_base->value.sctp_pdapi_event, + (struct sctp_pdapi_event *) iov[i].iov_base, error)) return STATUS_ERR; break; case EXPR_SCTP_AUTHKEY_EVENT: if (check_sctp_authkey_event(script_iov_base->value.sctp_authkey_event, - (struct sctp_authkey_event *) iov->iov_base, + (struct sctp_authkey_event *) iov[i].iov_base, 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, + (struct sctp_sender_dry_event *) iov[i].iov_base, error)) return STATUS_ERR; break; #if defined(__FreeBSD__) case EXPR_SCTP_SEND_FAILED_EVENT: if (check_sctp_send_failed_event(script_iov_base->value.sctp_send_failed_event, - (struct sctp_send_failed_event *) iov->iov_base, + (struct sctp_send_failed_event *) iov[i].iov_base, error)) return STATUS_ERR; break; #endif case EXPR_ELLIPSIS: + printf("check Ellipsis\n"); break; default: asprintf(error, "Bad type for iov_base. Can't check type %s", diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 0ed1f1e636c5bf5c0eec13b11fca5826caa4754e..a48423c5d0d37e1ac821b7f01655a60313e10384 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -89,6 +89,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_ASSOC_CHANGE, "sctp_assoc_change"}, { EXPR_SCTP_REMOTE_ERROR, "sctp_remote_error"}, { EXPR_SCTP_SHUTDOWN_EVENT, "sctp_shutdown_event"}, + { EXPR_SCTP_PDAPI_EVENT, "sctp_pdapi_event"}, { EXPR_SCTP_AUTHKEY_EVENT, "sctp_authkey_event"}, { EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"}, { EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"}, @@ -459,6 +460,15 @@ 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_PDAPI_EVENT: + free_expression(expression->value.sctp_pdapi_event->pdapi_type); + free_expression(expression->value.sctp_pdapi_event->pdapi_flags); + free_expression(expression->value.sctp_pdapi_event->pdapi_length); + free_expression(expression->value.sctp_pdapi_event->pdapi_indication); + free_expression(expression->value.sctp_pdapi_event->pdapi_stream); + free_expression(expression->value.sctp_pdapi_event->pdapi_seq); + free_expression(expression->value.sctp_pdapi_event->pdapi_assoc_id); + break; case EXPR_SCTP_AUTHKEY_EVENT: free_expression(expression->value.sctp_authkey_event->auth_type); free_expression(expression->value.sctp_authkey_event->auth_flags); @@ -1524,6 +1534,54 @@ static int evaluate_sctp_shutdown_event_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_pdapi_event_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_pdapi_event_expr *in_event; + struct sctp_pdapi_event_expr *out_event; + + assert(in->type == EXPR_SCTP_PDAPI_EVENT); + assert(in->value.sctp_pdapi_event); + assert(out->type == EXPR_SCTP_PDAPI_EVENT); + + out->value.sctp_pdapi_event = calloc(1, sizeof(struct sctp_pdapi_event_expr)); + + in_event = in->value.sctp_pdapi_event; + out_event = out->value.sctp_pdapi_event; + + if (evaluate(in_event->pdapi_type, + &out_event->pdapi_type, + error)) + return STATUS_ERR; + if (evaluate(in_event->pdapi_flags, + &out_event->pdapi_flags, + error)) + return STATUS_ERR; + if (evaluate(in_event->pdapi_length, + &out_event->pdapi_length, + error)) + return STATUS_ERR; + if (evaluate(in_event->pdapi_indication, + &out_event->pdapi_indication, + error)) + return STATUS_ERR; + if (evaluate(in_event->pdapi_stream, + &out_event->pdapi_stream, + error)) + return STATUS_ERR; + if (evaluate(in_event->pdapi_seq, + &out_event->pdapi_seq, + error)) + return STATUS_ERR; + if (evaluate(in_event->pdapi_assoc_id, + &out_event->pdapi_assoc_id, + error)) + return STATUS_ERR; + + return STATUS_OK; +} + static int evaluate_sctp_authkey_event_expression(struct expression *in, struct expression *out, char **error) @@ -1746,6 +1804,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_PDAPI_EVENT: + result = evaluate_sctp_pdapi_event_expression(in, out, error); + break; case EXPR_SCTP_AUTHKEY_EVENT: result = evaluate_sctp_authkey_event_expression(in, out, error); break; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 82e269719df2aa46cb264ef5b702f7af173e2003..c88287efca23aa6a352b3c96034c7fd5a77f7d45 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -69,6 +69,7 @@ enum expression_t { EXPR_SCTP_ASSOC_CHANGE, /* expression tree for sctp_assoc_change_event */ EXPR_SCTP_REMOTE_ERROR, /* expression tree for sctp_remote_error_event */ EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */ + EXPR_SCTP_PDAPI_EVENT, /* expression tree for sctp_partial_delivery_event */ EXPR_SCTP_AUTHKEY_EVENT, /* expression tree for sctp_authentication_event */ EXPR_SCTP_SENDER_DRY_EVENT, /* expression tree for sctp_sender_dry_event */ EXPR_SCTP_SEND_FAILED_EVENT, /* expression tree for sctp_send_failed_event */ @@ -114,6 +115,7 @@ struct expression { struct sctp_assoc_change_expr *sctp_assoc_change; struct sctp_remote_error_expr *sctp_remote_error; struct sctp_shutdown_event_expr *sctp_shutdown_event; + struct sctp_pdapi_event_expr *sctp_pdapi_event; struct sctp_authkey_event_expr *sctp_authkey_event; struct sctp_sender_dry_event_expr *sctp_sender_dry_event; struct sctp_send_failed_event_expr *sctp_send_failed_event; @@ -356,6 +358,17 @@ struct sctp_shutdown_event_expr { struct expression *sse_length; }; +/* Parse tree for sctp_partial_delivery_event for notifications. */ +struct sctp_pdapi_event_expr { + struct expression *pdapi_type; + struct expression *pdapi_flags; + struct expression *pdapi_length; + struct expression *pdapi_indication; + struct expression *pdapi_stream; + struct expression *pdapi_seq; + struct expression *pdapi_assoc_id; +}; + /* Parse tree for sctp_authentication_event for notifications. */ struct sctp_authkey_event_expr { struct expression *auth_type; diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index 5a54612f9c633b4af06d72afaa28fa6a2cca1504..7437cd1290ef19fafc7577bcc28083f60abeef04 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -216,6 +216,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_ASSOC_SUPPORTS_AUTH, "SCTP_ASSOC_SUPPORTS_AUTH" }, { SCTP_ASSOC_SUPPORTS_ASCONF, "SCTP_ASSOC_SUPPORTS_ASCONF" }, { SCTP_ASSOC_SUPPORTS_MULTIBUF, "SCTP_ASSOC_SUPPORTS_MULTIBUF" }, + { SCTP_PARTIAL_DELIVERY_ABORTED, "SCTP_PARTIAL_DELIVERY_ABORTED" }, /* /usr/include/netinet/tcp.h */ { TCP_NODELAY, "TCP_NODELAY" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_partial_delivery_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_partial_delivery_event.pkt new file mode 100644 index 0000000000000000000000000000000000000000..566aeecaf7d29a4a5a53cff4eabdca6c2fd23650 --- /dev/null +++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_partial_delivery_event.pkt @@ -0,0 +1,21 @@ ++0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3 ++0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) ++0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 +// Check the handshake with an empty(!) cookie ++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_PARTIAL_DELIVERY_EVENT, se_on=1}, 8) = 0 ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_PARTIAL_DELIVERY_EVENT, se_on=1}, [8]) = 0 ++0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=1, ...] ++0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=1, is=1, tsn=1, STATE_COOKIE[len=4, val=...]] ++0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...] ++0.1 < sctp: COOKIE_ACK[flgs=0] ++0.0 write(3, ..., 3000) = 3000 +* > sctp: DATA[flgs=B, len=1468, tsn=1, sid=0, ssn=0, ppid=0] ++0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]] + +* > sctp: DATA[flgs=0, len=1468, tsn=2, sid=0, ssn=0, ppid=0] +//+0.0 < sctp: ABORT[flgs=0, USER_INITIATED_ABORT[info="Testing"]] + ++0.0 sctp_recvv(3, [{iov_base=..., iov_len=1000}, {iov_base={pdapi_type=SCTP_PARTIAL_DELIVERY_EVENT, pdapi_flags=0,pdapi_length=24, +pdapi_indication=SCTP_PARTIAL_DELIVERY_ABORTED, pdapi_stream=0, pdapi_seq=0, pdapi_assoc_id=3 }, iov_len=1000}], 2, ..., 20, NULL, [0], +[SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 21