From 1190aeb0f90222834231bc3af3f0a37fb4897722 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Wed, 28 Feb 2024 10:50:53 +0100 Subject: [PATCH] Skip interfaces without IPv4 addresses for mDNS 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. --- ...ip-interfaces-without-IPv4-addresses.patch | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 0008-MinMDNS-skip-interfaces-without-IPv4-addresses.patch diff --git a/0008-MinMDNS-skip-interfaces-without-IPv4-addresses.patch b/0008-MinMDNS-skip-interfaces-without-IPv4-addresses.patch new file mode 100644 index 0000000..0e6a8b2 --- /dev/null +++ b/0008-MinMDNS-skip-interfaces-without-IPv4-addresses.patch @@ -0,0 +1,96 @@ +From 72e9a1c20118b6c41c750a8bcaca578ff85488e2 Mon Sep 17 00:00:00 2001 +From: Stefan Agner +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 +