[PATCH] 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
On Wed, 26 Nov 2025 19:53:16 -0500
Jon Maloy
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
--- arp.c | 3 +++ ndp.c | 5 +++-- tap.c | 27 +++++++++++++++++++++++++++ tap.h | 1 + 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;
Thanks for catching this one as well! I actually spotted the warning a while ago but never had time to investigate. Applied. -- Stefano
participants (2)
-
Jon Maloy
-
Stefano Brivio