net: IPv6: Fix source address for mesh multicast destination
Currently there is chosen the link local address as a source address
for each multicast destination address. It is a bug for OpenThread
network where the mesh-local EID addres should be picked in this case.
This commit fixes it by distinquish the mesh local multicast among any
others.
Signed-off-by: Lukasz Maciejonczyk <lukasz.maciejonczyk@nordicsemi.no>
diff --git a/include/net/net_ip.h b/include/net/net_ip.h
index 0a2ea18..4f021d9 100644
--- a/include/net/net_ip.h
+++ b/include/net/net_ip.h
@@ -931,6 +931,20 @@
}
/**
+ * @brief Check if the IPv6 address is a mesh-local scope multicast
+ * address (FFx3::).
+ *
+ * @param addr IPv6 address.
+ *
+ * @return True if the address is a mesh-local scope multicast address,
+ * false otherwise.
+ */
+static inline bool net_ipv6_is_addr_mcast_mesh(const struct in6_addr *addr)
+{
+ return net_ipv6_is_addr_mcast_scope(addr, 0x03);
+}
+
+/**
* @brief Check if the IPv6 address is a site scope multicast
* address (FFx5::).
*
diff --git a/subsys/net/ip/net_if.c b/subsys/net/ip/net_if.c
index 6ba7a66..8c5d91d 100644
--- a/subsys/net/ip/net_if.c
+++ b/subsys/net/ip/net_if.c
@@ -2347,7 +2347,8 @@
/* Mesh local address can only be selected for the same
* subnet.
*/
- if (ipv6->unicast[i].is_mesh_local && len < 64) {
+ if (ipv6->unicast[i].is_mesh_local && len < 64 &&
+ !net_ipv6_is_addr_mcast_mesh(dst)) {
continue;
}
@@ -2366,8 +2367,8 @@
uint8_t best_match = 0U;
struct net_if *iface;
- if (!net_ipv6_is_ll_addr(dst) && !net_ipv6_is_addr_mcast(dst)) {
-
+ if (!net_ipv6_is_ll_addr(dst) && (!net_ipv6_is_addr_mcast(dst) ||
+ net_ipv6_is_addr_mcast_mesh(dst))) {
for (iface = __net_if_start;
!dst_iface && iface != __net_if_end;
iface++) {