aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorJon Maloy <jmaloy@redhat.com>2025-11-26 19:53:16 -0500
committerStefano Brivio <sbrivio@redhat.com>2025-11-27 22:29:25 +0100
commit2002c7d39c9d4fa01099d7f780b66cfb213b6454 (patch)
tree3358e60e554c0bb8f5e9781fdc2d3d6a9b853127
parent391c15afedacbc4c5e01bfd05ef73be5ab1770ac (diff)
downloadpasst-2002c7d39c9d4fa01099d7f780b66cfb213b6454.tar
passt-2002c7d39c9d4fa01099d7f780b66cfb213b6454.tar.gz
passt-2002c7d39c9d4fa01099d7f780b66cfb213b6454.tar.bz2
passt-2002c7d39c9d4fa01099d7f780b66cfb213b6454.tar.lz
passt-2002c7d39c9d4fa01099d7f780b66cfb213b6454.tar.xz
passt-2002c7d39c9d4fa01099d7f780b66cfb213b6454.tar.zst
passt-2002c7d39c9d4fa01099d7f780b66cfb213b6454.zip
arp/ndp: don't send messages on uninitialized tap interface
When running pasta without --config-net, the tap interface is opened and assigned a valid file descriptor, but intentionally not brought up in the namespace. This is the expected behavior when the user wants to configure the namespace manually. However, in PASTA mode the code is attempting to send ARP announcements and NDP messages (initial requests and unsolicited NAs) based solely on whether c->fd_tap is valid, without checking if the interface actually is up and ready to transmit. This results in send failures, and when debug is activated (pasta -d) we see error printouts for these early messages. We now add new function tap_is_ready() which checks both conditions: - Whether fd_tap is valid (all modes) - Whether the tap interface is up (pasta mode only). In this mode, we use the existing c->pasta_conf_ns flag, which indicates whether pasta_ns_conf() configured and brought up the interface. This test is simple, and good enough for now. We update all functions that send unsolicited ARP/NDP messages to check with the new function before making any send attempt. This eliminates spurious send errors when starting pasta without --config-net, while preserving correct behavior when the interface is properly initialized. Signed-off-by: Jon Maloy <jmaloy@redhat.com> Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r--arp.c3
-rw-r--r--ndp.c5
-rw-r--r--tap.c27
-rw-r--r--tap.h1
4 files changed, 34 insertions, 2 deletions
diff --git a/arp.c b/arp.c
index 33b03cf..bb042e9 100644
--- a/arp.c
+++ b/arp.c
@@ -168,6 +168,9 @@ void arp_announce(const struct ctx *c, struct in_addr *ip,
struct arpmsg am;
} __attribute__((__packed__)) msg;
+ if (!tap_is_ready(c))
+ return;
+
/* Ethernet header */
msg.eh.h_proto = htons(ETH_P_ARP);
memcpy(msg.eh.h_dest, MAC_BROADCAST, sizeof(msg.eh.h_dest));
diff --git a/ndp.c b/ndp.c
index a33239d..eb9e313 100644
--- a/ndp.c
+++ b/ndp.c
@@ -227,7 +227,8 @@ static void ndp_na(const struct ctx *c, const struct in6_addr *dst,
*/
void ndp_unsolicited_na(const struct ctx *c, const struct in6_addr *addr)
{
- ndp_na(c, &in6addr_ll_all_nodes, addr);
+ if (tap_is_ready(c))
+ ndp_na(c, &in6addr_ll_all_nodes, addr);
}
/**
@@ -411,7 +412,7 @@ void ndp_timer(const struct ctx *c, const struct timespec *now)
time_t max_rtr_adv_interval = DEFAULT_MAX_RTR_ADV_INTERVAL;
time_t min_rtr_adv_interval, interval;
- if (c->fd_tap < 0 || c->no_ra || now->tv_sec < next_ra)
+ if (!tap_is_ready(c) || c->no_ra || now->tv_sec < next_ra)
return;
/* We must advertise before the route's lifetime expires */
diff --git a/tap.c b/tap.c
index bb139d6..44b0644 100644
--- a/tap.c
+++ b/tap.c
@@ -1340,6 +1340,30 @@ static void tap_sock_unix_init(const struct ctx *c)
}
/**
+ * tap_is_ready() - Check if tap interface is ready to send packets
+ * @c: Execution context
+ *
+ * For pasta mode, checks if the tap interface is up.
+ * For other modes, just checks if fd_tap is valid.
+ *
+ * Return: true if ready, false otherwise
+ */
+bool tap_is_ready(const struct ctx *c)
+{
+ if (c->fd_tap < 0)
+ return false;
+
+ if (c->mode == MODE_PASTA) {
+ /* If pasta_conf_ns is set, the interface was configured and
+ * brought up during initialization. If not, it's still down.
+ */
+ return c->pasta_conf_ns;
+ }
+
+ return true;
+}
+
+/**
* tap_start_connection() - start a new connection
* @c: Execution context
*/
@@ -1362,6 +1386,9 @@ static void tap_start_connection(const struct ctx *c)
epoll_add(c->epollfd, EPOLLIN | EPOLLRDHUP, ref);
+ if (!tap_is_ready(c))
+ return;
+
if (c->ifi4)
arp_send_init_req(c);
if (c->ifi6 && !c->no_ndp)
diff --git a/tap.h b/tap.h
index 1864173..ee22a9d 100644
--- a/tap.h
+++ b/tap.h
@@ -109,6 +109,7 @@ size_t tap_send_frames(const struct ctx *c, const struct iovec *iov,
size_t bufs_per_frame, size_t nframes);
void eth_update_mac(struct ethhdr *eh,
const unsigned char *eth_d, const unsigned char *eth_s);
+bool tap_is_ready(const struct ctx *c);
void tap_listen_handler(struct ctx *c, uint32_t events);
void tap_handler_pasta(struct ctx *c, uint32_t events,
const struct timespec *now);