Skip to content

Commit

Permalink
Skip interfaces without IPv4 addresses for mDNS
Browse files Browse the repository at this point in the history
Instead of blindly try to use every interface for IPv4, add a patch
which filters interfaces without IPv4 addresses. IPv4 addresses are
required for any multicast operation, so an interface without IPv4
address will never be able to use mDNS.
  • Loading branch information
agners committed Feb 28, 2024
1 parent f52e36a commit 1190aeb
Showing 1 changed file with 96 additions and 0 deletions.
96 changes: 96 additions & 0 deletions 0008-MinMDNS-skip-interfaces-without-IPv4-addresses.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
From 72e9a1c20118b6c41c750a8bcaca578ff85488e2 Mon Sep 17 00:00:00 2001
From: Stefan Agner <[email protected]>
Date: Wed, 28 Feb 2024 10:38:37 +0100
Subject: [PATCH] MinMDNS skip interfaces without IPv4 addresses

IPv4 multicast require an IPv4 address to be present on a particular
interface. Skip interfaces without IPv4 addresses in the default
address policy. This avoids errors when trying to join the multicast
group later on:
MDNS failed to join multicast group on veth3cdf62f for address type IPv4: src/inet/UDPEndPointImplSockets.cpp:777: Inet Error 0x00000110: Address not found
---
.../minimal_mdns/AddressPolicy_LibNlImpl.cpp | 42 +++++++++++++++++--
1 file changed, 38 insertions(+), 4 deletions(-)

diff --git a/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp b/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp
index e73627f423..b1802c8d25 100644
--- a/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp
+++ b/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp
@@ -48,6 +48,7 @@ private:

nl_sock * mNlSocket = nullptr;
nl_cache * mNlCache = nullptr;
+ nl_cache * mNlAddrCache = nullptr;
nl_object * mCurrentLink = nullptr;
IPAddressType mCurrentLinkType = IPAddressType::kUnknown;

@@ -94,6 +95,12 @@ AllListenIterator::~AllListenIterator()
mNlCache = nullptr;
}

+ if (mNlAddrCache != nullptr)
+ {
+ nl_cache_free(mNlAddrCache);
+ mNlAddrCache = nullptr;
+ }
+
if (mNlSocket != nullptr)
{
nl_socket_free(mNlSocket);
@@ -151,7 +158,6 @@ bool AllListenIterator::Next(InterfaceId * id, IPAddressType * type)
while (true)
{
#if INET_CONFIG_ENABLE_IPV4
- // FOR IPv4, report all interfaces as 'try IPv4 here as well'
if (mCurrentLinkType == IPAddressType::kIPv6)
{
mCurrentLinkType = IPAddressType::kIPv4;
@@ -176,14 +182,42 @@ bool AllListenIterator::Next(InterfaceId * id, IPAddressType * type)
continue;
}

- int idx = rtnl_link_get_ifindex(CurrentLink());
- if (idx == 0)
+ int ifindex = rtnl_link_get_ifindex(CurrentLink());
+ if (ifindex == 0)
{
// Invalid index, move to the next interface
continue;
}

- *id = InterfaceId(idx);
+ // For IPv4, report only interfaces which have an IPv4 address
+ if (mCurrentLinkType == IPAddressType::kIPv4)
+ {
+ if (mNlAddrCache == nullptr)
+ {
+ int result = rtnl_addr_alloc_cache(mNlSocket, &mNlAddrCache);
+ if (result != 0)
+ {
+ ChipLogError(Inet, "Failed to cache addresses");
+ return false;
+ }
+ }
+
+ // Find IPv4 address for this interface
+ struct rtnl_addr * filter = rtnl_addr_alloc();
+ rtnl_addr_set_family(filter, AF_INET);
+ rtnl_addr_set_ifindex(filter, ifindex);
+
+ struct nl_object * addr = nl_cache_find(mNlAddrCache, OBJ_CAST(filter));
+ nl_object_put(OBJ_CAST(filter));
+
+ // No IPv4 address, skip this interface for IPv4.
+ if (addr == nullptr)
+ continue;
+
+ nl_object_put(addr);
+ }
+
+ *id = InterfaceId(ifindex);
*type = mCurrentLinkType; // advancing should have set this
return true;
}
--
2.44.0

0 comments on commit 1190aeb

Please sign in to comment.