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