|
| 1 | +From 72e9a1c20118b6c41c750a8bcaca578ff85488e2 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Stefan Agner <stefan@agner.ch> |
| 3 | +Date: Wed, 28 Feb 2024 10:38:37 +0100 |
| 4 | +Subject: [PATCH] MinMDNS skip interfaces without IPv4 addresses |
| 5 | + |
| 6 | +IPv4 multicast require an IPv4 address to be present on a particular |
| 7 | +interface. Skip interfaces without IPv4 addresses in the default |
| 8 | +address policy. This avoids errors when trying to join the multicast |
| 9 | +group later on: |
| 10 | +MDNS failed to join multicast group on veth3cdf62f for address type IPv4: src/inet/UDPEndPointImplSockets.cpp:777: Inet Error 0x00000110: Address not found |
| 11 | +--- |
| 12 | + .../minimal_mdns/AddressPolicy_LibNlImpl.cpp | 42 +++++++++++++++++-- |
| 13 | + 1 file changed, 38 insertions(+), 4 deletions(-) |
| 14 | + |
| 15 | +diff --git a/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp b/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp |
| 16 | +index e73627f423..b1802c8d25 100644 |
| 17 | +--- a/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp |
| 18 | ++++ b/src/lib/dnssd/minimal_mdns/AddressPolicy_LibNlImpl.cpp |
| 19 | +@@ -48,6 +48,7 @@ private: |
| 20 | + |
| 21 | + nl_sock * mNlSocket = nullptr; |
| 22 | + nl_cache * mNlCache = nullptr; |
| 23 | ++ nl_cache * mNlAddrCache = nullptr; |
| 24 | + nl_object * mCurrentLink = nullptr; |
| 25 | + IPAddressType mCurrentLinkType = IPAddressType::kUnknown; |
| 26 | + |
| 27 | +@@ -94,6 +95,12 @@ AllListenIterator::~AllListenIterator() |
| 28 | + mNlCache = nullptr; |
| 29 | + } |
| 30 | + |
| 31 | ++ if (mNlAddrCache != nullptr) |
| 32 | ++ { |
| 33 | ++ nl_cache_free(mNlAddrCache); |
| 34 | ++ mNlAddrCache = nullptr; |
| 35 | ++ } |
| 36 | ++ |
| 37 | + if (mNlSocket != nullptr) |
| 38 | + { |
| 39 | + nl_socket_free(mNlSocket); |
| 40 | +@@ -151,7 +158,6 @@ bool AllListenIterator::Next(InterfaceId * id, IPAddressType * type) |
| 41 | + while (true) |
| 42 | + { |
| 43 | + #if INET_CONFIG_ENABLE_IPV4 |
| 44 | +- // FOR IPv4, report all interfaces as 'try IPv4 here as well' |
| 45 | + if (mCurrentLinkType == IPAddressType::kIPv6) |
| 46 | + { |
| 47 | + mCurrentLinkType = IPAddressType::kIPv4; |
| 48 | +@@ -176,14 +182,42 @@ bool AllListenIterator::Next(InterfaceId * id, IPAddressType * type) |
| 49 | + continue; |
| 50 | + } |
| 51 | + |
| 52 | +- int idx = rtnl_link_get_ifindex(CurrentLink()); |
| 53 | +- if (idx == 0) |
| 54 | ++ int ifindex = rtnl_link_get_ifindex(CurrentLink()); |
| 55 | ++ if (ifindex == 0) |
| 56 | + { |
| 57 | + // Invalid index, move to the next interface |
| 58 | + continue; |
| 59 | + } |
| 60 | + |
| 61 | +- *id = InterfaceId(idx); |
| 62 | ++ // For IPv4, report only interfaces which have an IPv4 address |
| 63 | ++ if (mCurrentLinkType == IPAddressType::kIPv4) |
| 64 | ++ { |
| 65 | ++ if (mNlAddrCache == nullptr) |
| 66 | ++ { |
| 67 | ++ int result = rtnl_addr_alloc_cache(mNlSocket, &mNlAddrCache); |
| 68 | ++ if (result != 0) |
| 69 | ++ { |
| 70 | ++ ChipLogError(Inet, "Failed to cache addresses"); |
| 71 | ++ return false; |
| 72 | ++ } |
| 73 | ++ } |
| 74 | ++ |
| 75 | ++ // Find IPv4 address for this interface |
| 76 | ++ struct rtnl_addr * filter = rtnl_addr_alloc(); |
| 77 | ++ rtnl_addr_set_family(filter, AF_INET); |
| 78 | ++ rtnl_addr_set_ifindex(filter, ifindex); |
| 79 | ++ |
| 80 | ++ struct nl_object * addr = nl_cache_find(mNlAddrCache, OBJ_CAST(filter)); |
| 81 | ++ nl_object_put(OBJ_CAST(filter)); |
| 82 | ++ |
| 83 | ++ // No IPv4 address, skip this interface for IPv4. |
| 84 | ++ if (addr == nullptr) |
| 85 | ++ continue; |
| 86 | ++ |
| 87 | ++ nl_object_put(addr); |
| 88 | ++ } |
| 89 | ++ |
| 90 | ++ *id = InterfaceId(ifindex); |
| 91 | + *type = mCurrentLinkType; // advancing should have set this |
| 92 | + return true; |
| 93 | + } |
| 94 | +-- |
| 95 | +2.44.0 |
| 96 | + |
0 commit comments