diff --git a/gtests/net/packetdrill/packet.h b/gtests/net/packetdrill/packet.h index 832f6125665a1dcdcfd3abeb58d5c1a1a285da64..8e931ec28528670813bf29749eb3f205f0d84528 100644 --- a/gtests/net/packetdrill/packet.h +++ b/gtests/net/packetdrill/packet.h @@ -109,6 +109,7 @@ struct packet { #define FLAG_WIN_NOCHECK 0x1 /* don't check TCP receive window */ #define FLAG_OPTIONS_NOCHECK 0x2 /* don't check TCP options */ #define FLAGS_SCTP_BAD_CRC32C 0x4 /* compute bad CRC32C for SCTP packets */ +#define FLAGS_SCTP_EXPLICIT_TAG 0x8 /* verification tag specified */ enum ip_ecn_t ecn; /* IPv4/IPv6 ECN treatment for packet */ diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index bb2fb56b5a72dc63bcf7b54f14b2fa6e5b0f2e2b..7df5a63877e4b8201eb6d4025f494e8d2f58dac9 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -821,7 +821,7 @@ sctp_packet_spec enum direction_t direction = outer->direction; inner = new_sctp_packet(in_config->wire_protocol, direction, $2, - false, $5, &error); + -1, false, $5, &error); if (inner == NULL) { assert(error != NULL); semantic_error(error); @@ -836,7 +836,43 @@ sctp_packet_spec enum direction_t direction = outer->direction; inner = new_sctp_packet(in_config->wire_protocol, direction, $2, - true, $8, &error); + -1, true, $8, &error); + if (inner == NULL) { + assert(error != NULL); + semantic_error(error); + free(error); + } + + $$ = packet_encapsulate_and_free(outer, inner); +} +| packet_prefix opt_ip_info SCTP '(' TAG '=' INTEGER ')' ':' sctp_chunk_list_spec { + char *error = NULL; + struct packet *outer = $1, *inner = NULL; + enum direction_t direction = outer->direction; + + if (!is_valid_u32($7)) { + semantic_error("tag value out of range"); + } + inner = new_sctp_packet(in_config->wire_protocol, direction, $2, + $7, false, $10, &error); + if (inner == NULL) { + assert(error != NULL); + semantic_error(error); + free(error); + } + + $$ = packet_encapsulate_and_free(outer, inner); +} +| packet_prefix opt_ip_info SCTP '(' BAD_CRC32C ',' TAG '=' INTEGER ')' ':' sctp_chunk_list_spec { + char *error = NULL; + struct packet *outer = $1, *inner = NULL; + enum direction_t direction = outer->direction; + + if (!is_valid_u32($9)) { + semantic_error("tag value out of range"); + } + inner = new_sctp_packet(in_config->wire_protocol, direction, $2, + $9, true, $12, &error); if (inner == NULL) { assert(error != NULL); semantic_error(error); diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 45d44a1cc63ff4b83f0db828fb6509fbc00bcffb..7dc504fd8cf7f52c589863bee6387ac0283f6f1a 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -2695,7 +2695,7 @@ int abort_association(struct state *state, struct socket *socket) chunk_list = sctp_chunk_list_new(); sctp_chunk_list_append(chunk_list, sctp_abort_chunk_new(flgs, cause_list)); packet = new_sctp_packet(socket->address_family, - DIRECTION_INBOUND, ECN_NONE, false, + DIRECTION_INBOUND, ECN_NONE, -1, false, chunk_list, &error); if (packet == NULL) die("%s", error); diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c index 2658b47d4554a868f7cda2cda85c324ce3a627a3..48416d3b0c43233012bd302ca09075cf9a9c57cf 100644 --- a/gtests/net/packetdrill/sctp_packet.c +++ b/gtests/net/packetdrill/sctp_packet.c @@ -2242,6 +2242,7 @@ struct packet * new_sctp_packet(int address_family, enum direction_t direction, enum ip_ecn_t ecn, + s64 tag, bool bad_crc32c, struct sctp_chunk_list *list, char **error) @@ -2512,6 +2513,9 @@ new_sctp_packet(int address_family, if (bad_crc32c) { packet->flags |= FLAGS_SCTP_BAD_CRC32C; } + if (tag != -1) { + packet->flags |= FLAGS_SCTP_EXPLICIT_TAG; + } packet->ecn = ecn; /* Set IP header fields */ @@ -2528,7 +2532,7 @@ new_sctp_packet(int address_family, /* Set SCTP header fields */ packet->sctp->src_port = htons(0); packet->sctp->dst_port = htons(0); - packet->sctp->v_tag = htonl(0); + packet->sctp->v_tag = htonl((u32)tag); packet->sctp->crc32c = htonl(0); for (chunk_item = list->first; diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h index ca0256b107fb8a0ffb0e418a7c502f10a616c97d..c32e8d9d6878ed480890735478ec254c21483741 100644 --- a/gtests/net/packetdrill/sctp_packet.h +++ b/gtests/net/packetdrill/sctp_packet.h @@ -423,6 +423,7 @@ sctp_cause_list_free(struct sctp_cause_list *list); extern struct packet *new_sctp_packet(int address_family, enum direction_t direction, enum ip_ecn_t ecn, + s64 tag, bool bad_crc32c, struct sctp_chunk_list *chunk_list, char **error);