Lift out connection setup and PSP assoc uapi code in psp.py and responder, so that the key exchange sequence can be used in other test cases that start with a key exchange, but might choose to perform additional tx/rx assoc calls afterwards. The caller of conn_setup_psp() not handling errors was preexisting. Here we are adding some more error paths, so we just handle errors by closing the data sock to make the code a bit more robust. Signed-off-by: Daniel Zahka --- v3: - take key lengths from the kernel's rx-assoc reply instead of a per-version table - close the data socket in psp_responder if conn_setup_psp() fails --- tools/testing/selftests/drivers/net/psp.py | 14 +++- .../testing/selftests/drivers/net/psp_responder.c | 78 ++++++++++++++-------- 2 files changed, 63 insertions(+), 29 deletions(-) diff --git a/tools/testing/selftests/drivers/net/psp.py b/tools/testing/selftests/drivers/net/psp.py index 473500901879..71eeade62ad2 100755 --- a/tools/testing/selftests/drivers/net/psp.py +++ b/tools/testing/selftests/drivers/net/psp.py @@ -447,10 +447,11 @@ def assoc_twice(cfg): ksft_eq(len(tx), 0) -def _data_basic_send(cfg, version, ipver): - """ Test basic data send """ - _init_psp_dev(cfg) +def _establish_psp_conn(cfg, version, ipver=None): + """Establish a PSP connection and return after key exchange + Requires _init_psp_dev() to have been called first. + """ # Version 0 is required by spec, don't let it skip if version: name = cfg.pspnl.consts["version"].entries_by_val[version].name @@ -475,7 +476,14 @@ def _data_basic_send(cfg, version, ipver): "version": version, "tx-key": tx, "sock-fd": s.fileno()}) + return s + + +def _data_basic_send(cfg, version, ipver): + """ Test basic data send """ + _init_psp_dev(cfg) + s = _establish_psp_conn(cfg, version, ipver) data_len = _send_careful(cfg, s, 100) _check_data_rx(cfg, data_len) _close_psp_conn(cfg, s) diff --git a/tools/testing/selftests/drivers/net/psp_responder.c b/tools/testing/selftests/drivers/net/psp_responder.c index a26e7628bbb1..14b179e1aec8 100644 --- a/tools/testing/selftests/drivers/net/psp_responder.c +++ b/tools/testing/selftests/drivers/net/psp_responder.c @@ -37,20 +37,15 @@ static struct { unsigned char rx; } psp_vers; -static int conn_setup_psp(struct ynl_sock *ys, struct opts *opts, int data_sock) +#define PSP_MAX_KEY_LEN 32 + +static int +rx_assoc(struct ynl_sock *ys, __u32 *spi, char *key, unsigned int *key_len, + int data_sock) { struct psp_rx_assoc_rsp *rsp; struct psp_rx_assoc_req *req; - struct psp_tx_assoc_rsp *tsp; - struct psp_tx_assoc_req *teq; - char info[300]; - int key_len; - ssize_t sz; - __u32 spi; - dbg("create PSP connection\n"); - - // Rx assoc alloc req = psp_rx_assoc_req_alloc(); psp_rx_assoc_req_set_sock_fd(req, data_sock); @@ -64,29 +59,28 @@ static int conn_setup_psp(struct ynl_sock *ys, struct opts *opts, int data_sock) return -1; } - // SPI exchange - key_len = rsp->rx_key._len.key; - memcpy(info, &rsp->rx_key.spi, sizeof(spi)); - memcpy(&info[sizeof(spi)], rsp->rx_key.key, key_len); - sz = sizeof(spi) + key_len; + *key_len = rsp->rx_key._len.key; + memcpy(spi, &rsp->rx_key.spi, sizeof(*spi)); + memcpy(key, rsp->rx_key.key, *key_len); - send(data_sock, info, sz, MSG_WAITALL); psp_rx_assoc_rsp_free(rsp); - sz = recv(data_sock, info, sz, MSG_WAITALL); - if (sz < 0) { - perror("ERROR: failed to read PSP key from sock"); - return -1; - } - memcpy(&spi, info, sizeof(spi)); + return 0; +} + +static int +tx_assoc(struct ynl_sock *ys, __u8 version, __u32 spi, char *key, + unsigned int key_len, int data_sock) +{ + struct psp_tx_assoc_rsp *tsp; + struct psp_tx_assoc_req *teq; - // Setup Tx assoc teq = psp_tx_assoc_req_alloc(); psp_tx_assoc_req_set_sock_fd(teq, data_sock); - psp_tx_assoc_req_set_version(teq, psp_vers.tx); + psp_tx_assoc_req_set_version(teq, version); psp_tx_assoc_req_set_tx_key_spi(teq, spi); - psp_tx_assoc_req_set_tx_key_key(teq, &info[sizeof(spi)], key_len); + psp_tx_assoc_req_set_tx_key_key(teq, key, key_len); tsp = psp_tx_assoc(ys, teq); psp_tx_assoc_req_free(teq); @@ -99,6 +93,35 @@ static int conn_setup_psp(struct ynl_sock *ys, struct opts *opts, int data_sock) return 0; } +static int conn_setup_psp(struct ynl_sock *ys, struct opts *opts, int data_sock) +{ + char info[sizeof(__u32) + PSP_MAX_KEY_LEN]; + unsigned int key_len; + ssize_t sz; + __u32 spi; + + dbg("create PSP connection\n"); + + if (rx_assoc(ys, &spi, &info[sizeof(spi)], &key_len, data_sock)) + return -1; + + // SPI exchange + memcpy(info, &spi, sizeof(spi)); + sz = sizeof(spi) + key_len; + + send(data_sock, info, sz, MSG_WAITALL); + + sz = recv(data_sock, info, sz, MSG_WAITALL); + if (sz < 0) { + perror("ERROR: failed to read PSP key from sock"); + return -1; + } + memcpy(&spi, info, sizeof(spi)); + + return tx_assoc(ys, psp_vers.tx, spi, &info[sizeof(spi)], key_len, + data_sock); +} + static void send_ack(int sock) { send(sock, "ack", 4, MSG_WAITALL); @@ -282,7 +305,10 @@ run_session(struct ynl_sock *ys, struct opts *opts, /* nothing to do */ } else if (accept_cfg == ACCEPT_CFG_PSP) { dbg("new data sock: psp\n"); - conn_setup_psp(ys, opts, data_sock); + if (conn_setup_psp(ys, opts, data_sock)) { + close(data_sock); + data_sock = -1; + } } else { fprintf(stderr, "WARN: new data sock but no config\n"); } -- 2.52.0