From 7b0d48fbb3ceebcafb18177fba02ab1a9ad4c24e Mon Sep 17 00:00:00 2001 From: Mohsin Kazmi Date: Tue, 7 Mar 2023 11:07:56 +0000 Subject: [PATCH] af_packet: fix the broken functionality upon admin down Type: fix In vpp, file descriptor handler closes the fd upon error if there is no error handling function is registered. This patch fixes the issue for af_packet interface by registering the error handling function. Errors will also be gracefully logged. Signed-off-by: Mohsin Kazmi Change-Id: I260d780ac54ffd0199dcd6ca5b95e5afe957e968 --- src/plugins/af_packet/af_packet.c | 21 ++++++++++++++++++ src/plugins/af_packet/device.c | 45 ++++----------------------------------- 2 files changed, 25 insertions(+), 41 deletions(-) diff --git a/src/plugins/af_packet/af_packet.c b/src/plugins/af_packet/af_packet.c index b2f860e658d..f505fac9e2c 100644 --- a/src/plugins/af_packet/af_packet.c +++ b/src/plugins/af_packet/af_packet.c @@ -110,6 +110,26 @@ af_packet_fd_read_ready (clib_file_t * uf) return 0; } +static clib_error_t * +af_packet_fd_error (clib_file_t *uf) +{ + af_packet_main_t *apm = &af_packet_main; + clib_error_t *err = 0; + u64 u64; + + int ret = read (uf->file_descriptor, (char *) &u64, sizeof (u64)); + + if (ret < 0) + { + err = clib_error_return_unix (0, ""); + vlib_log_notice (apm->log_class, "fd %u %U", uf->file_descriptor, + format_clib_error, err); + clib_error_free (err); + } + + return 0; +} + static int is_bridge (const u8 * host_if_name) { @@ -146,6 +166,7 @@ af_packet_set_rx_queues (vlib_main_t *vm, af_packet_if_t *apif) { clib_file_t template = { 0 }; template.read_function = af_packet_fd_read_ready; + template.error_function = af_packet_fd_error; template.file_descriptor = rx_queue->fd; template.private_data = rx_queue->queue_index; template.flags = UNIX_FILE_EVENT_EDGE_TRIGGERED; diff --git a/src/plugins/af_packet/device.c b/src/plugins/af_packet/device.c index 27f5559c8cd..fc6733fc446 100644 --- a/src/plugins/af_packet/device.c +++ b/src/plugins/af_packet/device.c @@ -35,6 +35,7 @@ #include #include +#include #define foreach_af_packet_tx_func_error \ _(FRAME_NOT_READY, "tx frame not ready") \ @@ -654,63 +655,25 @@ af_packet_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, af_packet_if_t *apif = pool_elt_at_index (apm->interfaces, hw->dev_instance); u32 hw_flags; - int rv, fd = socket (AF_UNIX, SOCK_DGRAM, 0); - struct ifreq ifr; - - if (0 > fd) - { - vlib_log_warn (apm->log_class, "af_packet_%s could not open socket", - apif->host_if_name); - return 0; - } - /* if interface is a bridge ignore */ if (apif->host_if_index < 0) - goto error; /* no error */ - - /* use host_if_index in case host name has changed */ - ifr.ifr_ifindex = apif->host_if_index; - if ((rv = ioctl (fd, SIOCGIFNAME, &ifr)) < 0) - { - vlib_log_warn (apm->log_class, - "af_packet_%s ioctl could not retrieve eth name", - apif->host_if_name); - goto error; - } + return 0; /* no error */ apif->is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0; - if ((rv = ioctl (fd, SIOCGIFFLAGS, &ifr)) < 0) - { - vlib_log_warn (apm->log_class, "af_packet_%s error: %d", - apif->is_admin_up ? "up" : "down", rv); - goto error; - } - if (apif->is_admin_up) { hw_flags = VNET_HW_INTERFACE_FLAG_LINK_UP; - ifr.ifr_flags |= IFF_UP; + vnet_netlink_set_link_state (apif->host_if_index, 1); } else { hw_flags = 0; - ifr.ifr_flags &= ~IFF_UP; - } - - if ((rv = ioctl (fd, SIOCSIFFLAGS, &ifr)) < 0) - { - vlib_log_warn (apm->log_class, "af_packet_%s error: %d", - apif->is_admin_up ? "up" : "down", rv); - goto error; + vnet_netlink_set_link_state (apif->host_if_index, 0); } vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags); -error: - if (0 <= fd) - close (fd); - return 0; /* no error */ } -- 2.16.6