1 /***************************************************************************
2 * Copyright (c) 2024 Microsoft Corporation
3 *
4 * This program and the accompanying materials are made available under the
5 * terms of the MIT License which is available at
6 * https://opensource.org/licenses/MIT.
7 *
8 * SPDX-License-Identifier: MIT
9 **************************************************************************/
10
11
12 /**************************************************************************/
13 /**************************************************************************/
14 /** */
15 /** NetX Component */
16 /** */
17 /** Internet Protocol (IP) */
18 /** */
19 /**************************************************************************/
20 /**************************************************************************/
21
22 #define NX_SOURCE_CODE
23
24
25 /* Include necessary system files. */
26
27 #include "nx_api.h"
28 #include "nx_ip.h"
29 #ifdef FEATURE_NX_IPV6
30 #include "nx_ipv6.h"
31 #endif
32
33
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* _nx_ip_interface_attach PORTABLE C */
40 /* 6.1.8 */
41 /* AUTHOR */
42 /* */
43 /* Yuxin Zhou, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This function attaches a physical network interface to the IP */
48 /* instance, invokes the associated device driver to initialize and */
49 /* enable the device. */
50 /* */
51 /* If this function is called before the IP thread starts running, */
52 /* the deivce initialization is executed as part of the device */
53 /* initialization during IP thread start up phase. If this function */
54 /* is called after the IP thread has been started, the device */
55 /* initialization is executed as part of this function call. */
56 /* */
57 /* */
58 /* INPUT */
59 /* */
60 /* ip_ptr_value Pointer to IP control block */
61 /* interface_name Name of this interface */
62 /* ip_address Interface IP Address, in host */
63 /* byte order */
64 /* network_mask Network Mask, in host byte */
65 /* order */
66 /* ip_link_driver User supplied link driver */
67 /* */
68 /* OUTPUT */
69 /* */
70 /* status Completion status */
71 /* */
72 /* CALLS */
73 /* */
74 /* tx_mutex_get Obtain protection mutex */
75 /* tx_mutex_put Release protection mutex */
76 /* (ip_link_driver) User supplied link driver */
77 /* _nx_ipv6_multicast_join Join IPv6 multicast group */
78 /* */
79 /* CALLED BY */
80 /* */
81 /* Application */
82 /* */
83 /* RELEASE HISTORY */
84 /* */
85 /* DATE NAME DESCRIPTION */
86 /* */
87 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
88 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
89 /* resulting in version 6.1 */
90 /* 08-02-2021 Yuxin Zhou Modified comment(s), and */
91 /* supported TCP/IP offload, */
92 /* resulting in version 6.1.8 */
93 /* */
94 /**************************************************************************/
_nx_ip_interface_attach(NX_IP * ip_ptr,CHAR * interface_name,ULONG ip_address,ULONG network_mask,VOID (* ip_link_driver)(struct NX_IP_DRIVER_STRUCT *))95 UINT _nx_ip_interface_attach(NX_IP *ip_ptr, CHAR *interface_name, ULONG ip_address, ULONG network_mask, VOID (*ip_link_driver)(struct NX_IP_DRIVER_STRUCT *))
96 {
97
98 INT i;
99 NX_INTERFACE *nx_interface = NX_NULL;
100 NX_IP_DRIVER driver_request;
101 UINT status = NX_SUCCESS;
102
103 #if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_SOLICITATION)
104 ULONG address[4];
105 #endif
106
107 #ifdef NX_DISABLE_IPV4
108 NX_PARAMETER_NOT_USED(ip_address);
109 NX_PARAMETER_NOT_USED(network_mask);
110 #else
111 /* Perform duplicate address detection. */
112 for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
113 {
114 if ((ip_ptr -> nx_ip_interface[i].nx_interface_ip_address == ip_address) &&
115 (ip_address != 0))
116 {
117
118 /* The IPv4 address already exists. */
119 return(NX_DUPLICATED_ENTRY);
120 }
121 }
122 #endif /* !NX_DISABLE_IPV4 */
123
124 for (i = 0; i < NX_MAX_PHYSICAL_INTERFACES; i++)
125 {
126
127 nx_interface = &(ip_ptr -> nx_ip_interface[i]);
128
129 if (!(nx_interface -> nx_interface_valid))
130 {
131 /* Find a valid entry. */
132 break;
133 }
134 }
135
136 if (i == NX_MAX_PHYSICAL_INTERFACES)
137 {
138 /* No more free entry. return. */
139 return(NX_NO_MORE_ENTRIES);
140 }
141
142 /* Obtain the IP internal mutex before calling the driver. */
143 tx_mutex_get(&(ip_ptr -> nx_ip_protection), TX_WAIT_FOREVER);
144
145 /* Mark the entry as valid. */
146 nx_interface -> nx_interface_valid = NX_TRUE;
147
148 /* Fill in the interface information. */
149 #ifndef NX_DISABLE_IPV4
150 nx_interface -> nx_interface_ip_address = ip_address;
151 nx_interface -> nx_interface_ip_network_mask = network_mask;
152 nx_interface -> nx_interface_ip_network = ip_address & network_mask;
153 #endif /* !NX_DISABLE_IPV4 */
154 nx_interface -> nx_interface_link_driver_entry = ip_link_driver;
155 nx_interface -> nx_interface_name = interface_name;
156
157 /* If trace is enabled, insert this event into the trace buffer. */
158 NX_TRACE_IN_LINE_INSERT(NX_TRACE_IP_INTERFACE_ATTACH, ip_ptr, ip_address, i, 0, NX_TRACE_IP_EVENTS, 0, 0);
159
160 /* If the IP thread is already running, this service needs to go through the rest of the initializeation process. */
161 if (ip_ptr -> nx_ip_initialize_done == NX_TRUE)
162 {
163
164 #ifdef NX_ENABLE_INTERFACE_CAPABILITY
165 /* Clear capability flag. */
166 ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag = 0;
167 #endif /* NX_ENABLE_INTERFACE_CAPABILITY */
168
169 /* First attach the interface to the device. */
170 driver_request.nx_ip_driver_ptr = ip_ptr;
171 driver_request.nx_ip_driver_command = NX_LINK_INTERFACE_ATTACH;
172 driver_request.nx_ip_driver_interface = &(ip_ptr -> nx_ip_interface[i]);
173 (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
174
175 #ifdef NX_ENABLE_TCPIP_OFFLOAD
176 if (ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag & NX_INTERFACE_CAPABILITY_TCPIP_OFFLOAD)
177 {
178
179 /* Set checksum capability for TCP/IP offload interface. */
180 ip_ptr -> nx_ip_interface[i].nx_interface_capability_flag |= NX_INTERFACE_CAPABILITY_CHECKSUM_ALL;
181 }
182 #endif /* NX_ENABLE_TCPIP_OFFLOAD */
183
184 /* Call the link driver to initialize the hardware. Among other
185 responsibilities, the driver is required to provide the
186 Maximum Transfer Unit (MTU) for the physical layer. The MTU
187 should represent the actual physical layer transfer size
188 less the physical layer headers and trailers. */
189 driver_request.nx_ip_driver_ptr = ip_ptr;
190 driver_request.nx_ip_driver_command = NX_LINK_INITIALIZE;
191
192 /* If trace is enabled, insert this event into the trace buffer. */
193 NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_INITIALIZE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
194
195 /*
196 When an IP instance is created, the first interface (nx_ip_interface[0]) is configured using parameters
197 provided in the IP create call.
198
199 When IP thread runs, it invokes the 1st interface link driver for link initialization.
200 */
201 (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
202
203
204
205 /* Call the link driver again to enable the interface. */
206 driver_request.nx_ip_driver_ptr = ip_ptr;
207 driver_request.nx_ip_driver_command = NX_LINK_ENABLE;
208
209 /* If trace is enabled, insert this event into the trace buffer. */
210 NX_TRACE_IN_LINE_INSERT(NX_TRACE_INTERNAL_IO_DRIVER_LINK_ENABLE, ip_ptr, 0, 0, 0, NX_TRACE_INTERNAL_EVENTS, 0, 0);
211
212 (ip_ptr -> nx_ip_interface[i].nx_interface_link_driver_entry)(&driver_request);
213
214 /* Also configure the all-node multicast address. */
215 #if defined(FEATURE_NX_IPV6) && !defined(NX_DISABLE_ICMPV6_ROUTER_SOLICITATION)
216 /* Create the all-node multicast group address, */
217 address[0] = 0xFF020000;
218 address[1] = 0;
219 address[2] = 0;
220 address[3] = 1;
221
222
223 /* Join all-node multicast group. */
224 status = _nx_ipv6_multicast_join(ip_ptr, address, &ip_ptr -> nx_ip_interface[i]);
225
226 #endif
227 }
228
229 /* Release the IP internal mutex. */
230 tx_mutex_put(&(ip_ptr -> nx_ip_protection));
231
232
233 /* All done. Return. */
234 return(status);
235 }
236
237