blob: f5ee0b5a64874c954c48b61831dbb220ce210508 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* Copyright (c) Meta Platforms, Inc. and affiliates. (http://www.meta.com)
*/
/*
* This test verifies slirp responses to NC-SI commands.
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "slirp.h"
#include "ncsi-pkt.h"
#define NCSI_RESPONSE_CAPACITY 1024
static void test_ncsi_get_version_id(Slirp *slirp)
{
slirp->mfr_id = 0xabcdef01;
uint8_t command[] = {
/* Destination MAC */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Source MAC */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Ethertype */
0x88, 0xf8,
/* NC-SI Control packet header */
0x00, /* MC ID */
0x01, /* Header revision */
0x00, /* Reserved */
0x01, /* Instance ID */
0x15, /* Control Packet Type */
0x00, /* Channel ID */
0x00, /* Reserved */
0x00, /* Payload length */
0x00, 0x00, 0x00, 0x00, /* Reserved */
0x00, 0x00, 0x00, 0x00, /* Reserved */
};
slirp_input(slirp, command, sizeof(command));
const struct ncsi_rsp_gvi_pkt *gvi = (const struct ncsi_rsp_gvi_pkt *) ((const char*) slirp->opaque + ETH_HLEN);
assert(ntohs(gvi->rsp.code) == NCSI_PKT_RSP_C_COMPLETED);
assert(ntohs(gvi->rsp.code) == NCSI_PKT_RSP_R_NO_ERROR);
assert(ntohl(gvi->mf_id) == slirp->mfr_id);
slirp->mfr_id = 0;
}
static void test_ncsi_oem_mlx_unsupported_command(Slirp *slirp)
{
uint8_t command[] = {
/* Destination MAC */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Source MAC */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Ethertype */
0x88, 0xf8,
/* NC-SI Control packet header */
0x00, /* MC ID */
0x01, /* Header revision */
0x00, /* Reserved */
0x01, /* Instance ID */
0x50, /* Control Packet Type */
0x00, /* Channel ID */
0x00, /* Reserved */
0x08, /* Payload length */
0x00, 0x00, 0x00, 0x00, /* Reserved */
0x00, 0x00, 0x00, 0x00, /* Reserved */
/* NC-SI OEM packet header */
0x00, 0x00, 0x81, 0x19, /* Manufacturer ID: Mellanox */
/* Vendor Data */
0xff, /* Command Revision */
0xff, /* Command ID */
0x00, /* Parameter */
0x00, /* Optional data */
};
const struct ncsi_rsp_oem_pkt *oem = (const struct ncsi_rsp_oem_pkt *) ((const char*) slirp->opaque + ETH_HLEN);
slirp->mfr_id = 0x00000000;
slirp_input(slirp, command, sizeof(command));
assert(ntohs(oem->rsp.code) == NCSI_PKT_RSP_C_UNSUPPORTED);
assert(ntohs(oem->rsp.reason) == NCSI_PKT_RSP_R_UNKNOWN);
assert(ntohl(oem->mfr_id) == 0x8119);
slirp->mfr_id = 0x8119;
slirp_input(slirp, command, sizeof(command));
assert(ntohs(oem->rsp.code) == NCSI_PKT_RSP_C_UNSUPPORTED);
assert(ntohs(oem->rsp.reason) == NCSI_PKT_RSP_R_UNKNOWN);
assert(ntohl(oem->mfr_id) == 0x8119);
}
static void test_ncsi_oem_mlx_gma(Slirp *slirp)
{
uint8_t oob_eth_addr[ETH_ALEN] = {0xde, 0xad, 0xbe, 0xef, 0xca, 0xfe};
uint8_t command[] = {
/* Destination MAC */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Source MAC */
0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
/* Ethertype */
0x88, 0xf8,
/* NC-SI Control packet header */
0x00, /* MC ID */
0x01, /* Header revision */
0x00, /* Reserved */
0x01, /* Instance ID */
0x50, /* Control Packet Type */
0x00, /* Channel ID */
0x00, /* Reserved */
0x08, /* Payload length */
0x00, 0x00, 0x00, 0x00, /* Reserved */
0x00, 0x00, 0x00, 0x00, /* Reserved */
/* NC-SI OEM packet header */
0x00, 0x00, 0x81, 0x19, /* Manufacturer ID: Mellanox */
/* Vendor Data */
0x00, /* Command Revision */
0x00, /* Command ID */
0x1b, /* Parameter */
0x00, /* Optional data */
};
const struct ncsi_rsp_oem_pkt *oem = (const struct ncsi_rsp_oem_pkt *) ((const char*) slirp->opaque + ETH_HLEN);
memset(slirp->oob_eth_addr, 0, ETH_ALEN);
slirp->mfr_id = 0x8119;
slirp_input(slirp, command, sizeof(command));
assert(ntohs(oem->rsp.code) == NCSI_PKT_RSP_C_COMPLETED);
assert(ntohs(oem->rsp.reason) == NCSI_PKT_RSP_R_NO_ERROR);
assert(ntohl(oem->mfr_id) == slirp->mfr_id);
assert(ntohs(oem->rsp.common.length) == MLX_GMA_PAYLOAD_LEN);
assert(memcmp(slirp->oob_eth_addr, &oem->data[MLX_MAC_ADDR_OFFSET], ETH_ALEN) == 0);
assert(oem->data[MLX_GMA_STATUS_OFFSET] == 0);
memcpy(slirp->oob_eth_addr, oob_eth_addr, ETH_ALEN);
slirp_input(slirp, command, sizeof(command));
assert(ntohs(oem->rsp.code) == NCSI_PKT_RSP_C_COMPLETED);
assert(ntohs(oem->rsp.reason) == NCSI_PKT_RSP_R_NO_ERROR);
assert(ntohl(oem->mfr_id) == slirp->mfr_id);
assert(ntohs(oem->rsp.common.length) == MLX_GMA_PAYLOAD_LEN);
assert(memcmp(oob_eth_addr, &oem->data[MLX_MAC_ADDR_OFFSET], ETH_ALEN) == 0);
assert(oem->data[MLX_GMA_STATUS_OFFSET] == 1);
}
static slirp_ssize_t send_packet(const void *buf, size_t len, void *opaque)
{
assert(len <= NCSI_RESPONSE_CAPACITY);
memcpy(opaque, buf, len);
return len;
}
int main(int argc, char *argv[])
{
SlirpConfig config = {
.version = SLIRP_CONFIG_VERSION_MAX,
};
SlirpCb callbacks = {
.send_packet = send_packet,
};
Slirp *slirp = NULL;
uint8_t ncsi_response[NCSI_RESPONSE_CAPACITY];
slirp = slirp_new(&config, &callbacks, ncsi_response);
test_ncsi_get_version_id(slirp);
test_ncsi_oem_mlx_unsupported_command(slirp);
test_ncsi_oem_mlx_gma(slirp);
slirp_cleanup(slirp);
}