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 int server_socket; /* Unix socket for primary process. */
24 struct rte_intr_handle server_intr_handle; /* Interrupt handler. */
27 mlx5_pmd_make_path(struct sockaddr_un *addr, int pid)
29 snprintf(addr->sun_path, sizeof(addr->sun_path), "/var/tmp/dpdk_%s_%d",
30 MLX5_DRIVER_NAME, pid);
34 * Handle server pmd socket interrupts.
37 mlx5_pmd_socket_handle(void *cb __rte_unused)
41 struct cmsghdr *cmsg = NULL;
43 char buf[CMSG_SPACE(sizeof(int))] = { 0 };
46 .iov_len = sizeof(data),
52 .msg_controllen = sizeof(buf),
57 struct rte_eth_dev *dev;
59 /* Accept the connection from the client. */
60 conn_sock = accept(server_socket, NULL, NULL);
62 DRV_LOG(WARNING, "connection failed: %s", strerror(errno));
65 ret = recvmsg(conn_sock, &msg, MSG_WAITALL);
67 DRV_LOG(WARNING, "wrong message received: %s",
71 /* Receive file descriptor. */
72 cmsg = CMSG_FIRSTHDR(&msg);
73 if (cmsg == NULL || cmsg->cmsg_type != SCM_RIGHTS ||
74 cmsg->cmsg_len < sizeof(int)) {
75 DRV_LOG(WARNING, "invalid file descriptor message");
78 memcpy(&fd, CMSG_DATA(cmsg), sizeof(fd));
79 file = fdopen(fd, "w");
81 DRV_LOG(WARNING, "Failed to open file");
84 /* Receive port number. */
85 if (msg.msg_iovlen != 1 || msg.msg_iov->iov_len < sizeof(uint16_t)) {
86 DRV_LOG(WARNING, "wrong port number message");
89 memcpy(&port_id, msg.msg_iov->iov_base, sizeof(port_id));
90 if (!rte_eth_dev_is_valid_port(port_id)) {
91 DRV_LOG(WARNING, "Invalid port %u", port_id);
95 dev = &rte_eth_devices[port_id];
96 ret = mlx5_flow_dev_dump(dev, file, NULL);
97 /* Set-up the ancillary data and reply. */
98 msg.msg_controllen = 0;
99 msg.msg_control = NULL;
103 io.iov_len = sizeof(data);
106 ret = sendmsg(conn_sock, &msg, 0);
107 } while (ret < 0 && errno == EINTR);
109 DRV_LOG(WARNING, "failed to send response %s",
119 * Install interrupt handler.
122 * Pointer to Ethernet device.
124 * 0 on success, a negative errno value otherwise.
127 mlx5_pmd_interrupt_handler_install(void)
129 MLX5_ASSERT(server_socket);
130 server_intr_handle.fd = server_socket;
131 server_intr_handle.type = RTE_INTR_HANDLE_EXT;
132 return rte_intr_callback_register(&server_intr_handle,
133 mlx5_pmd_socket_handle, NULL);
137 * Uninstall interrupt handler.
140 mlx5_pmd_interrupt_handler_uninstall(void)
143 mlx5_intr_callback_unregister(&server_intr_handle,
144 mlx5_pmd_socket_handle,
147 server_intr_handle.fd = 0;
148 server_intr_handle.type = RTE_INTR_HANDLE_UNKNOWN;
152 * Initialise the socket to communicate with the secondary process
155 * Pointer to Ethernet device.
158 * 0 on success, a negative value otherwise.
161 mlx5_pmd_socket_init(void)
163 struct sockaddr_un sun = {
164 .sun_family = AF_UNIX,
169 MLX5_ASSERT(rte_eal_process_type() == RTE_PROC_PRIMARY);
173 * Initialize the socket to communicate with the secondary
176 ret = socket(AF_UNIX, SOCK_STREAM, 0);
178 DRV_LOG(WARNING, "Failed to open mlx5 socket: %s",
183 flags = fcntl(server_socket, F_GETFL, 0);
186 ret = fcntl(server_socket, F_SETFL, flags | O_NONBLOCK);
189 mlx5_pmd_make_path(&sun, getpid());
190 remove(sun.sun_path);
191 ret = bind(server_socket, (const struct sockaddr *)&sun, sizeof(sun));
194 "cannot bind mlx5 socket: %s", strerror(errno));
197 ret = listen(server_socket, 0);
199 DRV_LOG(WARNING, "cannot listen on mlx5 socket: %s",
203 if (mlx5_pmd_interrupt_handler_install()) {
204 DRV_LOG(WARNING, "cannot register interrupt handler for mlx5 socket: %s",
210 remove(sun.sun_path);
212 claim_zero(close(server_socket));
214 DRV_LOG(ERR, "Cannot initialize socket: %s", strerror(errno));
219 * Un-Initialize the pmd socket
221 RTE_FINI(mlx5_pmd_socket_uninit)
225 mlx5_pmd_interrupt_handler_uninstall();
226 claim_zero(close(server_socket));
228 MKSTR(path, "/var/tmp/dpdk_%s_%d", MLX5_DRIVER_NAME, getpid());
229 claim_zero(remove(path));