diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 70219bd5..61bdb96a 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -1257,6 +1257,10 @@ tcp_option } $$->data.window_scale.shift_count = $2; } +| WSCALE '*' { + $$ = tcp_option_new(TCPOPT_WINDOW | TCPOPT_WILDCARD, TCPOLEN_WINDOW); + $$->data.window_scale.shift_count = 0; +} | SACKOK { $$ = tcp_option_new(TCPOPT_SACK_PERMITTED, TCPOLEN_SACK_PERMITTED); diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index d68d68d5..cb3b01f1 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -1248,14 +1248,18 @@ static int verify_outbound_live_tcp_options( /* TCP options are expected to be a deterministic order. */ while (a_opt != NULL || s_opt != NULL) { if (a_opt == NULL || s_opt == NULL || - a_opt->kind != s_opt->kind) { + (a_opt->kind & ~TCPOPT_WILDCARD) != + (s_opt->kind & ~TCPOPT_WILDCARD)) { asprintf(error, "bad outbound TCP options"); return STATUS_ERR; } - if (verify_outbound_tcp_option(config, actual_packet, - script_packet, a_opt, s_opt, - error) != STATUS_OK) { + /* skip btye-to-byte comparison of wildcard option */ + if ((a_opt->kind | s_opt->kind) & TCPOPT_WILDCARD) + ; + else if (verify_outbound_tcp_option(config, actual_packet, + script_packet, a_opt, s_opt, + error) != STATUS_OK) { return STATUS_ERR; } diff --git a/gtests/net/packetdrill/tcp.h b/gtests/net/packetdrill/tcp.h index 5a03f35c..7467f6cb 100644 --- a/gtests/net/packetdrill/tcp.h +++ b/gtests/net/packetdrill/tcp.h @@ -101,6 +101,17 @@ #define TCP_MD5_DIGEST_LEN 16 /* bytes in RFC2385 TCP MD5 digest */ +/* + * To compare subset of options between script packet and actual packet, + * we use * for "option with any value". For example, "wscale *" in the + * script packet means wscale option of any value. + * + * TCPOPT_WILDCARD is used to mark a option in the script packet as + * "any value". A script packet of kind "TCPOPT_WINDOW | TCPOPT_WILDCARD" + * means "wscale option of any value". + */ +#define TCPOPT_WILDCARD 0x80 + /* A portable TCP header definition (Linux and *BSD use different names). */ struct tcp { __be16 src_port; diff --git a/gtests/net/packetdrill/tcp_options_iterator.c b/gtests/net/packetdrill/tcp_options_iterator.c index 6123387d..3f45924a 100644 --- a/gtests/net/packetdrill/tcp_options_iterator.c +++ b/gtests/net/packetdrill/tcp_options_iterator.c @@ -50,6 +50,7 @@ static int get_expected_tcp_option_length(u8 kind, u8 *expected_length, break; case TCPOPT_WINDOW: + case TCPOPT_WINDOW | TCPOPT_WILDCARD: *expected_length = TCPOLEN_WINDOW; break; diff --git a/gtests/net/packetdrill/tcp_options_to_string.c b/gtests/net/packetdrill/tcp_options_to_string.c index 09a52301..84287153 100644 --- a/gtests/net/packetdrill/tcp_options_to_string.c +++ b/gtests/net/packetdrill/tcp_options_to_string.c @@ -106,6 +106,10 @@ int tcp_options_to_string(struct packet *packet, option->data.window_scale.shift_count); break; + case TCPOPT_WINDOW | TCPOPT_WILDCARD: + fprintf(s, "wscale *"); + break; + case TCPOPT_SACK_PERMITTED: fputs("sackOK", s); break;