diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index d08de406abf29e75d688d980ae48386a0358d02d..5ad8469738501d5cc0e150ea61e5605dff2b6d4d 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -572,6 +572,7 @@ SSN_TSN_RESET return SSN_TSN_RESET; RECONFIG_RESPONSE return RECONFIG_RESPONSE; ADD_OUTGOING_STREAMS return ADD_OUTGOING_STREAMS; ADD_INCOMING_STREAMS return ADD_INCOMING_STREAMS; +RECONFIG_REQUEST_GENERIC return RECONFIG_REQUEST_GENERIC; req_sn return REQ_SN; resp_sn return RESP_SN; last_tsn return LAST_TSN; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 6d3c7f6fe4378753428f23ba6952435dfac7df98..ecb74c63b45917a779c0e47f583cb8ec877f2c97 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -528,7 +528,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> OUTGOING_SSN_RESET REQ_SN RESP_SN LAST_TSN SIDS INCOMING_SSN_RESET %token <reserved> RECONFIG_RESPONSE RESULT SENDER_NEXT_TSN RECEIVER_NEXT_TSN %token <reserved> SSN_TSN_RESET ADD_INCOMING_STREAMS NUMBER_OF_NEW_STREAMS -%token <reserved> ADD_OUTGOING_STREAMS +%token <reserved> ADD_OUTGOING_STREAMS RECONFIG_REQUEST_GENERIC %token <reserved> ADDR INCR TYPES PARAMS %token <reserved> IPV4_TYPE IPV6_TYPE HOSTNAME_TYPE %token <reserved> CAUSE @@ -690,7 +690,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %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 incoming_ssn_reset_request -%type <parameter_list_item> reconfig_response ssn_tsn_reset_request +%type <parameter_list_item> reconfig_response ssn_tsn_reset_request generic_reconfig_request %type <parameter_list_item> add_outgoing_streams_request add_incoming_streams_request %type <cause_list> opt_cause_list_spec sctp_cause_list_spec %type <cause_list_item> sctp_cause_spec @@ -1752,6 +1752,7 @@ sctp_reconfig_parameter_spec | reconfig_response { $$ = $1; } | add_outgoing_streams_request { $$ = $1; } | add_incoming_streams_request { $$ = $1; } +| generic_reconfig_request { $$ = $1; } ; opt_sender_next_tsn @@ -1761,6 +1762,12 @@ opt_sender_next_tsn } $$ = $3; } +| SENDER_NEXT_TSN '=' HEX_INTEGER { + if (!is_valid_u32($3)) { + semantic_error("sender_next_tsn out of range"); + } + $$ = $3; +} | SENDER_NEXT_TSN '=' ELLIPSIS { $$ = -1; } ; @@ -1771,6 +1778,12 @@ opt_receiver_next_tsn } $$ = $3; } +| RECEIVER_NEXT_TSN '=' HEX_INTEGER { + if (!is_valid_u32($3)) { + semantic_error("receiver_next_tsn out of range"); + } + $$ = $3; +} | RECEIVER_NEXT_TSN '=' ELLIPSIS { $$ = -1; } ; @@ -1829,10 +1842,19 @@ add_incoming_streams_request } ; +generic_reconfig_request +: RECONFIG_REQUEST_GENERIC '[' opt_parameter_type ',' opt_len ',' opt_req_sn ',' opt_val ']' { + $$ = sctp_generic_reconfig_request_parameter_new($3, $5, $7, $9); +} +; + sctp_reconfig_chunk_spec : RECONFIG '[' opt_flags ',' sctp_reconfig_parameter_list_spec ']' { $$ = sctp_reconfig_chunk_new($3, $5); } +| RECONFIG '[' opt_flags ']' { + $$ = sctp_reconfig_chunk_new($3, NULL); +} ; opt_parameter_list_spec @@ -5307,6 +5329,12 @@ assocreset_local_tsn } $$ = new_integer_expression($3, "%u"); } +| ASSOCRESET_LOCAL_TSN '=' HEX_INTEGER { + if (!is_valid_u32($3)) { + semantic_error("assocreset_local_tsn out of range"); + } + $$ = new_integer_expression($3, "%u"); +} | ASSOCRESET_LOCAL_TSN '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; @@ -5317,6 +5345,12 @@ assocreset_remote_tsn } $$ = new_integer_expression($3, "%u"); } +| ASSOCRESET_REMOTE_TSN '=' HEX_INTEGER { + if (!is_valid_u32($3)) { + semantic_error("assocreset_remote_tsn out of range"); + } + $$ = new_integer_expression($3, "%u"); +} | ASSOCRESET_REMOTE_TSN '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; diff --git a/gtests/net/packetdrill/sctp.h b/gtests/net/packetdrill/sctp.h index badde3425886c0ce13f01fa1d9bbf36e84d542ea..0b95445b49bdb9ea78db841600e1e70a14199074 100644 --- a/gtests/net/packetdrill/sctp.h +++ b/gtests/net/packetdrill/sctp.h @@ -387,6 +387,13 @@ struct sctp_add_incoming_streams_request_parameter { __be16 reserved; } __packed; +struct sctp_reconfig_generic_request_parameter { + __be16 type; + __be16 length; + __be32 reqsn; + __u8 value[]; +} __packed; + #define SCTP_INVALID_STREAM_IDENTIFIER_CAUSE_CODE 0x0001 #define SCTP_MISSING_MANDATORY_PARAMETER_CAUSE_CODE 0x0002 #define SCTP_STALE_COOKIE_ERROR_CAUSE_CODE 0x0003 diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c index 6e61ad52f0a3ce97225e087567d4209060240465..7936fc02d201db725bbdaae9137f69edc36f72d9 100644 --- a/gtests/net/packetdrill/sctp_packet.c +++ b/gtests/net/packetdrill/sctp_packet.c @@ -1313,22 +1313,23 @@ sctp_reconfig_chunk_new(s64 flgs, struct sctp_parameter_list *parameters) chunk->length = htons(chunk_length); offset = 0; - for (item = parameters->first; item != NULL; item = item->next) { - parameter_padding_length = item->length % 4; - if (parameter_padding_length > 0) { - parameter_padding_length = 4 - parameter_padding_length; - } - memcpy(chunk->parameter + offset, - item->parameter, - item->length + parameter_padding_length); - free(item->parameter); - item->parameter = (struct sctp_parameter *)(chunk->parameter + offset); - if (item->flags & FLAG_PARAMETER_LENGTH_NOCHECK) { - flags |= FLAG_CHUNK_LENGTH_NOCHECK; + if (parameters != NULL) { + for (item = parameters->first; item != NULL; item = item->next) { + parameter_padding_length = item->length % 4; + if (parameter_padding_length > 0) { + parameter_padding_length = 4 - parameter_padding_length; + } + memcpy(chunk->parameter + offset, + item->parameter, + item->length + parameter_padding_length); + free(item->parameter); + item->parameter = (struct sctp_parameter *)(chunk->parameter + offset); + if (item->flags & FLAG_PARAMETER_LENGTH_NOCHECK) { + flags |= FLAG_CHUNK_LENGTH_NOCHECK; + } + offset += item->length + parameter_padding_length; } - offset += item->length + parameter_padding_length; } - return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, chunk_length + padding_length, flags, parameters, @@ -1921,6 +1922,7 @@ sctp_reconfig_response_parameter_new(s64 respsn, s64 result, s64 sender_next_tsn parameter->receiver_next_tsn = htonl((u32)receiver_next_tsn); } } + return sctp_parameter_list_item_new((struct sctp_parameter *)parameter, parameter_length, flags); } @@ -1973,7 +1975,7 @@ sctp_add_outgoing_streams_request_parameter_new(s64 reqsn, s32 number_of_new_str } else { parameter->reqsn = htonl((u32)reqsn); } - if (reqsn == -1) { + if (number_of_new_streams == -1) { flags |= FLAG_RECONFIG_NUMBER_OF_NEW_STREAMS_NOCHECK; parameter->number_of_new_streams = 0; } else { @@ -2006,7 +2008,7 @@ sctp_add_incoming_streams_request_parameter_new(s64 reqsn, s32 number_of_new_str } else { parameter->reqsn = htonl((u32)reqsn); } - if (reqsn == -1) { + if (number_of_new_streams == -1) { flags |= FLAG_RECONFIG_NUMBER_OF_NEW_STREAMS_NOCHECK; parameter->number_of_new_streams = 0; } else { @@ -2017,6 +2019,50 @@ sctp_add_incoming_streams_request_parameter_new(s64 reqsn, s32 number_of_new_str parameter_length, flags); } +struct sctp_parameter_list_item * +sctp_generic_reconfig_request_parameter_new(s32 type, s32 len, s64 reqsn, struct sctp_byte_list *payload) +{ + struct sctp_reconfig_generic_request_parameter *parameter; + struct sctp_byte_list_item *item; + u32 flags = 0; + u16 parameter_length; + u16 payload_len=0; + + if (payload != NULL) { + payload_len = payload->nr_entries; + } + parameter_length = sizeof(struct sctp_reconfig_generic_request_parameter) + payload_len; + + parameter = malloc(parameter_length); + assert(parameter != NULL); + + if (type == -1) { + parameter->type = 0; + } else { + parameter->type = htons((u16)type); + } + if (len == -1) { + parameter->length = 0; + } else { + parameter->length = htons((u16)len); + } + if (reqsn == -1) { + flags |= FLAG_RECONFIG_REQ_SN_NOCHECK; + parameter->reqsn = 0; + } else { + parameter->reqsn = htonl((u32)reqsn); + } + if (payload != NULL) { + int i = 0; + for (i = 0, item = payload->first; item != NULL; i++, item = item->next) { + parameter->value[i] = item->byte; + } + } + + return sctp_parameter_list_item_new((struct sctp_parameter *)parameter, + parameter_length, flags); +} + struct sctp_parameter_list_item * sctp_ecn_capable_parameter_new(void) { diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h index 8a1a4bec96e11e69ae08a8e46003105beb3e95ea..7581f207e72d32e1df27900dd80f5416d09657b8 100644 --- a/gtests/net/packetdrill/sctp_packet.h +++ b/gtests/net/packetdrill/sctp_packet.h @@ -405,6 +405,9 @@ sctp_add_outgoing_streams_request_parameter_new(s64 reqsn, s32 number_of_new_str struct sctp_parameter_list_item * sctp_add_incoming_streams_request_parameter_new(s64 reqsn, s32 number_of_new_streams); +struct sctp_parameter_list_item * +sctp_generic_reconfig_request_parameter_new(s32 type, s32 len, s64 reqsn, struct sctp_byte_list *payload); + struct sctp_parameter_list * sctp_parameter_list_new(void);