summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-08-27 20:12:10 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-08-31 08:31:46 +0200
commit7f6c35ba7a55503495c6b70cbd77dc0fc8a321c5 (patch)
treebcdb5bfbd67998bb371562aeb508fbe1b7f4f3b9 /src
parent36afe253e5def100585428abdab6c75b095a036f (diff)
downloadouroboros-7f6c35ba7a55503495c6b70cbd77dc0fc8a321c5.tar.gz
ouroboros-7f6c35ba7a55503495c6b70cbd77dc0fc8a321c5.zip
ipcpd: Assign random MAC on ETH poa with loopback
The loopback has an all-zero MAC, so two PoAs on a loopback receive their own frames and a PoA refuses its own FLOW_REQ, failing the flow with ECONNREFUSED. The shim IPCP didn't have this problem because it ignored requests for names not registered locally (shim-data). The PoA has no "local" name registry, it uses the unicast IPCP's directory (DHT) via IRMd query requests. This fixes the issue by generating a random locally administered MAC on the loopback device. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src')
-rw-r--r--src/lib/poa/eth.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/lib/poa/eth.c b/src/lib/poa/eth.c
index 5e959ef6..93ccbdfe 100644
--- a/src/lib/poa/eth.c
+++ b/src/lib/poa/eth.c
@@ -44,6 +44,7 @@
#include <ouroboros/hash.h>
#include <ouroboros/logs.h>
#include <ouroboros/pthread.h>
+#include <ouroboros/random.h>
#include <ouroboros/sockets.h>
#include <ouroboros/time.h>
@@ -316,6 +317,20 @@ static bool mac_is_zero(const uint8_t * mac)
return memcmp(mac, zero, POA_MAC_SIZE) == 0;
}
+/* Assign a random MAC on loopback interfaces (zero MAC). */
+static int eth_dev_mac(uint8_t * mac)
+{
+ if (!mac_is_zero(mac))
+ return 0;
+
+ if (random_buffer(mac, POA_MAC_SIZE) < 0)
+ return -1;
+
+ mac[0] = (mac[0] | 0x02) & 0xFE;
+
+ return 0;
+}
+
static bool eth_query_is_match(const struct eth_query * q,
const struct poa * poa)
{
@@ -805,6 +820,9 @@ static int eth_dev_info(const char * dev,
close(fd);
+ if (eth_dev_mac(mac) < 0)
+ return -EIO;
+
*mtu = MIN(MIN(ETH_MAX_MTU, POA_ETH_RD_BUF), (uint32_t) ifr.ifr_mtu);
if (memcmp(dev, "lo", 2) == 0 && *mtu > POA_ETH_LO_MTU)
*mtu = POA_ETH_LO_MTU;
@@ -1405,6 +1423,9 @@ static int eth_dev_info(const char * dev,
close(fd);
+ if (eth_dev_mac(mac) < 0)
+ return -1;
+
*mtu = MIN(MIN(ETH_MAX_MTU, POA_ETH_RD_BUF), (uint32_t) ifr.ifr_mtu);
if (memcmp(dev, "lo", 2) == 0 && *mtu > POA_ETH_LO_MTU)
*mtu = POA_ETH_LO_MTU;
@@ -1771,6 +1792,9 @@ static int eth_dev_info(const char * dev,
close(fd);
+ if (eth_dev_mac(mac) < 0)
+ return -1;
+
*mtu = MIN(MIN(ETH_MAX_MTU, POA_ETH_RD_BUF), (uint32_t) ifr.ifr_mtu);
if (memcmp(dev, "lo", 2) == 0 && *mtu > POA_ETH_LO_MTU)
*mtu = POA_ETH_LO_MTU;