From 924e433ffbc863d9daecd633992e975bfd6addc3 Mon Sep 17 00:00:00 2001 From: Jukka Rissanen Date: Tue, 2 Mar 2021 14:45:31 +0200 Subject: [PATCH] net: context: Set target network interface in send if needed If we are sending a network packet and if the remote address is not set in the context (which means that connect() has not been called), then we must set the target network interface to a proper value. This is done so that when we select the local source address, we might select the wrong interface if we have multiple network interfaces in the system. In this case the packet would be always assigned to first network interface regardless of the destination address. Signed-off-by: Jukka Rissanen --- subsys/net/ip/net_context.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/subsys/net/ip/net_context.c b/subsys/net/ip/net_context.c index 66b4c1231a..71b24ae973 100644 --- a/subsys/net/ip/net_context.c +++ b/subsys/net/ip/net_context.c @@ -1462,6 +1462,20 @@ static int context_sendto(struct net_context *context, if (net_ipv6_is_addr_unspecified(&addr6->sin6_addr)) { return -EDESTADDRREQ; } + + /* If application has not yet set the destination address + * i.e., by not calling connect(), then set the interface + * here so that the packet gets sent to the correct network + * interface. This issue can be seen if there are multiple + * network interfaces and we are trying to send data to + * second or later network interface. + */ + if (addr6 && net_ipv6_is_addr_unspecified( + &net_sin6(&context->remote)->sin6_addr)) { + iface = net_if_ipv6_select_src_iface(&addr6->sin6_addr); + net_context_set_iface(context, iface); + } + } else if (IS_ENABLED(CONFIG_NET_IPV4) && net_context_get_family(context) == AF_INET) { const struct sockaddr_in *addr4 = @@ -1488,6 +1502,19 @@ static int context_sendto(struct net_context *context, if (!addr4->sin_addr.s_addr) { return -EDESTADDRREQ; } + + /* If application has not yet set the destination address + * i.e., by not calling connect(), then set the interface + * here so that the packet gets sent to the correct network + * interface. This issue can be seen if there are multiple + * network interfaces and we are trying to send data to + * second or later network interface. + */ + if (addr4 && net_sin(&context->remote)->sin_addr.s_addr == 0U) { + iface = net_if_ipv4_select_src_iface(&addr4->sin_addr); + net_context_set_iface(context, iface); + } + } else if (IS_ENABLED(CONFIG_NET_SOCKETS_PACKET) && net_context_get_family(context) == AF_PACKET) { struct sockaddr_ll *ll_addr = (struct sockaddr_ll *)dst_addr;