From 15b314293a835bc98a98507052586f6136122d03 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Tue, 27 Oct 2015 17:35:46 +0100 Subject: [PATCH] add support for sctp_adaptation_event (Untested) --- gtests/net/packetdrill/lexer.l | 5 ++ gtests/net/packetdrill/parser.y | 69 +++++++++++++++++++ gtests/net/packetdrill/run_system_call.c | 33 ++++++++- gtests/net/packetdrill/script.c | 51 ++++++++++++++ gtests/net/packetdrill/script.h | 11 +++ .../notifications/sctp_adaptation_event.pkt | 15 ++++ 6 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 53effec3..4d92cdb9 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -343,6 +343,11 @@ ssf_error return SSF_ERROR; ssf_info return SSF_INFO; ssf_assoc_id return SSF_ASSOC_ID; ssf_data return SSF_DATA; +sai_type return SAI_TYPE; +sai_length return SAI_LENGTH; +sai_flags return SAI_FLAGS; +sai_adaptation_ind return SAI_ADAPTATION_IND; +sai_assoc_id return SAI_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 320d694c..7771e687 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -561,6 +561,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> PDAPI_TYPE PDAPI_FLAGS PDAPI_LENGTH PDAPI_INDICATION PDAPI_STREAM PDAPI_SEQ %token <reserved> SPC_TYPE SPC_FLAGS SPC_LENGTH SPC_AADDR SPC_STATE SPC_ERROR SPC_ASSOC_ID %token <reserved> SSF_TYPE SSF_LENGTH SSF_FLAGS SSF_ERROR SSF_INFO SSF_ASSOC_ID SSF_DATA +%token <reserved> SAI_TYPE SAI_FLAGS SAI_LENGTH SAI_ADAPTATION_IND SAI_ASSOC_ID %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -627,6 +628,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_pdapi_event pdapi_type pdapi_flags pdapi_length pdapi_indication pdapi_stream pdapi_seq pdapi_assoc_id %type <expression> sctp_paddr_change spc_type spc_flags spc_length spc_aaddr spc_error spc_state spc_assoc_id %type <expression> sctp_send_failed ssf_type ssf_length ssf_flags ssf_error ssf_info ssf_assoc_id ssf_data +%type <expression> sctp_adaptation_event sai_type sai_flags sai_length sai_adaptation_ind sai_assoc_id %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2606,6 +2608,7 @@ data | sctp_remote_error { $$ = $1; } | sctp_send_failed { $$ = $1; } | sctp_shutdown_event { $$ = $1; } +| sctp_adaptation_event { $$ = $1; } | sctp_pdapi_event { $$ = $1; } | sctp_sender_dry_event { $$ = $1; } | sctp_send_failed_event { $$ = $1; } @@ -4255,6 +4258,72 @@ sctp_send_failed } ; +sai_type +: SAI_TYPE '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("sai_type out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SAI_TYPE '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| SAI_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sai_flags +: SAI_FLAGS '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("sai_flags out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SAI_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sai_length +: SAI_LENGTH '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("sai_length out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SAI_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sai_adaptation_ind +: SAI_ADAPTATION_IND '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("sai_adaptation_ind out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SAI_ADAPTATION_IND '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sai_assoc_id +: SAI_ASSOC_ID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("sai_assoc_id out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SAI_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_adaptation_event +: '{' sai_type ',' sai_flags ',' sai_length ',' sai_adaptation_ind ',' sai_assoc_id '}' { + $$ = new_expression(EXPR_SCTP_ADAPTATION_EVENT); + $$->value.sctp_adaptation_event = calloc(1, sizeof(struct sctp_adaptation_event_expr)); + $$->value.sctp_adaptation_event->sai_type = $2; + $$->value.sctp_adaptation_event->sai_flags = $4; + $$->value.sctp_adaptation_event->sai_length = $6; + $$->value.sctp_adaptation_event->sai_adaptation_ind = $8; + $$->value.sctp_adaptation_event->sai_assoc_id = $10; +} +; + opt_errno : { $$ = NULL; } | WORD note { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 4e6f5eae..4ede3caf 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -572,6 +572,7 @@ static int iovec_new(struct expression *expression, iov_expr->iov_base->type == EXPR_SCTP_REMOTE_ERROR || iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED || iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT || + iov_expr->iov_base->type == EXPR_SCTP_ADAPTATION_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 || @@ -3529,6 +3530,31 @@ static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr, } #endif +#if defined(__FreeBSD__) || defined(linux) +static int check_sctp_adaptation_event(struct sctp_adaptation_event_expr *expr, + struct sctp_adaptation_event *sctp_event, + char **error) { + + if (check_u16_expr(expr->sai_type, sctp_event->sai_type, + "sctp_adaptation_event.sai_type", error)) + return STATUS_ERR; + if (check_u16_expr(expr->sai_flags, sctp_event->sai_flags, + "sctp_adaptation_event.sai_flags", error)) + return STATUS_ERR; + if (check_u32_expr(expr->sai_length, sctp_event->sai_length, + "sctp_adaptation_event.sai_length", error)) + return STATUS_ERR; + if (check_u32_expr(expr->sai_adaptation_ind, sctp_event->sai_adaptation_ind, + "sctp_adaptation_event.sai_adaptation_ind", error)) + return STATUS_ERR; + if (check_u32_expr(expr->sai_assoc_id, sctp_event->sai_assoc_id, + "sctp_adaptation_event.sai_assoc_id", error)) + return STATUS_ERR; + + return STATUS_OK; +} +#endif + #if defined(__FreeBSD__) || defined(linux) static int check_sctp_pdapi_event(struct sctp_pdapi_event_expr *expr, struct sctp_pdapi_event *sctp_event, @@ -3704,8 +3730,13 @@ static int check_sctp_notification(struct iovec *iov, error)) return STATUS_ERR; break; + case EXPR_SCTP_ADAPTATION_EVENT: + if (check_sctp_adaptation_event(script_iov_base->value.sctp_adaptation_event, + (struct sctp_adaptation_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)) diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 53b30e85..f119c512 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -91,6 +91,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_REMOTE_ERROR, "sctp_remote_error"}, { EXPR_SCTP_SEND_FAILED, "sctp_send_failed"}, { EXPR_SCTP_SHUTDOWN_EVENT, "sctp_shutdown_event"}, + { EXPR_SCTP_ADAPTATION_EVENT,"sctp_adaptation_event"}, { EXPR_SCTP_PDAPI_EVENT, "sctp_pdapi_event"}, { EXPR_SCTP_AUTHKEY_EVENT, "sctp_authkey_event"}, { EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"}, @@ -480,6 +481,13 @@ 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_ADAPTATION_EVENT: + free_expression(expression->value.sctp_adaptation_event->sai_type); + free_expression(expression->value.sctp_adaptation_event->sai_flags); + free_expression(expression->value.sctp_adaptation_event->sai_length); + free_expression(expression->value.sctp_adaptation_event->sai_adaptation_ind); + free_expression(expression->value.sctp_adaptation_event->sai_assoc_id); + break; case EXPR_SCTP_PDAPI_EVENT: free_expression(expression->value.sctp_pdapi_event->pdapi_type); free_expression(expression->value.sctp_pdapi_event->pdapi_flags); @@ -1650,6 +1658,46 @@ static int evaluate_sctp_shutdown_event_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_adaptation_event_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_adaptation_event_expr *in_event; + struct sctp_adaptation_event_expr *out_event; + + assert(in->type == EXPR_SCTP_ADAPTATION_EVENT); + assert(in->value.sctp_adaptation_event); + assert(out->type == EXPR_SCTP_ADAPTATION_EVENT); + + out->value.sctp_adaptation_event = calloc(1, sizeof(struct sctp_adaptation_event_expr)); + + in_event = in->value.sctp_adaptation_event; + out_event = out->value.sctp_adaptation_event; + + if (evaluate(in_event->sai_type, + &out_event->sai_type, + error)) + return STATUS_ERR; + if (evaluate(in_event->sai_flags, + &out_event->sai_flags, + error)) + return STATUS_ERR; + if (evaluate(in_event->sai_length, + &out_event->sai_length, + error)) + return STATUS_ERR; + if (evaluate(in_event->sai_adaptation_ind, + &out_event->sai_adaptation_ind, + error)) + return STATUS_ERR; + if (evaluate(in_event->sai_assoc_id, + &out_event->sai_assoc_id, + error)) + return STATUS_ERR; + + return STATUS_OK; +} + static int evaluate_sctp_pdapi_event_expression(struct expression *in, struct expression *out, char **error) @@ -1926,6 +1974,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_ADAPTATION_EVENT: + result = evaluate_sctp_adaptation_event_expression(in, out, error); + break; case EXPR_SCTP_PDAPI_EVENT: result = evaluate_sctp_pdapi_event_expression(in, out, error); break; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index dc755dbb..26264d74 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -71,6 +71,7 @@ enum expression_t { EXPR_SCTP_REMOTE_ERROR, /* expression tree for sctp_remote_error_event */ EXPR_SCTP_SEND_FAILED, /* expression tree for sctp_send_failed event (DEPRICATED) */ EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */ + EXPR_SCTP_ADAPTATION_EVENT, /* expression tree for sctp_adaptation_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 */ @@ -119,6 +120,7 @@ struct expression { struct sctp_remote_error_expr *sctp_remote_error; struct sctp_send_failed_expr *sctp_send_failed; struct sctp_shutdown_event_expr *sctp_shutdown_event; + struct sctp_adaptation_event_expr *sctp_adaptation_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; @@ -385,6 +387,15 @@ struct sctp_shutdown_event_expr { struct expression *sse_length; }; +/* Parse tree for sctp_adaptation_event for notifications. */ +struct sctp_adaptation_event_expr { + struct expression *sai_type; + struct expression *sai_flags; + struct expression *sai_length; + struct expression *sai_adaptation_ind; + struct expression *sai_assoc_id; +}; + /* Parse tree for sctp_partial_delivery_event for notifications. */ struct sctp_pdapi_event_expr { struct expression *pdapi_type; diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt new file mode 100644 index 00000000..e5b5e282 --- /dev/null +++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_adaptation_event.pkt @@ -0,0 +1,15 @@ ++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_ADAPTATION_INDICATION, se_on=1}, 8) = 0 ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_ADAPTATION_INDICATION, 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] + +//TODO: Packetdrill does not support Path reconfiguration, after that update this test ++0.0 sctp_recvv(3, [{iov_base={sai_type=SCTP_ADAPTATION_INDICATION, sai_flags=0, sai_length=16, sai_adaptation_ind=0, sai_assoc_id=...}, +iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO],[MSG_NOTIFICATION|MSG_EOR]) = 21 -- GitLab