1 /**************************************************************************/
2 /* */
3 /* Copyright (c) Microsoft Corporation. All rights reserved. */
4 /* */
5 /* This software is licensed under the Microsoft Software License */
6 /* Terms for Microsoft Azure RTOS. Full text of the license can be */
7 /* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */
8 /* and in the root directory of this software. */
9 /* */
10 /**************************************************************************/
11
12
13 /**************************************************************************/
14 /**************************************************************************/
15 /** */
16 /** NetX Component */
17 /** */
18 /** Neighbor Discovery Cache */
19 /** */
20 /**************************************************************************/
21 /**************************************************************************/
22
23 #define NX_SOURCE_CODE
24
25
26 /* Include necessary system files. */
27
28 #include "nx_api.h"
29 #include "nx_ipv6.h"
30 #include "nx_nd_cache.h"
31
32 #ifdef FEATURE_NX_IPV6
33
34
35 /**************************************************************************/
36 /* */
37 /* FUNCTION RELEASE */
38 /* */
39 /* nx_nd_cache_add PORTABLE C */
40 /* 6.1 */
41 /* AUTHOR */
42 /* */
43 /* Yuxin Zhou, Microsoft Corporation */
44 /* */
45 /* DESCRIPTION */
46 /* */
47 /* This internal function adds IPv6 and MAC mapping to the ND cache */
48 /* table. */
49 /* */
50 /* INPUT */
51 /* */
52 /* ip_ptr Pointer to the IP instance. */
53 /* dest_ip Pointer to the IP address. */
54 /* if_ptr Interface through which the neighbor can be*/
55 /* reached. */
56 /* mac Pointer to the MAC address to map to. */
57 /* IsStatic 1: the entry is manully configured, thus */
58 /* does not time out. */
59 /* 0: The entry is dynamically configured. */
60 /* status Initial status */
61 /* iface_address Interface associated with this entry. */
62 /* nd_cache_entry User specified storage space of pointer to */
63 /* the corresponding ND cache. */
64 /* */
65 /* OUTPUT */
66 /* */
67 /* status NX_SUCCESS: An ND cache entry has been */
68 /* added. nd_cache_entry contains valid */
69 /* value. */
70 /* NX_NOT_SUCCESSFUL: The ND cache entry */
71 /* cannot be added, or nd_cache_entry is */
72 /* NULL. */
73 /* */
74 /* CALLS */
75 /* */
76 /* tx_mutex_get Obtain protection mutex */
77 /* tx_mutex_put Release protection mutex */
78 /* _nx_nd_cache_add_entry Obtain an empty entry */
79 /* */
80 /* CALLED BY */
81 /* */
82 /* _nx_icmpv6_process_na Process NA message */
83 /* _nx_icmpv6_process_ns Process NS message */
84 /* _nx_icmpv6_process_ra Process RA message */
85 /* nx_icmpv6_process_redirect.c Process Redirect message */
86 /* nxd_nd_cache_entry_set.c User level service */
87 /* */
88 /* */
89 /* RELEASE HISTORY */
90 /* */
91 /* DATE NAME DESCRIPTION */
92 /* */
93 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
94 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
95 /* resulting in version 6.1 */
96 /* */
97 /**************************************************************************/
_nx_nd_cache_add(NX_IP * ip_ptr,ULONG * dest_ip,NX_INTERFACE * if_ptr,CHAR * mac,INT IsStatic,INT status,NXD_IPV6_ADDRESS * iface_address,ND_CACHE_ENTRY ** nd_cache_entry)98 UINT _nx_nd_cache_add(NX_IP *ip_ptr, ULONG *dest_ip, NX_INTERFACE *if_ptr, CHAR *mac, INT IsStatic,
99 INT status, NXD_IPV6_ADDRESS *iface_address,
100 ND_CACHE_ENTRY **nd_cache_entry)
101 {
102
103 USHORT *copy_from, *copy_to;
104 ND_CACHE_ENTRY *entry;
105
106
107 /* Initialize the return value. */
108 *nd_cache_entry = NX_NULL;
109
110 /* First find if there has a exit entry. */
111 if (_nx_nd_cache_find_entry(ip_ptr, dest_ip, &entry) != NX_SUCCESS)
112 {
113
114 /* Did not find a valid entry. Add one. */
115 if (_nx_nd_cache_add_entry(ip_ptr, dest_ip, iface_address, &entry) != NX_SUCCESS)
116 {
117
118 /* Can not add, return. */
119 return(NX_NOT_SUCCESSFUL);
120 }
121 }
122
123 /* At this point we know the entry is in the ND cache.
124 Finish up updating the rest of the information. */
125
126 /*lint -e{644} suppress variable might not be initialized, since "entry" was initialized in _nx_nd_cache_find_entry or _nx_nd_cache_add_entry. */
127 entry -> nx_nd_cache_is_static = IsStatic ? (UCHAR)1 : (UCHAR)0;
128
129 entry -> nx_nd_cache_interface_ptr = if_ptr;
130
131 /* If the entry is already in reachable state, and the link layer address
132 is the same, we should not update the status field. */
133 /*lint -e{929} -e{740} suppress cast of pointer to pointer, since it is necessary */
134 copy_from = (USHORT *)mac;
135
136 /*lint -e{927} suppress cast of pointer to pointer, since it is necessary */
137 copy_to = (USHORT *)(entry -> nx_nd_cache_mac_addr);
138
139 /* Set the return value. */
140 *nd_cache_entry = entry;
141
142 if (entry -> nx_nd_cache_nd_status == ND_CACHE_STATE_REACHABLE)
143 {
144 /* Check mac address.*/
145 if ((copy_from[0] == copy_to[0]) &&
146 (copy_from[1] == copy_to[1]) &&
147 (copy_from[2] == copy_to[2]))
148 {
149
150 /* The MAC address is the same. So we are done. */
151
152 return(NX_SUCCESS);
153 }
154 }
155
156 /* Is this a static entry? */
157 if (IsStatic)
158 {
159
160 /* Just set the status, no need to update the cache entry timeout. */
161 entry -> nx_nd_cache_nd_status = (UCHAR)status;
162 }
163 /* Is the status changed? */
164 else if (entry -> nx_nd_cache_nd_status != (UCHAR)status)
165 {
166
167 /* Update status in the cache entry. */
168 entry -> nx_nd_cache_nd_status = (UCHAR)status;
169
170 if (entry -> nx_nd_cache_nd_status == ND_CACHE_STATE_REACHABLE) /* New entry */
171 {
172
173 /* Set the timer tick. The tick value only applies to the REACHABLE state. */
174 entry -> nx_nd_cache_timer_tick = ip_ptr -> nx_ipv6_reachable_timer;
175 }
176 }
177
178 /* Copy the MAC address. */
179 *copy_to = *copy_from;
180 copy_to++; copy_from++;
181 *copy_to = *copy_from;
182 copy_to++; copy_from++;
183 *copy_to = *copy_from;
184
185 return(NX_SUCCESS);
186 }
187
188 #endif /* FEATURE_NX_IPV6 */
189
190