diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-08-27 20:12:10 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-08-31 08:31:46 +0200 |
| commit | 7f6c35ba7a55503495c6b70cbd77dc0fc8a321c5 (patch) | |
| tree | bcdb5bfbd67998bb371562aeb508fbe1b7f4f3b9 /src/lib/poa | |
| parent | 36afe253e5def100585428abdab6c75b095a036f (diff) | |
| download | ouroboros-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/lib/poa')
| -rw-r--r-- | src/lib/poa/eth.c | 24 |
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; |
