Skip to content

Commit

Permalink
Network: add support for simultaneous outgoing connections via differ…
Browse files Browse the repository at this point in the history
…ent network interfaces
  • Loading branch information
furbanc authored and RobertRostohar committed Jan 17, 2025
1 parent fe3adcc commit 49f1739
Show file tree
Hide file tree
Showing 11 changed files with 125 additions and 44 deletions.
5 changes: 3 additions & 2 deletions Components/Network/Include/rl_net.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::Network
* Copyright (c) 2004-2024 Arm Limited (or its affiliates). All rights reserved.
* Copyright (c) 2004-2025 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: rl_net.h
* Purpose: Network API
Expand All @@ -17,7 +17,7 @@

/// Network component version
#define MW_NET_VERSION_MAJOR 8
#define MW_NET_VERSION_MINOR 0
#define MW_NET_VERSION_MINOR 1
#define MW_NET_VERSION_PATCH 0

#ifdef __cplusplus
Expand Down Expand Up @@ -136,6 +136,7 @@ typedef enum {
typedef enum {
netTCP_OptionTOS = 0, ///< IPv4 Type of Service; val=TOS
netTCP_OptionTrafficClass, ///< IPv6 Traffic Class; val=TrafficClass
netTCP_OptionInterface, ///< Network interface to bind; val=if_id (class and number)
netTCP_OptionTimeout, ///< TCP Idle Timeout; val=timeout (in seconds)
netTCP_OptionKeepAlive, ///< TCP Keep Alive; val: 0=disabled (default), 1=enabled
netTCP_OptionFlowControl, ///< TCP Flow Control; val: 0=disabled (default), 1=enabled
Expand Down
16 changes: 9 additions & 7 deletions Components/Network/Network.scvd
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>

<component_viewer schemaVersion="0.1" xmlns:xs="http://www.w3.org/2001/XMLSchema-instance" xs:noNamespaceSchemaLocation="Component_Viewer.xsd">
<component name="Network" shortname="NET" version="8.0.1"/> <!-- name and version of the component -->
<component name="Network" shortname="NET" version="8.1.0"/> <!-- name and version of the component -->

<typedefs>
<!-- Network Library variant -->
Expand Down Expand Up @@ -745,7 +745,7 @@
<enum name="TTL" value="1" info="IPv4 Multi-cast Time to Live"/>
<enum name="TrafficClass" value="2" info="IPv6 Traffic Class"/>
<enum name="HopLimit" value="3" info="IPv6 Multi-cast Hop limit"/>
<enum name="Interface" value="4" info="Broadcast Network interface"/>
<enum name="Interface" value="4" info="Bound Network interface"/>
<enum name="Checksum" value="5" info="Checksum Options"/>
</member>
</typedef>
Expand Down Expand Up @@ -808,10 +808,11 @@
<member name="id" type="uint8_t" offset="0">
<enum name="TOS" value="0" info="IPv4 Type of Service"/>
<enum name="TrafficClass" value="1" info="IPv6 Traffic Class"/>
<enum name="Timeout" value="2" info="TCP Idle Timeout"/>
<enum name="KeepAlive" value="3" info="TCP Keep Alive"/>
<enum name="FlowControl" value="4" info="TCP Flow Control"/>
<enum name="DelayedACK" value="5" info="TCP Delayed Acknowledgment"/>
<enum name="Interface" value="2" info="Bound Network interface"/>
<enum name="Timeout" value="3" info="TCP Idle Timeout"/>
<enum name="KeepAlive" value="4" info="TCP Keep Alive"/>
<enum name="FlowControl" value="5" info="TCP Flow Control"/>
<enum name="DelayedACK" value="6" info="TCP Delayed Acknowledgment"/>
</member>
</typedef>

Expand Down Expand Up @@ -2110,7 +2111,7 @@
<event id="19 + 0xD000" level="Detail" property="SetOptionTclass" value="socket=%d[val1], tclass=%d[val2]" info="Set socket option traffic class for IPv6"/>
<event id="20 + 0xD000" level="Detail" property="SetOptionHopLimit" value="socket=%d[val1], hop_limit=%d[val2]" info="Set socket option hop limit for IPv6"/>
<event id="21 + 0xD000" level="Detail" property="SetOptionChecksum" value="socket=%d[val1], send=%t[val2 &amp; 1 ? &quot;On&quot; : &quot;Off&quot;], verify=%t[val2 &amp; 2 ? &quot;On&quot; : &quot;Off&quot;]" info="Set socket checksum calculation options"/>
<event id="42 + 0xD000" level="Detail" property="SetOptionInterface" value="socket=%d[val1], netif=%E[val2, NetIf:id]" info="Set Network Interface for broadcasts and multicasts"/>
<event id="42 + 0xD000" level="Detail" property="SetOptionInterface" value="socket=%d[val1], netif=%E[val2, NetIf:id]" info="Set Network Interface for broadcasts, multicasts and internet access"/>
<event id="22 + 0xD000" level="Error" property="SetOptionWrongOption" value="socket=%d[val1], opt=%E[val2, UDP_Opt:id]" info="Invalid option requested"/>
<event id="23 + 0xD000" level="Error" property="SetOptionWrongValue" value="socket=%d[val1], value=%d[val2]" info="Invalid value for option provided"/>
<event id="24 + 0xD000" level="Error" property="GetBufferFailed" value="size=%d[val1]" info="GetBuffer failed, out of memory error"/>
Expand Down Expand Up @@ -2189,6 +2190,7 @@
<event id="50 + 0xD100" level="Detail" property="SetOptionKeepAlive" value="socket=%d[val1], enable=%d[val2]" info="Set socket option keep-alive"/>
<event id="51 + 0xD100" level="Detail" property="SetOptionFlowControl" value="socket=%d[val1], enable=%d[val2]" info="Set socket option flow-control"/>
<event id="52 + 0xD100" level="Detail" property="SetOptionDelayedAck" value="socket=%d[val1], enable=%d[val2]" info="Set socket option delayed-acknowledge"/>
<event id="116+ 0xD100" level="Detail" property="SetOptionInterface" value="socket=%d[val1], netif=%E[val2, NetIf:id]" info="Set Network Interface for internet connections"/>
<event id="53 + 0xD100" level="Error" property="SetOptionWrongOption" value="socket=%d[val1], opt=%E[val2, TCP_Opt:id]" info="Invalid option requested"/>
<event id="54 + 0xD100" level="Error" property="SetOptionWrongValue" value="socket=%d[val1], value=%d[val2]" info="Invalid value for option provided"/>
<event id="55 + 0xD100" level="Op" property="SendDelayedAck" value="socket=%d[val1]" info="Send delayed-acknowledge"/>
Expand Down
26 changes: 18 additions & 8 deletions Components/Network/Source/net_bsd.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::Network
* Copyright (c) 2004-2024 Arm Limited (or its affiliates). All rights reserved.
* Copyright (c) 2004-2025 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: net_bsd.c
* Purpose: Berkeley Socket API
Expand Down Expand Up @@ -1793,6 +1793,7 @@ int32_t getsockname (int32_t sock, SOCKADDR *name, int32_t *namelen) {
int32_t setsockopt (int32_t sock, int32_t level,
int32_t optname, const char *optval, int32_t optlen) {
NET_BSD_INFO *bsd_s;
netStatus retv;
uint32_t bval;
uint16_t bval16;

Expand Down Expand Up @@ -1896,15 +1897,23 @@ not_supp: ERRORF (BSD,"Setsockopt, Socket %d opt not supported\n",sock);
break;

case SO_BINDTODEVICE:
/* Bind a socket to network interface */
if (bsd_s->Type != SOCK_DGRAM) {
goto not_supp;
/* Bind socket to network interface */
if (bsd_s->Type == SOCK_STREAM) {
if (bsd_s->State > BSD_STATE_CREATED) {
ERRORF (BSD,"Setsockopt, Socket %d already bound\n",sock);
EvrNetBSD_SetoptSocketBound (sock);
RETURN (BSD_ERROR);
}
retv = net_tcp_set_option (bsd_s->Socket, netTCP_OptionInterface, bval);
}
else {
retv = net_udp_set_option (bsd_s->Socket, netUDP_OptionInterface, bval);
}
if (net_udp_set_option (bsd_s->Socket, netUDP_OptionInterface, bval) != netOK) {
if (retv != netOK) {
/* Invalid interface id */
goto inv_arg;
}
DEBUGF (BSD," Bind to %s\n", net_if_map_lan(bval)->Name);
DEBUGF (BSD," Bind to %s\n", net_if_map_all(bval)->Name);
EvrNetBSD_SetoptBindToDevice (sock, bval);
break;

Expand Down Expand Up @@ -2116,8 +2125,9 @@ not_supp: ERRORF (BSD,"Getsockopt, Socket %d opt not supported\n",sock);

case SO_BINDTODEVICE:
/* Bound network interface */
if (bsd_s->Type != SOCK_DGRAM) {
goto not_supp;
if (bsd_s->Type == SOCK_STREAM) {
retv = net_tcp_get_option (bsd_s->Socket, netTCP_OptionInterface);
break;
}
retv = net_udp_get_option (bsd_s->Socket, netUDP_OptionInterface);
break;
Expand Down
20 changes: 17 additions & 3 deletions Components/Network/Source/net_evr.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::Network
* Copyright (c) 2004-2024 Arm Limited (or its affiliates). All rights reserved.
* Copyright (c) 2004-2025 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: net_evr.h
* Purpose: Network definitions for Event Recorder
Expand Down Expand Up @@ -9140,7 +9140,7 @@ typedef struct evr_addr {
#endif

/**
\brief Event on UDP set socket option broadcast interface (Detail)
\brief Event on UDP set socket option bind to interface (Detail)
\param socket socket handle
\param if_id network interface identifier
*/
Expand Down Expand Up @@ -9426,7 +9426,7 @@ typedef struct evr_addr {
#define EvtNetTCP_ConnectLocalPortInvalid EventID (EventLevelError, EvtNetTCP, 17)
#define EvtNetTCP_AssignLocalPort EventID (EventLevelOp, EvtNetTCP, 18)
#define EvtNetTCP_ConnectSocketWrongState EventID (EventLevelError, EvtNetTCP, 19)
#define EvtNetTCP_ConnectNoRouteFound EventID (EventLevelError, EvtNetTCP,115) // End
#define EvtNetTCP_ConnectNoRouteFound EventID (EventLevelError, EvtNetTCP,115)
#define EvtNetTCP_ShowRttVariables EventID (EventLevelDetail,EvtNetTCP, 20)
#define EvtNetTCP_GetBufferFailed EventID (EventLevelError, EvtNetTCP, 21)
#define EvtNetTCP_SendFrame EventID (EventLevelOp, EvtNetTCP, 22)
Expand Down Expand Up @@ -9460,6 +9460,7 @@ typedef struct evr_addr {
#define EvtNetTCP_SetOptionKeepAlive EventID (EventLevelDetail,EvtNetTCP, 50)
#define EvtNetTCP_SetOptionFlowControl EventID (EventLevelDetail,EvtNetTCP, 51)
#define EvtNetTCP_SetOptionDelayedAck EventID (EventLevelDetail,EvtNetTCP, 52)
#define EvtNetTCP_SetOptionInterface EventID (EventLevelDetail,EvtNetTCP,116) // End
#define EvtNetTCP_SetOptionWrongOption EventID (EventLevelError, EvtNetTCP, 53)
#define EvtNetTCP_SetOptionWrongValue EventID (EventLevelError, EvtNetTCP, 54)
#define EvtNetTCP_SendDelayedAck EventID (EventLevelOp, EvtNetTCP, 55)
Expand Down Expand Up @@ -10139,6 +10140,19 @@ typedef struct evr_addr {
#define EvrNetTCP_SetOptionTclass(socket, ip6_tclass)
#endif

/**
\brief Event on TCP set socket option bind to interface (Detail)
\param socket socket handle
\param if_id network interface identifier
*/
#ifdef Network_Debug_EVR
__STATIC_INLINE void EvrNetTCP_SetOptionInterface(int32_t socket, uint16_t if_id) {
EventRecord2 (EvtNetTCP_SetOptionInterface, (uint32_t)socket, if_id);
}
#else
#define EvrNetTCP_SetOptionInterface(socket, if_id)
#endif

/**
\brief Event on TCP set socket option connection timeout (Detail)
\param socket socket handle
Expand Down
7 changes: 6 additions & 1 deletion Components/Network/Source/net_ip4.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::Network
* Copyright (c) 2004-2024 Arm Limited (or its affiliates). All rights reserved.
* Copyright (c) 2004-2025 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: net_ip4.c
* Purpose: Internet Protocol Version 4
Expand Down Expand Up @@ -483,6 +483,11 @@ NET_IF_CFG *net_ip4_find_route (NET_IF_CFG *net_if, const uint8_t *dst_addr) {
}
}
/* Address is external */
if (net_if != NULL) {
/* Use desired interface */
return (net_if);
}
/* Use default interface */
return (ip4->DefNetIf);
}

Expand Down
33 changes: 28 additions & 5 deletions Components/Network/Source/net_tcp.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::Network
* Copyright (c) 2004-2024 Arm Limited (or its affiliates). All rights reserved.
* Copyright (c) 2004-2025 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: net_tcp.c
* Purpose: Transmission Control Protocol
Expand Down Expand Up @@ -276,6 +276,7 @@ netStatus net_tcp_listen (int32_t socket, uint16_t port) {
*/
netStatus net_tcp_connect (int32_t socket, const __ADDR *addr, uint16_t local_port) {
NET_TCP_INFO *tcp_s;
NET_IF_CFG *out_if;

DEBUGF (TCP,"Connect Socket %d, LocPort %d\n",socket,local_port);
EvrNetTCP_ConnectSocket (socket, local_port);
Expand Down Expand Up @@ -323,14 +324,16 @@ netStatus net_tcp_connect (int32_t socket, const __ADDR *addr, uint16_t local_po
EvrNetTCP_ConnectSocketWrongState (socket, tcp_s->State);
return (netWrongState);
}
/* Assign an interface for the connection */
tcp_s->net_if = net_addr_find_route (NULL, addr);
if (tcp_s->net_if == NULL) {
/* No route to destination, also fails for IP6 in IP4_only variant */

/* Check the interface routing */
out_if = net_addr_find_route (tcp_s->net_if, addr);
if (!out_if || (tcp_s->net_if && (out_if != tcp_s->net_if))) {
/* No route or the route differs from the requested */
ERRORF (TCP,"Connect, Socket %d no route found\n",socket);
EvrNetTCP_ConnectNoRouteFound (socket);
return (netError);
}
tcp_s->net_if = out_if;

/* Socket mode is Client now */
tcp_s->Type &= ~TCP_TYPE_SERVER;
Expand Down Expand Up @@ -885,6 +888,7 @@ netStatus net_tcp_reset_window (int32_t socket) {
*/
netStatus net_tcp_set_option (int32_t socket, netTCP_Option option, uint32_t val) {
NET_TCP_INFO *tcp_s;
NET_IF_CFG *net_if;

DEBUGF (TCP,"SetOption Socket %d\n",socket);
EvrNetTCP_SetOptionSocket (socket, option, val);
Expand All @@ -895,6 +899,7 @@ netStatus net_tcp_set_option (int32_t socket, netTCP_Option option, uint32_t val
}
tcp_s = &tcp->Scb[socket-1];
if (tcp_s->State == netTCP_StateUNUSED) {
wrong_state:
ERRORF (TCP,"SetOption, Socket %d wrong state\n",socket);
EvrNetTCP_SetOptionSocketWrongState (socket, tcp_s->State);
return (netWrongState);
Expand All @@ -916,6 +921,17 @@ netStatus net_tcp_set_option (int32_t socket, netTCP_Option option, uint32_t val
return (netOK);
#endif

case netTCP_OptionInterface:
if (tcp_s->State != netTCP_StateCLOSED) {
goto wrong_state;
}
net_if = net_if_map_all (val);
if (net_if == NULL) break;
DEBUGF (TCP," Interface=%s\n",net_if->Name);
EvrNetTCP_SetOptionInterface (socket, net_if->Id);
tcp_s->net_if = net_if;
return (netOK);

case netTCP_OptionTimeout:
if (val > 65535) break;
if (val == 0) {
Expand Down Expand Up @@ -992,6 +1008,13 @@ uint32_t net_tcp_get_option (int32_t socket, netTCP_Option option) {
return (tcp_s->TClass);
#endif

case netTCP_OptionInterface:
if (!tcp_s->net_if) {
/* Network interface not assigned */
return (0);
}
return (tcp_s->net_if->Id);

case netTCP_OptionTimeout:
return (tcp_s->ConnTout);

Expand Down
4 changes: 2 additions & 2 deletions Components/Network/Source/net_udp.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*------------------------------------------------------------------------------
* MDK Middleware - Component ::Network
* Copyright (c) 2004-2024 Arm Limited (or its affiliates). All rights reserved.
* Copyright (c) 2004-2025 Arm Limited (or its affiliates). All rights reserved.
*------------------------------------------------------------------------------
* Name: net_udp.c
* Purpose: User Datagram Protocol
Expand Down Expand Up @@ -278,7 +278,7 @@ netStatus net_udp_set_option (int32_t socket, netUDP_Option option, uint32_t val
#endif

case netUDP_OptionInterface:
net_if = net_if_map_lan (val);
net_if = net_if_map_all (val);
if (net_if == NULL) break;
DEBUGF (UDP," Interface=%s\n",net_if->Name);
EvrNetUDP_SetOptionInterface (socket, net_if->Id);
Expand Down
18 changes: 15 additions & 3 deletions Documentation/Doxygen/Network/src/net_evr.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7190,7 +7190,7 @@ This usually happens when the \ref netUDP_SetOption function is executed.
\details
The event \b SetOptionInterface is created, when the internal function \e udp_set_option
sets the network interface for the socket that is used when the \ref netUDP_Send sends data
to a broadcast or a multicast address. This usually happens when the \ref netUDP_SetOption
to a broadcast, multicast or external address. This usually happens when the \ref netUDP_SetOption
function is executed.

\b Value in the Event Recorder shows:
Expand Down Expand Up @@ -8032,6 +8032,18 @@ when the \ref netTCP_SetOption function is executed.
- \b enable: controlling the delayed acknowledgement (1= enable, 0= disable).
*/

/**
\fn __STATIC_INLINE void EvrNetTCP_SetOptionInterface(int32_t socket, uint16_t if_id)
\details
The event \b SetOptionInterface is created, when the internal function \e tcp_set_option
sets the network interface for the socket used to connect to an external address.
This usually happens when the \ref netTCP_SetOption function is executed.

\b Value in the Event Recorder shows:
- \b socket: TCP socket handle for setting the option.
- \b netif: network interface identifier.
*/

/**
\fn __STATIC_INLINE void EvrNetTCP_SetOptionWrongOption(int32_t socket, int32_t tcp_option)
\details
Expand Down Expand Up @@ -8830,8 +8842,8 @@ the required socket is not created. This happens when the \ref bind function is
\fn __STATIC_INLINE void EvrNetBSD_BindSocketAlreadyBound(int32_t sock)
\details
The event \b BindSocketAlreadyBound is created when the BSD socket can not bind,
because the required socket is bound already. This happens when the \ref bind function
is executed.
because the required socket is bound already. This happens when the \ref bind or
\ref setsockopt function is executed.

\b Value in the Event Recorder shows:
- \b sock: BSD socket descriptor for binding.
Expand Down
3 changes: 2 additions & 1 deletion Documentation/Doxygen/Network/src/revision_history.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
<th>Description</th>
</tr>
<tr>
<td>V8.0.1</td>
<td>V8.1.0</td>
<td>
- added support for simultaneous outgoing connections via different network interfaces
- fixed handling of Ethernet drivers not supporting multicast address filtering
</td>
</tr>
Expand Down
Loading

0 comments on commit 49f1739

Please sign in to comment.