aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2025-04-15 17:16:20 +1000
committerStefano Brivio <sbrivio@redhat.com>2025-04-15 19:45:09 +0200
commit3f995586b35494b08631081fbf609ff932110849 (patch)
tree1b8d2fcc5e4c740bd312f87a31e37e98cb6f505c
parent1bb8145c221a9124ca1671e64b27de173ff2d82d (diff)
downloadpasst-3f995586b35494b08631081fbf609ff932110849.tar
passt-3f995586b35494b08631081fbf609ff932110849.tar.gz
passt-3f995586b35494b08631081fbf609ff932110849.tar.bz2
passt-3f995586b35494b08631081fbf609ff932110849.tar.lz
passt-3f995586b35494b08631081fbf609ff932110849.tar.xz
passt-3f995586b35494b08631081fbf609ff932110849.tar.zst
passt-3f995586b35494b08631081fbf609ff932110849.zip
udp: Pass socket & flow information direction to error handling functions
udp_sock_recverr() and udp_sock_errs() take an epoll reference from which they obtain both the socket fd to receive errors from, and - for flow specific sockets - the flow and side the socket is associated with. We have some upcoming cases where we want to clear errors when we're not directly associated with receiving an epoll event, so it's not natural to have an epoll reference. Therefore, make these functions take the socket and flow from explicit parameters. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--udp.c26
1 files changed, 13 insertions, 13 deletions
diff --git a/udp.c b/udp.c
index 154f99b..c51ac95 100644
--- a/udp.c
+++ b/udp.c
@@ -467,14 +467,15 @@ static void udp_send_tap_icmp6(const struct ctx *c,
/**
* udp_sock_recverr() - Receive and clear an error from a socket
* @c: Execution context
- * @ref: epoll reference
+ * @s: Socket to receive errors from
+ * @sidx: Flow and side of @s, or FLOW_SIDX_NONE if unknown
*
* Return: 1 if error received and processed, 0 if no more errors in queue, < 0
* if there was an error reading the queue
*
* #syscalls recvmsg
*/
-static int udp_sock_recverr(const struct ctx *c, union epoll_ref ref)
+static int udp_sock_recverr(const struct ctx *c, int s, flow_sidx_t sidx)
{
struct errhdr {
struct sock_extended_err ee;
@@ -484,7 +485,6 @@ static int udp_sock_recverr(const struct ctx *c, union epoll_ref ref)
char data[ICMP6_MAX_DLEN];
const struct errhdr *eh;
struct cmsghdr *hdr;
- int s = ref.fd;
struct iovec iov = {
.iov_base = data,
.iov_len = sizeof(data)
@@ -525,12 +525,12 @@ static int udp_sock_recverr(const struct ctx *c, union epoll_ref ref)
}
eh = (const struct errhdr *)CMSG_DATA(hdr);
- if (ref.type == EPOLL_TYPE_UDP) {
- flow_sidx_t sidx = flow_sidx_opposite(ref.flowside);
- const struct flowside *toside = flowside_at_sidx(sidx);
+ if (flow_sidx_valid(sidx)) {
+ flow_sidx_t tosidx = flow_sidx_opposite(sidx);
+ const struct flowside *toside = flowside_at_sidx(tosidx);
size_t dlen = rc;
- if (pif_is_socket(pif_at_sidx(sidx))) {
+ if (pif_is_socket(pif_at_sidx(tosidx))) {
/* XXX Is there any way to propagate ICMPs from socket
* to socket? */
} else if (hdr->cmsg_level == IPPROTO_IP) {
@@ -554,21 +554,21 @@ static int udp_sock_recverr(const struct ctx *c, union epoll_ref ref)
/**
* udp_sock_errs() - Process errors on a socket
* @c: Execution context
- * @ref: epoll reference
+ * @s: Socket to receive errors from
+ * @sidx: Flow and side of @s, or FLOW_SIDX_NONE if unknown
*
* Return: Number of errors handled, or < 0 if we have an unrecoverable error
*/
-static int udp_sock_errs(const struct ctx *c, union epoll_ref ref)
+static int udp_sock_errs(const struct ctx *c, int s, flow_sidx_t sidx)
{
unsigned n_err = 0;
socklen_t errlen;
- int s = ref.fd;
int rc, err;
ASSERT(!c->no_udp);
/* Empty the error queue */
- while ((rc = udp_sock_recverr(c, ref)) > 0)
+ while ((rc = udp_sock_recverr(c, s, sidx)) > 0)
n_err += rc;
if (rc < 0)
@@ -777,7 +777,7 @@ void udp_listen_sock_handler(const struct ctx *c,
const struct timespec *now)
{
if (events & EPOLLERR) {
- if (udp_sock_errs(c, ref) < 0) {
+ if (udp_sock_errs(c, ref.fd, FLOW_SIDX_NONE) < 0) {
err("UDP: Unrecoverable error on listening socket:"
" (%s port %hu)", pif_name(ref.udp.pif), ref.udp.port);
/* FIXME: what now? close/re-open socket? */
@@ -804,7 +804,7 @@ void udp_sock_handler(const struct ctx *c, union epoll_ref ref,
ASSERT(!c->no_udp && uflow);
if (events & EPOLLERR) {
- if (udp_sock_errs(c, ref) < 0) {
+ if (udp_sock_errs(c, ref.fd, ref.flowside) < 0) {
flow_err(uflow, "Unrecoverable error on flow socket");
goto fail;
}