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 /** NetX Component */
15 /** */
16 /** Internet Control Message Protocol (ICMP) */
17 /** */
18 /**************************************************************************/
19 /**************************************************************************/
20
21 #define NX_SOURCE_CODE
22
23
24 /* Include necessary system files. */
25 #include "nx_api.h"
26 #include "nx_ipv6.h"
27 #include "nx_icmpv6.h"
28
29 #ifdef FEATURE_NX_IPV6
30
31
32 /**************************************************************************/
33 /* */
34 /* FUNCTION RELEASE */
35 /* */
36 /* _nx_icmpv6_dest_table_find PORTABLE C */
37 /* 6.1 */
38 /* AUTHOR */
39 /* */
40 /* Yuxin Zhou, Microsoft Corporation */
41 /* */
42 /* DESCRIPTION */
43 /* */
44 /* This function finds a destination table entry based on destination */
45 /* address. If no match is found, a the destination entry pointer is */
46 /* set to NULL, but a successful search status returned. */
47 /* */
48 /* INPUT */
49 /* */
50 /* ip_ptr Pointer to IP */
51 /* destination_address Destination IP address. */
52 /* dest_entry_ptr Pointer to location of matching*/
53 /* table entry, if any. */
54 /* path_mtu Optional path mtu update. */
55 /* Note: caller shall make sure */
56 /* MTU does not exceed physical */
57 /* link MTU size. */
58 /* mtu_timeout Optional entry timeout update */
59 /* */
60 /* OUTPUT */
61 /* */
62 /* NX_SUCCESS Search successfully completed */
63 /* regardless if match found */
64 /* NX_NOT_SUCCESSFUL Invalid input; search aborted */
65 /* */
66 /* CALLS */
67 /* */
68 /* */
69 /* CALLED BY */
70 /* */
71 /* nx_icmpv6_send_queued_packets Send queued ICMPv6 packets */
72 /* nx_ipv6_send_packet Send specified IPv6 packet */
73 /* */
74 /* RELEASE HISTORY */
75 /* */
76 /* DATE NAME DESCRIPTION */
77 /* */
78 /* 05-19-2020 Yuxin Zhou Initial Version 6.0 */
79 /* 09-30-2020 Yuxin Zhou Modified comment(s), */
80 /* resulting in version 6.1 */
81 /* */
82 /**************************************************************************/
_nx_icmpv6_dest_table_find(NX_IP * ip_ptr,ULONG * destination_address,NX_IPV6_DESTINATION_ENTRY ** dest_entry_ptr,ULONG path_mtu,ULONG mtu_timeout)83 UINT _nx_icmpv6_dest_table_find(NX_IP *ip_ptr, ULONG *destination_address, NX_IPV6_DESTINATION_ENTRY **dest_entry_ptr,
84 ULONG path_mtu, ULONG mtu_timeout)
85 {
86
87 UINT i, table_size;
88
89 /* Destination address must be valid. */
90 NX_ASSERT((destination_address != NX_NULL) && (dest_entry_ptr != NULL));
91
92 /* Set a local variable for convenience. */
93 table_size = ip_ptr -> nx_ipv6_destination_table_size;
94
95 /* Check the destination num. */
96 if (table_size == 0)
97 {
98 return(NX_NOT_SUCCESSFUL);
99 }
100
101 /* Initialize the return value. */
102 *dest_entry_ptr = NX_NULL;
103
104 /* Loop through all entries. */
105 for (i = 0; table_size && (i < NX_IPV6_DESTINATION_TABLE_SIZE); i++)
106 {
107
108 /* Skip invalid entries. */
109 if (!ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_valid)
110 {
111 continue;
112 }
113
114 /* Keep track of valid entries we have checked. */
115 table_size--;
116
117 /* Check whether or not the address is the same. */
118 if (CHECK_IPV6_ADDRESSES_SAME(&ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_destination_address[0], destination_address))
119 {
120
121 #ifdef NX_ENABLE_IPV6_PATH_MTU_DISCOVERY
122
123 /* Update the table entry if the supplied path MTU is non zero and
124 does not exceed our IP instance MTU. */
125 if (path_mtu > 0)
126 {
127
128 /* Do we have a valid timeout e.g. did this information come from an RA packet?
129 Or is a packet too big message indicating we need to decrease our path MTU? */
130 if ((mtu_timeout > 0) || (ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu > path_mtu))
131 {
132
133 /* OK to change the path MTU. */
134 ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_path_mtu = path_mtu;
135
136 /* Was a valid timeout supplied? */
137 if (mtu_timeout > 0)
138 {
139
140 /* Yes; Ok to update table entry with the specified timeout. */
141 ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = mtu_timeout;
142 }
143 else
144 {
145 /* No; the path MTU changed in response to a packet too big error
146 message. Set the table entry timeout to the required wait
147 interval. We cannot attempt to restore (increase) the path MTU
148 before this time out expires. */
149 ip_ptr -> nx_ipv6_destination_table[i].nx_ipv6_destination_entry_MTU_timer_tick = NX_PATH_MTU_INCREASE_WAIT_INTERVAL_TICKS;
150 }
151 }
152
153 /* Else this information presumably comes a Packet too Big message.
154 RFC 1981 disallows increasing a path MTU based on a PTB message
155 (decreasing is allowed and required). */
156 }
157 #else
158 NX_PARAMETER_NOT_USED(path_mtu);
159 NX_PARAMETER_NOT_USED(mtu_timeout);
160 #endif /* NX_ENABLE_IPV6_PATH_MTU_DISCOVERY */
161
162 *dest_entry_ptr = &ip_ptr -> nx_ipv6_destination_table[i];
163
164 return(NX_SUCCESS);
165 }
166 }
167
168 return(NX_NOT_SUCCESSFUL);
169 }
170
171 #endif /* FEATURE_NX_IPV6 */
172
173