diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 85a411ac57fc65d4c7d39e27b2fb27a7dacf9323..0b696791da302884e446ee78b4c5a039648f817e 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -334,6 +334,8 @@ iov_len return IOV_LEN; headers return SF_HDTR_HEADERS; trailers return SF_HDTR_TRAILERS; [.][.][.] return ELLIPSIS; +function_set_name return FUNCTION_SET_NAME; +pcbcnt return PCBCNT; assoc_id return ASSOC_ID; assoc_value return ASSOC_VALUE; shmac_number_of_idents return SHMAC_NUMBER_OF_IDENTS; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 715bfd2bbd8481ea3450e86b68a7c4d2b7be13d9..a25ffb5b994d6488f27dd643c59a565a4bc7a649 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -528,6 +528,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> IPV4 IPV6 ICMP SCTP UDP UDPLITE GRE MTU %token <reserved> MPLS LABEL TC TTL %token <reserved> OPTION +%token <reserved> FUNCTION_SET_NAME PCBCNT %token <reserved> SRTO_ASSOC_ID SRTO_INITIAL SRTO_MAX SRTO_MIN %token <reserved> SINIT_NUM_OSTREAMS SINIT_MAX_INSTREAMS SINIT_MAX_ATTEMPTS %token <reserved> SINIT_MAX_INIT_TIMEO @@ -641,6 +642,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> inaddr sockaddr msghdr cmsghdr cmsg_level cmsg_type cmsg_data %type <expression> sf_hdtr iovec pollfd opt_revents %type <expression> linger l_onoff l_linger +%type <expression> tcp_function_set function_set_name pcbcnt %type <udp_encaps_info> opt_udp_encaps_info %type <sctp_header_spec> sctp_header_spec %type <expression> sctp_assoc_id @@ -2850,6 +2852,9 @@ expression | linger { $$ = $1; } +| tcp_function_set { + $$ = $1; +} | sf_hdtr { $$ = $1; } @@ -3163,7 +3168,9 @@ l_onoff } $$ = new_integer_expression($3, "%ld"); } -| ONOFF '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +| ONOFF '=' ELLIPSIS { + $$ = new_expression(EXPR_ELLIPSIS); +} ; l_linger @@ -3173,7 +3180,9 @@ l_linger } $$ = new_integer_expression($3, "%ld"); } -| LINGER '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +| LINGER '=' ELLIPSIS { + $$ = new_expression(EXPR_ELLIPSIS); +} ; linger @@ -3185,6 +3194,42 @@ linger } ; +function_set_name +: FUNCTION_SET_NAME '=' STRING { + $$ = new_expression(EXPR_STRING); + $$->value.string = $3; + $$->format = "\"%s\""; +} +| FUNCTION_SET_NAME '=' ELLIPSIS { + $$ = new_expression(EXPR_ELLIPSIS); +} +; + +pcbcnt +: PCBCNT '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("linger out of range"); + } + $$ = new_integer_expression($3, "%lu"); +} +| PCBCNT '=' ELLIPSIS { + $$ = new_expression(EXPR_ELLIPSIS); +} +; + +tcp_function_set +: '{' function_set_name ',' pcbcnt '}' { +#if defined(__FreeBSD__) + $$ = new_expression(EXPR_TCP_FUNCTION_SET); + $$->value.tcp_function_set = calloc(1, sizeof(struct tcp_function_set_expr)); + $$->value.tcp_function_set->function_set_name = $2; + $$->value.tcp_function_set->pcbcnt = $4; +#else + $$ = NULL; +#endif +} +; + sf_hdtr : '{' SF_HDTR_HEADERS '(' decimal_integer ')' '=' array ',' SF_HDTR_TRAILERS '('decimal_integer ')' '=' array '}' { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 87b3e7a939561033e4c97bef42f8a8ed8953cee2..ffca2f8feaeed7f10c716787ee30e15a456d3a4c 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -3175,6 +3175,27 @@ static int check_sctp_udpencaps(struct sctp_udpencaps_expr *expr, } #endif +#ifdef TCP_FUNCTION_BLK +static int check_tcp_function_set(struct tcp_function_set_expr *expr, + struct tcp_function_set *tcp_function_set, + char **error) { + if (strncmp(expr->function_set_name->value.string, + tcp_function_set->function_set_name, + TCP_FUNCTION_NAME_LEN_MAX)) { + asprintf(error, "tcp_function_set.function_set_name: expected: %s, actual: %.*s\n", + expr->function_set_name->value.string, + TCP_FUNCTION_NAME_LEN_MAX, + tcp_function_set->function_set_name); + return STATUS_ERR; + } + if (check_u32_expr(expr->pcbcnt, tcp_function_set->pcbcnt, + "tcp_function_set.pcbcnt", error)) + return STATUS_ERR; + return STATUS_OK; +} + +#endif + static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { @@ -3487,6 +3508,15 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, live_optval = live_udpencaps; break; } +#endif +#ifdef TCP_FUNCTION_BLK + case EXPR_TCP_FUNCTION_SET: { + struct tcp_function_set *live_tcp_function_set = malloc(sizeof(struct tcp_function_set)); + + memset(live_tcp_function_set, 0, sizeof(struct tcp_function_set)); + live_optval = live_tcp_function_set; + break; + } #endif case EXPR_LIST: s32_bracketed_arg(args, 3, &script_optval, error); @@ -3639,6 +3669,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, case EXPR_SCTP_UDPENCAPS: result = check_sctp_udpencaps(val_expression->value.sctp_udpencaps, live_optval, error); break; +#endif +#ifdef TCP_FUNCTION_BLK + case EXPR_TCP_FUNCTION_SET: + result = check_tcp_function_set(val_expression->value.tcp_function_set, live_optval, error); + break; #endif case EXPR_LIST: if (*(int*)live_optval != script_optval) { @@ -3739,6 +3774,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #ifdef SCTP_REMOTE_UDP_ENCAPS_PORT struct sctp_udpencaps udpencaps; #endif +#ifdef TCP_FUNCTION_BLK + struct tcp_function_set tcp_function_set; +#endif if (check_arg_count(args, 5, error)) return STATUS_ERR; @@ -4270,6 +4308,22 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, } optval = &udpencaps; break; +#endif +#ifdef TCP_FUNCTION_BLK + case EXPR_TCP_FUNCTION_SET: + if (val_expression->value.tcp_function_set->function_set_name->type == EXPR_STRING) { + strncpy(tcp_function_set.function_set_name, + val_expression->value.tcp_function_set->function_set_name->value.string, + TCP_FUNCTION_NAME_LEN_MAX); + } else { + return STATUS_ERR; + } + if (get_u32(val_expression->value.tcp_function_set->pcbcnt, + &tcp_function_set.pcbcnt, error)) { + return STATUS_ERR; + } + optval = &tcp_function_set; + break; #endif default: asprintf(error, "unsupported value type: %s", diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 6c1a54c4adb2aeee83de6ae1822c26af453ed7a8..5e61430111575c11c27887f6f76d2387daf470dc 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -70,6 +70,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_POLLFD, "pollfd" }, #if defined(__FreeBSD__) { EXPR_SF_HDTR, "sf_hdtr" }, + { EXPR_TCP_FUNCTION_SET, "tcp_function_set" }, #endif { EXPR_SCTP_RTOINFO, "sctp_rtoinfo" }, { EXPR_SCTP_INITMSG, "sctp_initmsg" }, @@ -331,6 +332,11 @@ void free_expression(struct expression *expression) free_expression(expression->value.linger->l_onoff); free_expression(expression->value.linger->l_linger); break; + case EXPR_TCP_FUNCTION_SET: + assert(expression->value.tcp_function_set); + free_expression(expression->value.tcp_function_set->function_set_name); + free_expression(expression->value.tcp_function_set->pcbcnt); + break; case EXPR_SCTP_RTOINFO: assert(expression->value.sctp_rtoinfo); free_expression(expression->value.sctp_rtoinfo->srto_assoc_id); @@ -2759,6 +2765,10 @@ static int evaluate(struct expression *in, memcpy(&out->value.linger, &in->value.linger, sizeof(in->value.linger)); break; + case EXPR_TCP_FUNCTION_SET: /* copy as-is */ + memcpy(&out->value.tcp_function_set, &in->value.tcp_function_set, + sizeof(in->value.tcp_function_set)); + break; case EXPR_SCTP_RTOINFO: result = evaluate_sctp_rtoinfo_expression(in, out, error); break; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 2b0be6b6aaaa22e0f562edca00d26aa50e780dc4..b4d75eaf18eb815cb3d663c52689711d939f85d3 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -49,6 +49,7 @@ enum expression_t { EXPR_POLLFD, /* expression tree for a pollfd struct */ #if defined(__FreeBSD__) EXPR_SF_HDTR, /* struct sf_hdtr for sendfile */ + EXPR_TCP_FUNCTION_SET, /* struct tcp_function_set */ #endif EXPR_SCTP_RTOINFO, /* struct sctp_rtoinfo for SCTP_RTOINFO */ EXPR_SCTP_INITMSG, /* struct sctp_initmsg for SCTP_INITMSG */ @@ -119,6 +120,7 @@ struct expression { struct pollfd_expr *pollfd; #if defined(__FreeBSD__) struct sf_hdtr_expr *sf_hdtr; + struct tcp_function_set_expr *tcp_function_set; #endif struct sctp_rtoinfo_expr *sctp_rtoinfo; struct sctp_initmsg_expr *sctp_initmsg; @@ -232,6 +234,11 @@ struct sf_hdtr_expr { struct expression *trailers; struct expression *trl_cnt; }; + +struct tcp_function_set_expr { + struct expression *function_set_name; + struct expression *pcbcnt; +}; #endif /* Parse tree for a sctp_rtoinfo struct in a [gs]etsockopt syscall. */ diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index 9e21d3752be19eb6b23f02603a1e91dfcad47964..350aa3ed419f2ade54d60818afce2afb95f8ced7 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -376,9 +376,13 @@ struct int_symbol platform_symbols_table[] = { #if defined(TCP_FASTOPEN) { TCP_FASTOPEN, "TCP_FASTOPEN" }, #endif +#if defined(TCP_FUNCTION_BLK) + { TCP_FUNCTION_BLK, "TCP_FUNCTION_BLK" }, +#endif #if defined(TCP_REMOTE_UDP_ENCAPS_PORT) { TCP_REMOTE_UDP_ENCAPS_PORT, "TCP_REMOTE_UDP_ENCAPS_PORT" }, #endif + #if defined(UDPLITE_RECV_CSCOV) && defined(UDPLITE_SEND_CSCOV) /* /usr/include/netinet/udplite.h */ { UDPLITE_RECV_CSCOV, "UDPLITE_RECV_CSCOV" },