diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 17e8f55ed446fab88020a5a1db974f5ecf1dc07f..d258c19ed94bf1f985940c5b513876f2a236d400 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -567,6 +567,7 @@ gaps return GAPS; dups return DUPS; adaptation_code_point return ADAPTATION_CODE_POINT; OUTGOING_SSN_RESET return OUTGOING_SSN_RESET; +SSN_TSN_RESET return SSN_TSN_RESET; RECONFIG_RESPONSE return RECONFIG_RESPONSE; req_sn return REQ_SN; resp_sn return RESP_SN; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index a9051530391985a7354fa41ea1883065d4ca212d..a7af8e0dea7bc8a68ea69b1cf696d95ab274232b 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -527,6 +527,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SUPPORTED_EXTENSIONS ADAPTATION_CODE_POINT ADAPTATION_INDICATION %token <reserved> OUTGOING_SSN_RESET REQ_SN RESP_SN LAST_TSN SIDS %token <reserved> RECONFIG_RESPONSE RESULT SENDER_NEXT_TSN RECEIVER_NEXT_TSN +%token <reserved> SSN_TSN_RESET %token <reserved> ADDR INCR TYPES PARAMS %token <reserved> IPV4_TYPE IPV6_TYPE HOSTNAME_TYPE %token <reserved> CAUSE @@ -687,7 +688,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <parameter_list_item> sctp_supported_extensions_parameter_spec %type <parameter_list_item> sctp_adaptation_indication_parameter_spec %type <parameter_list_item> sctp_pad_parameter_spec sctp_reconfig_parameter_spec -%type <parameter_list_item> outgoing_ssn_reset_request reconfig_response +%type <parameter_list_item> outgoing_ssn_reset_request reconfig_response ssn_tsn_reset_request %type <cause_list> opt_cause_list_spec sctp_cause_list_spec %type <cause_list_item> sctp_cause_spec %type <cause_list_item> sctp_generic_cause_spec @@ -1743,8 +1744,10 @@ sctp_reconfig_parameter_list_spec sctp_reconfig_parameter_spec :outgoing_ssn_reset_request { $$ = $1; } +|ssn_tsn_reset_request { $$ = $1; } |reconfig_response { $$ = $1; } -; +; + opt_sender_next_tsn : SENDER_NEXT_TSN '=' INTEGER { if (!is_valid_u32($3)) { @@ -1774,12 +1777,18 @@ outgoing_ssn_reset_request } ; +ssn_tsn_reset_request +:SSN_TSN_RESET '[' opt_req_sn ']' { + $$ = sctp_ssn_tsn_reset_request_parameter_new($3); +} +; + reconfig_response :RECONFIG_RESPONSE '[' opt_resp_sn ',' opt_result ']' { - $$ = sctp_reconfig_response_new($3, $5, -2, -2); + $$ = sctp_reconfig_response_parameter_new($3, $5, -2, -2); } |RECONFIG_RESPONSE '[' opt_resp_sn ',' opt_result ',' opt_sender_next_tsn ',' opt_receiver_next_tsn']' { - $$ = sctp_reconfig_response_new($3, $5, $7, $9); + $$ = sctp_reconfig_response_parameter_new($3, $5, $7, $9); } ; diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index c3a3d5d87b04a38ddcfb961529da0f43cc06467e..1ff35223d79aaca4f35778ac5008a4d684285d42 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -758,6 +758,12 @@ static int map_inbound_sctp_packet( reset->last_tsn = htonl(ntohl(reset->last_tsn) + remote_diff); break; } + case SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_TYPE: { + struct sctp_ssn_tsn_reset_request_parameter *reset; + reset = (struct sctp_ssn_tsn_reset_request_parameter *)parameter; + reset->reqsn = htonl(ntohl(reset->reqsn) + remote_diff); + break; + } case SCTP_RECONFIG_RESPONSE_PARAMETER_TYPE: { struct sctp_reconfig_response_parameter *response; response = (struct sctp_reconfig_response_parameter *)parameter; @@ -989,6 +995,12 @@ static int map_outbound_live_sctp_packet( reset->last_tsn = htonl(ntohl(reset->last_tsn) + local_diff); break; } + case SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_TYPE: { + struct sctp_ssn_tsn_reset_request_parameter *reset; + reset = (struct sctp_ssn_tsn_reset_request_parameter *)parameter; + reset->reqsn = htonl(ntohl(reset->reqsn) + local_diff); + break; + } case SCTP_RECONFIG_RESPONSE_PARAMETER_TYPE: { struct sctp_reconfig_response_parameter *response; response = (struct sctp_reconfig_response_parameter *)parameter; diff --git a/gtests/net/packetdrill/sctp.h b/gtests/net/packetdrill/sctp.h index 84bdeff7d467b4dc6ce1e643369ce145405c6ae5..a9a5730d77a08353aa942554e7e1aaf862b2c1c5 100644 --- a/gtests/net/packetdrill/sctp.h +++ b/gtests/net/packetdrill/sctp.h @@ -249,6 +249,7 @@ struct sctp_reconfig_chunk { #define SCTP_HOSTNAME_ADDRESS_PARAMETER_TYPE 0x000b #define SCTP_SUPPORTED_ADDRESS_TYPES_PARAMETER_TYPE 0x000c #define SCTP_OUTGOING_SSN_RESET_REQUEST_PARAMETER_TYPE 0x000d +#define SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_TYPE 0x000f #define SCTP_RECONFIG_RESPONSE_PARAMETER_TYPE 0x0010 #define SCTP_ECN_CAPABLE_PARAMETER_TYPE 0x8000 #define SCTP_SUPPORTED_EXTENSIONS_PARAMETER_TYPE 0x8008 @@ -343,6 +344,12 @@ struct sctp_outgoing_ssn_reset_request_parameter { __be16 sids[]; } __packed; +struct sctp_ssn_tsn_reset_request_parameter { + __be16 type; + __be16 length; + __be32 reqsn; +} __packed; + struct sctp_reconfig_response_parameter { __be16 type; __be16 length; diff --git a/gtests/net/packetdrill/sctp_chunk_to_string.c b/gtests/net/packetdrill/sctp_chunk_to_string.c index c3634c5425410595a62e90cc4c7e757bee6d72dd..51bb4ca284397abaf74c6f915ef2568ca8492154 100644 --- a/gtests/net/packetdrill/sctp_chunk_to_string.c +++ b/gtests/net/packetdrill/sctp_chunk_to_string.c @@ -348,6 +348,24 @@ static int sctp_outgoing_ssn_reset_request_parameter_to_string( return STATUS_OK; } +static int sctp_ssn_tsn_reset_request_parameter_to_string( + FILE *s, + struct sctp_ssn_tsn_reset_request_parameter *parameter, + char **error) +{ + u16 length; + u32 reqsn; + + length = ntohs(parameter->length); + reqsn = ntohl(parameter->reqsn); + + fputs("SSN_TSN_RESET[", s); + fprintf(s, "len=%hu, ", length); + fprintf(s, "req_sn=%u", reqsn); + fputs("]", s); + return STATUS_OK; +} + static int sctp_reconfig_response_parameter_to_string( FILE *s, struct sctp_reconfig_response_parameter *parameter, @@ -355,14 +373,18 @@ static int sctp_reconfig_response_parameter_to_string( { u16 length; u32 respsn; + u32 result; u32 sender_next_tsn; u32 receiver_next_tsn; length = ntohs(parameter->length); respsn = ntohl(parameter->respsn); + result = ntohl(parameter->result); + fputs("RECONFIG_RESPONSE[", s); fprintf(s, "len=%hu, ", length); - fprintf(s, "resp_sn=%u", respsn); + fprintf(s, "resp_sn=%u, ", respsn); + fprintf(s, "result=%u", result); if (length == sizeof(struct sctp_reconfig_response_parameter)){ sender_next_tsn = ntohl(parameter->sender_next_tsn); receiver_next_tsn = ntohl(parameter->receiver_next_tsn); @@ -483,6 +505,10 @@ static int sctp_parameter_to_string(FILE *s, result = sctp_outgoing_ssn_reset_request_parameter_to_string(s, (struct sctp_outgoing_ssn_reset_request_parameter *)parameter, error); break; + case SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_TYPE: + result = sctp_ssn_tsn_reset_request_parameter_to_string(s, + (struct sctp_ssn_tsn_reset_request_parameter *)parameter, error); + break; case SCTP_RECONFIG_RESPONSE_PARAMETER_TYPE: result = sctp_reconfig_response_parameter_to_string(s, (struct sctp_reconfig_response_parameter *)parameter, error); diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c index 11e0b9d4a13599c9746ee1a7cca6782b62369060..27893aa5d420b5f76936a13dd58c66f3abbe7544 100644 --- a/gtests/net/packetdrill/sctp_packet.c +++ b/gtests/net/packetdrill/sctp_packet.c @@ -1843,7 +1843,7 @@ sctp_outgoing_ssn_reset_request_parameter_new(s64 reqsn, s64 respsn, s64 last_ts } struct sctp_parameter_list_item * -sctp_reconfig_response_new(s64 respsn, s64 result, s64 sender_next_tsn, s64 receiver_next_tsn) +sctp_reconfig_response_parameter_new(s64 respsn, s64 result, s64 sender_next_tsn, s64 receiver_next_tsn) { struct sctp_reconfig_response_parameter *parameter; u32 flags = 0; @@ -1890,6 +1890,32 @@ sctp_reconfig_response_new(s64 respsn, s64 result, s64 sender_next_tsn, s64 rece parameter_length, flags); } +struct sctp_parameter_list_item * +sctp_ssn_tsn_reset_request_parameter_new(s64 reqsn) +{ + struct sctp_ssn_tsn_reset_request_parameter *parameter; + u32 flags = 0; + u16 parameter_length; + + parameter_length = sizeof(struct sctp_ssn_tsn_reset_request_parameter); + + parameter = malloc(parameter_length); + assert(parameter != NULL); + + parameter->type = htons(SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_TYPE); + parameter->length = htons(parameter_length); + + if (reqsn == -1) { + flags |= FLAG_RECONFIG_REQ_SN_NOCHECK; + parameter->reqsn = 0; + } else { + parameter->reqsn = htonl((u32)reqsn); + } + + return sctp_parameter_list_item_new((struct sctp_parameter *)parameter, + parameter_length, flags); +} + struct sctp_parameter_list_item * sctp_ecn_capable_parameter_new(void) { @@ -2544,6 +2570,13 @@ new_sctp_packet(int address_family, return NULL; } break; + case SCTP_SSN_TSN_RESET_REQUEST_PARAMETER_TYPE: + if (parameter_item->flags & FLAG_RECONFIG_REQ_SN_NOCHECK) { + asprintf(error, + "reqsn value must be specified for inbound packets"); + return NULL; + } + break; case SCTP_RECONFIG_RESPONSE_PARAMETER_TYPE: if (parameter_item->flags & FLAG_RECONFIG_RESULT_NOCHECK) { asprintf(error, diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h index 59d988ec52e7fd6f0f2e0c5f1427c521397f6cc0..d8d29b24ea3ffcc56aef14bfe183c6511815c6e5 100644 --- a/gtests/net/packetdrill/sctp_packet.h +++ b/gtests/net/packetdrill/sctp_packet.h @@ -383,11 +383,14 @@ sctp_pad_parameter_new(s64 len, u8 *padding); struct sctp_parameter_list_item * sctp_outgoing_ssn_reset_request_parameter_new(s64 reqsn, s64 respsn, s64 last_tsn, struct sctp_u16_list *sids); +struct sctp_parameter_list_item * +sctp_ssn_tsn_reset_request_parameter_new(s64 reqsn); + #define FLAG_RECONFIG_RESULT_NOCHECK 0x00000010 #define FLAG_RECONFIG_SENDER_NEXT_TSN_NOCHECK 0x00000040 #define FLAG_RECONFIG_RECEIVER_NEXT_TSN_NOCHECK 0x00000080 struct sctp_parameter_list_item * -sctp_reconfig_response_new(s64 respsn, s64 result, s64 sender_next_tsn, s64 receiver_next_tsn); +sctp_reconfig_response_parameter_new(s64 respsn, s64 result, s64 sender_next_tsn, s64 receiver_next_tsn); struct sctp_parameter_list * sctp_parameter_list_new(void);