1 /* SPDX-License-Identifier: BSD-3-Clause
2 * Copyright 2019 Mellanox Technologies, Ltd
10 #include <sys/socket.h>
18 #include "mlx5_utils.h"
21 /* PMD socket service for tools. */
23 #define MLX5_SOCKET_PATH "/var/tmp/dpdk_net_mlx5_%d"
25 int server_socket; /* Unix socket for primary process. */
26 struct rte_intr_handle server_intr_handle; /* Interrupt handler. */
29 * Handle server pmd socket interrupts.
32 mlx5_pmd_socket_handle(void *cb __rte_unused)
36 struct cmsghdr *cmsg = NULL;
38 char buf[CMSG_SPACE(sizeof(int))] = { 0 };
41 .iov_len = sizeof(data),
47 .msg_controllen = sizeof(buf),
52 struct rte_eth_dev *dev;
54 /* Accept the connection from the client. */
55 conn_sock = accept(server_socket, NULL, NULL);
57 DRV_LOG(WARNING, "connection failed: %s", strerror(errno));
60 ret = recvmsg(conn_sock, &msg, MSG_WAITALL);
62 DRV_LOG(WARNING, "wrong message received: %s",
66 /* Receive file descriptor. */
67 cmsg = CMSG_FIRSTHDR(&msg);
68 if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS ||
69 cmsg->cmsg_len < sizeof(int)) {
70 DRV_LOG(WARNING, "invalid file descriptor message");
73 memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
74 file = fdopen(fd, "w");
76 DRV_LOG(WARNING, "Failed to open file");
79 /* Receive port number. */
80 if (msg.msg_iovlen != 1 || msg.msg_iov->iov_len < sizeof(uint16_t)) {
81 DRV_LOG(WARNING, "wrong port number message");
84 memcpy(&port_id, msg.msg_iov->iov_base, sizeof(port_id));
85 if (!rte_eth_dev_is_valid_port(port_id)) {
86 DRV_LOG(WARNING, "Invalid port %u", port_id);
90 dev = &rte_eth_devices[port_id];
91 ret = mlx5_flow_dev_dump(dev, file, NULL);
92 /* Set-up the ancillary data and reply. */
93 msg.msg_controllen = 0;
94 msg.msg_control = NULL;
98 io.iov_len = sizeof(data);
101 ret = sendmsg(conn_sock, &msg, 0);
102 } while (ret < 0 && errno == EINTR);
104 DRV_LOG(WARNING, "failed to send response %s",
114 * Install interrupt handler.
117 * Pointer to Ethernet device.
119 * 0 on success, a negative errno value otherwise.
122 mlx5_pmd_interrupt_handler_install(void)
124 MLX5_ASSERT(server_socket);
125 server_intr_handle.fd = server_socket;
126 server_intr_handle.type = RTE_INTR_HANDLE_EXT;
127 return rte_intr_callback_register(&server_intr_handle,
128 mlx5_pmd_socket_handle, NULL);
132 * Uninstall interrupt handler.
135 mlx5_pmd_interrupt_handler_uninstall(void)
138 mlx5_intr_callback_unregister(&server_intr_handle,
139 mlx5_pmd_socket_handle,
142 server_intr_handle.fd = 0;
143 server_intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
147 * Initialise the socket to communicate with the secondary process
150 * Pointer to Ethernet device.
153 * 0 on success, a negative value otherwise.
156 mlx5_pmd_socket_init(void)
158 struct sockaddr_un sun = {
159 .sun_family = AF_UNIX,
164 MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
168 * Initialize the socket to communicate with the secondary
171 ret = socket(AF_UNIX, SOCK_STREAM, 0);
173 DRV_LOG(WARNING, "Failed to open mlx5 socket: %s",
178 flags = fcntl(server_socket, F_GETFL, 0);
181 ret = fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
184 snprintf(sun.sun_path, sizeof(sun.sun_path), MLX5_SOCKET_PATH,
186 remove(sun.sun_path);
187 ret = bind(server_socket, (const struct sockaddr *)&sun, sizeof(sun));
190 "cannot bind mlx5 socket: %s", strerror(errno));
193 ret = listen(server_socket, 0);
195 DRV_LOG(WARNING, "cannot listen on mlx5 socket: %s",
199 if (mlx5_pmd_interrupt_handler_install()) {
200 DRV_LOG(WARNING, "cannot register interrupt handler for mlx5 socket: %s",
206 remove(sun.sun_path);
208 claim_zero(close(server_socket));
210 DRV_LOG(ERR, "Cannot initialize socket: %s", strerror(errno));
215 * Un-Initialize the pmd socket
217 RTE_FINI(mlx5_pmd_socket_uninit)
221 mlx5_pmd_interrupt_handler_uninstall();
222 claim_zero(close(server_socket));
224 MKSTR(path, MLX5_SOCKET_PATH, getpid());
225 claim_zero(remove(path));